Skip to content

Commit fc2a290

Browse files
authored
Merge pull request #33 from Forward-Future/codex/add-social-post-sharing
[codex] Add social post sharing
2 parents 6ee3345 + 48a9876 commit fc2a290

36 files changed

Lines changed: 785 additions & 68 deletions

File tree

scripts/build-loop-pages.mjs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,27 @@ function socialImageUrl(loop) {
3737
return `${site.baseUrl}assets/social/${loop.slug}-${site.socialImageVersion}.${site.socialImageExtension}`;
3838
}
3939

40+
function shareActions(loop, url) {
41+
const postText = `Try "${loop.title}" from the Loop Library: ${loop.summary}`;
42+
43+
return `<div class="share-actions" aria-label="Share this loop">
44+
<button
45+
class="share-action share-action-primary"
46+
type="button"
47+
data-copy-social-post
48+
data-post-text="${escapeHtml(postText)}"
49+
data-post-url="${escapeHtml(url)}"
50+
aria-label="Copy a social post about ${escapeHtml(loop.title)}"
51+
>
52+
<svg class="share-copy-icon" viewBox="0 0 24 24" aria-hidden="true">
53+
<rect x="8" y="8" width="11" height="11"></rect>
54+
<path d="M16 8V5a1 1 0 0 0-1-1H5a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h3"></path>
55+
</svg>
56+
<span>Copy social post</span>
57+
</button>
58+
</div>`;
59+
}
60+
4061
function relatedLinks(loop) {
4162
return loop.related
4263
.map((slug) => loops.find((candidate) => candidate.slug === slug))
@@ -221,11 +242,11 @@ function renderLoopPage(loop) {
221242
<link rel="alternate" type="application/json" title="${escapeHtml(site.name)} catalog" href="${escapeHtml(site.baseUrl)}catalog.json" />
222243
<link rel="alternate" type="text/markdown" title="${escapeHtml(site.name)} catalog in Markdown" href="${escapeHtml(site.baseUrl)}catalog.md" />
223244
<link rel="icon" type="image/png" href="../../assets/favicon.png" />
224-
<link rel="stylesheet" href="../../styles.css?v=20260617-simple-detail" />
245+
<link rel="stylesheet" href="../../styles.css?v=20260620-social-copy" />
225246
<script type="application/ld+json">
226247
${structuredData(loop)}
227248
</script>
228-
<script src="../../script.js?v=20260618-x-handle" defer></script>
249+
<script src="../../script.js?v=20260620-social-copy" defer></script>
229250
<title>${escapeHtml(loop.seoTitle)}</title>
230251
</head>
231252
<body>
@@ -286,6 +307,7 @@ ${structuredData(loop)}
286307
: ""
287308
}
288309
</p>
310+
${shareActions(loop, url)}
289311
</header>
290312
291313
<div class="detail-stack">

scripts/check.mjs

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,8 @@ for (const [index, loop] of loops.entries()) {
278278
const url = `${siteMeta.baseUrl}loops/${loop.slug}/`;
279279
const imageUrl = `${siteMeta.baseUrl}assets/social/${loop.slug}-${siteMeta.socialImageVersion}.${siteMeta.socialImageExtension}`;
280280
const imageAlt = `${loop.title} — Forward Future Loop Library`;
281+
const postText = `Try "${loop.title}" from the Loop Library: ${loop.summary}`;
282+
const socialPost = `${postText}\n\n${url}`;
281283
const page = loopPages[index];
282284
const listItem = collection.mainEntity.itemListElement[index];
283285
const homepageHref = `href="./loops/${loop.slug}/"`;
@@ -413,6 +415,15 @@ for (const [index, loop] of loops.entries()) {
413415
assert(page.includes('href="../../learn/">What is a loop?</a>'));
414416
assert(!page.includes('href="../../#tips"'));
415417
assert(page.includes('data-copy-root'));
418+
assert(page.includes('class="share-actions" aria-label="Share this loop"'));
419+
assert(page.includes('data-copy-social-post'));
420+
assert(page.includes(`data-post-text="${escapeHtml(postText)}"`));
421+
assert(page.includes(`data-post-url="${url}"`));
422+
assert(page.includes(`<span>Copy social post</span>`));
423+
assert(!page.includes("twitter.com/intent/tweet"));
424+
assert(!page.includes("Share on X"));
425+
assert(!page.includes(`<span>Copy link</span>`));
426+
assert(socialPost.length <= 280);
416427
assert.equal((page.match(/data-here-now-credit/g) || []).length, 2);
417428
assert.equal((page.match(/https:\/\/here\.now\/r\/signals/g) || []).length, 2);
418429
assert.equal((page.match(/aria-label="Hosted by here\.now"/g) || []).length, 2);
@@ -552,8 +563,18 @@ assert(!html.includes('data-type='));
552563
assert(!html.includes('class="cell-type"'));
553564
assert(!html.includes("type-badge"));
554565
assert(!html.includes('<th scope="col">Type</th>'));
555-
assert(html.includes("./styles.css?v=20260619-show-more"));
556-
assert(html.includes("./script.js?v=20260619-no-numbering"));
566+
assert(html.includes("./styles.css?v=20260620-social-copy"));
567+
assert(html.includes("./script.js?v=20260620-social-copy"));
568+
const homepagePostText =
569+
"Find Loops and create your own - Loop Library";
570+
assert(html.includes('class="share-actions" aria-label="Share Loop Library"'));
571+
assert(html.includes('data-copy-social-post'));
572+
assert(html.includes(`data-post-text="${homepagePostText}"`));
573+
assert(html.includes(`data-post-url="${siteMeta.baseUrl}"`));
574+
assert(html.includes('aria-label="Copy a Loop Library social post"'));
575+
assert(!html.includes("twitter.com/intent/tweet"));
576+
assert(!html.includes("Share on X"));
577+
assert(!html.includes(`<span>Copy link</span>`));
557578
assert(html.includes('href="./learn/"'));
558579
assert(!html.includes('class="loop-guide"'));
559580
assert(!html.includes("A useful loop specifies:"));
@@ -677,6 +698,11 @@ assert(css.includes("scroll-margin-top: 80px"));
677698
assert(css.includes(".pagination-button,\n .pagination-status"));
678699
assert(css.includes(".skill-promo"));
679700
assert(css.includes(".library-hero"));
701+
assert(css.includes(".share-actions"));
702+
assert(css.includes(".share-action-primary"));
703+
assert(css.includes(".share-action.is-copied"));
704+
assert(css.includes(".copy-fallback textarea"));
705+
assert(!css.includes(".share-action-x"));
680706
assert(css.includes(".loop-featured"));
681707
assert(!css.includes(".answer-capsule"));
682708
assert(css.includes(".skill-copy-button"));
@@ -757,6 +783,13 @@ assert(script.includes('candidate.setAttribute("aria-pressed", String(isActive))
757783
assert(script.includes('themeToggle.addEventListener("click"'));
758784
assert(script.includes("window.localStorage.setItem(THEME_STORAGE_KEY, theme)"));
759785
assert(script.includes('button.closest("[data-copy-root]")'));
786+
assert(script.includes('document.querySelectorAll("[data-copy-social-post]")'));
787+
assert(script.includes('const socialPost = `${postText}\\n\\n${postUrl}`'));
788+
assert(script.includes("showCopyFallback(button, socialPost)"));
789+
assert(script.includes('textArea.value = text'));
790+
assert(script.includes('textArea.setAttribute("readonly", "")'));
791+
assert(script.includes('showToast("Social post copied to clipboard.")'));
792+
assert(script.includes('label.textContent = "Copied!"'));
760793
assert(script.includes('document.querySelector("[data-copy-skill-command]")'));
761794
assert(script.includes("Install command copied to clipboard."));
762795
assert(script.includes('label.textContent = "Copy command"'));

site/index.html

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@
116116
href="https://signals.forwardfuture.ai/loop-library/catalog.md"
117117
/>
118118
<link rel="icon" type="image/png" href="./assets/favicon.png" />
119-
<link rel="stylesheet" href="./styles.css?v=20260619-show-more" />
119+
<link rel="stylesheet" href="./styles.css?v=20260620-social-copy" />
120120
<script type="application/ld+json">
121121
{
122122
"@context": "https://schema.org",
@@ -369,7 +369,7 @@
369369
]
370370
}
371371
</script>
372-
<script src="./script.js?v=20260619-no-numbering" defer></script>
372+
<script src="./script.js?v=20260620-social-copy" defer></script>
373373
<title>Loop Library: Repeatable AI Agent Workflows | Forward Future</title>
374374
</head>
375375
<body>
@@ -439,6 +439,22 @@ <h1>Loop Library</h1>
439439
Copy practical AI agent prompts with clear checks and stopping
440440
conditions.
441441
</p>
442+
<div class="share-actions" aria-label="Share Loop Library">
443+
<button
444+
class="share-action share-action-primary"
445+
type="button"
446+
data-copy-social-post
447+
data-post-text="Find Loops and create your own - Loop Library"
448+
data-post-url="https://signals.forwardfuture.ai/loop-library/"
449+
aria-label="Copy a Loop Library social post"
450+
>
451+
<svg class="share-copy-icon" viewBox="0 0 24 24" aria-hidden="true">
452+
<rect x="8" y="8" width="11" height="11"></rect>
453+
<path d="M16 8V5a1 1 0 0 0-1-1H5a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h3"></path>
454+
</svg>
455+
<span>Copy social post</span>
456+
</button>
457+
</div>
442458
</div>
443459

444460
</div>

site/loops/100-percent-test-coverage-loop/index.html

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
<link rel="alternate" type="application/json" title="Loop Library catalog" href="https://signals.forwardfuture.ai/loop-library/catalog.json" />
5858
<link rel="alternate" type="text/markdown" title="Loop Library catalog in Markdown" href="https://signals.forwardfuture.ai/loop-library/catalog.md" />
5959
<link rel="icon" type="image/png" href="../../assets/favicon.png" />
60-
<link rel="stylesheet" href="../../styles.css?v=20260617-simple-detail" />
60+
<link rel="stylesheet" href="../../styles.css?v=20260620-social-copy" />
6161
<script type="application/ld+json">
6262
{
6363
"@context": "https://schema.org",
@@ -129,7 +129,7 @@
129129
]
130130
}
131131
</script>
132-
<script src="../../script.js?v=20260618-x-handle" defer></script>
132+
<script src="../../script.js?v=20260620-social-copy" defer></script>
133133
<title>100% Test Coverage Loop for Coding Agents | Loop Library</title>
134134
</head>
135135
<body>
@@ -204,6 +204,22 @@ <h1>The 100% test coverage loop</h1>
204204
<p class="detail-byline">
205205
Contributed by <strong>Matthew Berman</strong>
206206
</p>
207+
<div class="share-actions" aria-label="Share this loop">
208+
<button
209+
class="share-action share-action-primary"
210+
type="button"
211+
data-copy-social-post
212+
data-post-text="Try &quot;The 100% test coverage loop&quot; from the Loop Library: Adds meaningful tests until the full suite reaches 100% coverage."
213+
data-post-url="https://signals.forwardfuture.ai/loop-library/loops/100-percent-test-coverage-loop/"
214+
aria-label="Copy a social post about The 100% test coverage loop"
215+
>
216+
<svg class="share-copy-icon" viewBox="0 0 24 24" aria-hidden="true">
217+
<rect x="8" y="8" width="11" height="11"></rect>
218+
<path d="M16 8V5a1 1 0 0 0-1-1H5a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h3"></path>
219+
</svg>
220+
<span>Copy social post</span>
221+
</button>
222+
</div>
207223
</header>
208224

209225
<div class="detail-stack">

site/loops/architecture-satisfaction-loop/index.html

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
<link rel="alternate" type="application/json" title="Loop Library catalog" href="https://signals.forwardfuture.ai/loop-library/catalog.json" />
5858
<link rel="alternate" type="text/markdown" title="Loop Library catalog in Markdown" href="https://signals.forwardfuture.ai/loop-library/catalog.md" />
5959
<link rel="icon" type="image/png" href="../../assets/favicon.png" />
60-
<link rel="stylesheet" href="../../styles.css?v=20260617-simple-detail" />
60+
<link rel="stylesheet" href="../../styles.css?v=20260620-social-copy" />
6161
<script type="application/ld+json">
6262
{
6363
"@context": "https://schema.org",
@@ -129,7 +129,7 @@
129129
]
130130
}
131131
</script>
132-
<script src="../../script.js?v=20260618-x-handle" defer></script>
132+
<script src="../../script.js?v=20260620-social-copy" defer></script>
133133
<title>Architecture Refactoring Loop for Coding Agents | Loop Library</title>
134134
</head>
135135
<body>
@@ -204,6 +204,22 @@ <h1>The architecture satisfaction loop</h1>
204204
<p class="detail-byline">
205205
Contributed by <strong>Peter Steinberger</strong>
206206
</p>
207+
<div class="share-actions" aria-label="Share this loop">
208+
<button
209+
class="share-action share-action-primary"
210+
type="button"
211+
data-copy-social-post
212+
data-post-text="Try &quot;The architecture satisfaction loop&quot; from the Loop Library: Refactors architecture in small, tested, independently reviewed checkpoints."
213+
data-post-url="https://signals.forwardfuture.ai/loop-library/loops/architecture-satisfaction-loop/"
214+
aria-label="Copy a social post about The architecture satisfaction loop"
215+
>
216+
<svg class="share-copy-icon" viewBox="0 0 24 24" aria-hidden="true">
217+
<rect x="8" y="8" width="11" height="11"></rect>
218+
<path d="M16 8V5a1 1 0 0 0-1-1H5a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h3"></path>
219+
</svg>
220+
<span>Copy social post</span>
221+
</button>
222+
</div>
207223
</header>
208224

209225
<div class="detail-stack">

site/loops/autonomy-loop/index.html

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
<link rel="alternate" type="application/json" title="Loop Library catalog" href="https://signals.forwardfuture.ai/loop-library/catalog.json" />
5858
<link rel="alternate" type="text/markdown" title="Loop Library catalog in Markdown" href="https://signals.forwardfuture.ai/loop-library/catalog.md" />
5959
<link rel="icon" type="image/png" href="../../assets/favicon.png" />
60-
<link rel="stylesheet" href="../../styles.css?v=20260617-simple-detail" />
60+
<link rel="stylesheet" href="../../styles.css?v=20260620-social-copy" />
6161
<script type="application/ld+json">
6262
{
6363
"@context": "https://schema.org",
@@ -130,7 +130,7 @@
130130
]
131131
}
132132
</script>
133-
<script src="../../script.js?v=20260618-x-handle" defer></script>
133+
<script src="../../script.js?v=20260620-social-copy" defer></script>
134134
<title>autonomy-loop Builder-Reviewer Workflow | Loop Library</title>
135135
</head>
136136
<body>
@@ -205,6 +205,22 @@ <h1>The autonomy-loop builder-reviewer loop</h1>
205205
<p class="detail-byline">
206206
Contributed by <strong>@inferencegod</strong> · <a class="detail-source-link" href="https://github.com/inferencegod/autonomy-loop" target="_blank" rel="noopener noreferrer">Source</a>
207207
</p>
208+
<div class="share-actions" aria-label="Share this loop">
209+
<button
210+
class="share-action share-action-primary"
211+
type="button"
212+
data-copy-social-post
213+
data-post-text="Try &quot;The autonomy-loop builder-reviewer loop&quot; from the Loop Library: Passes code between builder and reviewer until tests prove each accepted fix."
214+
data-post-url="https://signals.forwardfuture.ai/loop-library/loops/autonomy-loop/"
215+
aria-label="Copy a social post about The autonomy-loop builder-reviewer loop"
216+
>
217+
<svg class="share-copy-icon" viewBox="0 0 24 24" aria-hidden="true">
218+
<rect x="8" y="8" width="11" height="11"></rect>
219+
<path d="M16 8V5a1 1 0 0 0-1-1H5a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h3"></path>
220+
</svg>
221+
<span>Copy social post</span>
222+
</button>
223+
</div>
208224
</header>
209225

210226
<div class="detail-stack">

site/loops/boeing-747-benchmark/index.html

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
<link rel="alternate" type="application/json" title="Loop Library catalog" href="https://signals.forwardfuture.ai/loop-library/catalog.json" />
5858
<link rel="alternate" type="text/markdown" title="Loop Library catalog in Markdown" href="https://signals.forwardfuture.ai/loop-library/catalog.md" />
5959
<link rel="icon" type="image/png" href="../../assets/favicon.png" />
60-
<link rel="stylesheet" href="../../styles.css?v=20260617-simple-detail" />
60+
<link rel="stylesheet" href="../../styles.css?v=20260620-social-copy" />
6161
<script type="application/ld+json">
6262
{
6363
"@context": "https://schema.org",
@@ -130,7 +130,7 @@
130130
]
131131
}
132132
</script>
133-
<script src="../../script.js?v=20260618-x-handle" defer></script>
133+
<script src="../../script.js?v=20260620-social-copy" defer></script>
134134
<title>Boeing 747 Three.js Vision Benchmark | Loop Library</title>
135135
</head>
136136
<body>
@@ -205,6 +205,22 @@ <h1>The Boeing 747 benchmark</h1>
205205
<p class="detail-byline">
206206
Contributed by <strong>@victormustar</strong> · <a class="detail-source-link" href="https://x.com/victormustar/status/2064449741685968967" target="_blank" rel="noopener noreferrer">Source</a>
207207
</p>
208+
<div class="share-actions" aria-label="Share this loop">
209+
<button
210+
class="share-action share-action-primary"
211+
type="button"
212+
data-copy-social-post
213+
data-post-text="Try &quot;The Boeing 747 benchmark&quot; from the Loop Library: Builds and improves a Three.js Boeing 747 across nine repeatable views."
214+
data-post-url="https://signals.forwardfuture.ai/loop-library/loops/boeing-747-benchmark/"
215+
aria-label="Copy a social post about The Boeing 747 benchmark"
216+
>
217+
<svg class="share-copy-icon" viewBox="0 0 24 24" aria-hidden="true">
218+
<rect x="8" y="8" width="11" height="11"></rect>
219+
<path d="M16 8V5a1 1 0 0 0-1-1H5a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h3"></path>
220+
</svg>
221+
<span>Copy social post</span>
222+
</button>
223+
</div>
208224
</header>
209225

210226
<div class="detail-stack">

site/loops/clodex-adversarial-review-loop/index.html

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
<link rel="alternate" type="application/json" title="Loop Library catalog" href="https://signals.forwardfuture.ai/loop-library/catalog.json" />
5858
<link rel="alternate" type="text/markdown" title="Loop Library catalog in Markdown" href="https://signals.forwardfuture.ai/loop-library/catalog.md" />
5959
<link rel="icon" type="image/png" href="../../assets/favicon.png" />
60-
<link rel="stylesheet" href="../../styles.css?v=20260617-simple-detail" />
60+
<link rel="stylesheet" href="../../styles.css?v=20260620-social-copy" />
6161
<script type="application/ld+json">
6262
{
6363
"@context": "https://schema.org",
@@ -130,7 +130,7 @@
130130
]
131131
}
132132
</script>
133-
<script src="../../script.js?v=20260618-x-handle" defer></script>
133+
<script src="../../script.js?v=20260620-social-copy" defer></script>
134134
<title>Clodex Adversarial Code Review Loop | Loop Library</title>
135135
</head>
136136
<body>
@@ -205,6 +205,22 @@ <h1>The Clodex adversarial-review loop</h1>
205205
<p class="detail-byline">
206206
Contributed by <strong>Lukas Kucinski</strong> · <a class="detail-source-link" href="https://github.com/lukaskucinski/clodex" target="_blank" rel="noopener noreferrer">Source</a>
207207
</p>
208+
<div class="share-actions" aria-label="Share this loop">
209+
<button
210+
class="share-action share-action-primary"
211+
type="button"
212+
data-copy-social-post
213+
data-post-text="Try &quot;The Clodex adversarial-review loop&quot; from the Loop Library: Uses Codex to review Claude&#39;s pull request until blocking findings are resolved."
214+
data-post-url="https://signals.forwardfuture.ai/loop-library/loops/clodex-adversarial-review-loop/"
215+
aria-label="Copy a social post about The Clodex adversarial-review loop"
216+
>
217+
<svg class="share-copy-icon" viewBox="0 0 24 24" aria-hidden="true">
218+
<rect x="8" y="8" width="11" height="11"></rect>
219+
<path d="M16 8V5a1 1 0 0 0-1-1H5a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h3"></path>
220+
</svg>
221+
<span>Copy social post</span>
222+
</button>
223+
</div>
208224
</header>
209225

210226
<div class="detail-stack">

0 commit comments

Comments
 (0)