diff --git a/scripts/build-loop-pages.mjs b/scripts/build-loop-pages.mjs
index 27078ad..51b4c2f 100644
--- a/scripts/build-loop-pages.mjs
+++ b/scripts/build-loop-pages.mjs
@@ -252,7 +252,7 @@ function renderLoopPage(loop) {
-
+
${escapeHtml(loop.seoTitle)}
diff --git a/scripts/check.mjs b/scripts/check.mjs
index d949490..fd03978 100644
--- a/scripts/check.mjs
+++ b/scripts/check.mjs
@@ -544,7 +544,7 @@ for (const [index, loop] of loops.entries()) {
);
assert(page.includes(`rel="help" href="${siteMeta.baseUrl}agents/"`));
assert(page.includes("../../styles.css?v=20260620-primary-nav"));
- assert(page.includes("../../script.js?v=20260620-primary-nav"));
+ assert(page.includes("../../script.js?v=20260621-url-state"));
assert(page.includes(`Type'));
assert(html.includes("./styles.css?v=20260620-primary-nav"));
-assert(html.includes("./script.js?v=20260620-primary-nav"));
+assert(html.includes("./script.js?v=20260621-url-state"));
const homepagePostText =
"Find Loops and create your own - Loop Library";
assert(html.includes('class="share-actions" aria-label="Share Loop Library"'));
@@ -870,7 +870,7 @@ assert.equal(
2,
);
assert(learnHtml.includes("../styles.css?v=20260620-article-layout"));
-assert(learnHtml.includes("../script.js?v=20260620-primary-nav"));
+assert(learnHtml.includes("../script.js?v=20260621-url-state"));
assert(learnHtml.includes("How agent loops work"));
assert(learnHtml.includes('
-
+
-
+
Loop Library: Repeatable AI Agent Workflows | Forward Future
diff --git a/site/learn/index.html b/site/learn/index.html
index 813854f..eabd7c9 100644
--- a/site/learn/index.html
+++ b/site/learn/index.html
@@ -75,7 +75,7 @@
/>
-
+
-
+
100% Test Coverage Loop for Coding Agents | Loop Library
diff --git a/site/loops/accessibility-repair-loop/index.html b/site/loops/accessibility-repair-loop/index.html
index 480230b..0f89f43 100644
--- a/site/loops/accessibility-repair-loop/index.html
+++ b/site/loops/accessibility-repair-loop/index.html
@@ -132,7 +132,7 @@
]
}
-
+
Accessibility Repair Loop | Loop Library
diff --git a/site/loops/architecture-satisfaction-loop/index.html b/site/loops/architecture-satisfaction-loop/index.html
index 6196a03..2557023 100644
--- a/site/loops/architecture-satisfaction-loop/index.html
+++ b/site/loops/architecture-satisfaction-loop/index.html
@@ -132,7 +132,7 @@
]
}
-
+
Architecture Refactoring Loop for Coding Agents | Loop Library
diff --git a/site/loops/autonomy-loop/index.html b/site/loops/autonomy-loop/index.html
index 095ab9e..834c5ff 100644
--- a/site/loops/autonomy-loop/index.html
+++ b/site/loops/autonomy-loop/index.html
@@ -133,7 +133,7 @@
]
}
-
+
autonomy-loop Builder-Reviewer Workflow | Loop Library
diff --git a/site/loops/axelrod-subagent-arena-loop/index.html b/site/loops/axelrod-subagent-arena-loop/index.html
index a5eb0d7..ef69d89 100644
--- a/site/loops/axelrod-subagent-arena-loop/index.html
+++ b/site/loops/axelrod-subagent-arena-loop/index.html
@@ -133,7 +133,7 @@
]
}
-
+
Axelrod Subagent Arena Benchmark | Loop Library
diff --git a/site/loops/boeing-747-benchmark/index.html b/site/loops/boeing-747-benchmark/index.html
index b422ff0..8bffe05 100644
--- a/site/loops/boeing-747-benchmark/index.html
+++ b/site/loops/boeing-747-benchmark/index.html
@@ -133,7 +133,7 @@
]
}
-
+
Boeing 747 Three.js Vision Benchmark | Loop Library
diff --git a/site/loops/clodex-adversarial-review-loop/index.html b/site/loops/clodex-adversarial-review-loop/index.html
index 390a505..9942a4a 100644
--- a/site/loops/clodex-adversarial-review-loop/index.html
+++ b/site/loops/clodex-adversarial-review-loop/index.html
@@ -133,7 +133,7 @@
]
}
-
+
Clodex Adversarial Code Review Loop | Loop Library
diff --git a/site/loops/codex-completion-contract-loop/index.html b/site/loops/codex-completion-contract-loop/index.html
index ae8c50a..31e960a 100644
--- a/site/loops/codex-completion-contract-loop/index.html
+++ b/site/loops/codex-completion-contract-loop/index.html
@@ -133,7 +133,7 @@
]
}
-
+
Codex Completion Contract and Evidence Loop | Loop Library
diff --git a/site/loops/cold-load-trimmer-loop/index.html b/site/loops/cold-load-trimmer-loop/index.html
index 441523e..b9aa027 100644
--- a/site/loops/cold-load-trimmer-loop/index.html
+++ b/site/loops/cold-load-trimmer-loop/index.html
@@ -133,7 +133,7 @@
]
}
-
+
Cold-Load Byte Reduction Loop | Loop Library
diff --git a/site/loops/customer-ai-deployment-loop/index.html b/site/loops/customer-ai-deployment-loop/index.html
index 725d6e4..f4fe73d 100644
--- a/site/loops/customer-ai-deployment-loop/index.html
+++ b/site/loops/customer-ai-deployment-loop/index.html
@@ -133,7 +133,7 @@
]
}
-
+
Customer AI Deployment Loop | Loop Library
diff --git a/site/loops/devils-advocate-design-loop/index.html b/site/loops/devils-advocate-design-loop/index.html
index 689476c..17c5a20 100644
--- a/site/loops/devils-advocate-design-loop/index.html
+++ b/site/loops/devils-advocate-design-loop/index.html
@@ -132,7 +132,7 @@
]
}
-
+
Devil's-Advocate Design Review Loop | Loop Library
diff --git a/site/loops/easy-onboarding-loop/index.html b/site/loops/easy-onboarding-loop/index.html
index f735ab2..a752aa2 100644
--- a/site/loops/easy-onboarding-loop/index.html
+++ b/site/loops/easy-onboarding-loop/index.html
@@ -132,7 +132,7 @@
]
}
-
+
Fresh-State Onboarding Improvement Loop | Loop Library
diff --git a/site/loops/exhaustive-logging-coverage-loop/index.html b/site/loops/exhaustive-logging-coverage-loop/index.html
index 71b4b53..101c529 100644
--- a/site/loops/exhaustive-logging-coverage-loop/index.html
+++ b/site/loops/exhaustive-logging-coverage-loop/index.html
@@ -132,7 +132,7 @@
]
}
-
+
Logging Coverage Loop for Coding Agents | Loop Library
diff --git a/site/loops/five-minute-repository-maintainer-loop/index.html b/site/loops/five-minute-repository-maintainer-loop/index.html
index 2ab9e1d..573e6ac 100644
--- a/site/loops/five-minute-repository-maintainer-loop/index.html
+++ b/site/loops/five-minute-repository-maintainer-loop/index.html
@@ -133,7 +133,7 @@
]
}
-
+
Five-Minute Repository Maintainer Loop | Loop Library
diff --git a/site/loops/fresh-clone-loop/index.html b/site/loops/fresh-clone-loop/index.html
index b008a7c..cfade18 100644
--- a/site/loops/fresh-clone-loop/index.html
+++ b/site/loops/fresh-clone-loop/index.html
@@ -132,7 +132,7 @@
]
}
-
+
Fresh Clone README Verification Loop | Loop Library
diff --git a/site/loops/full-product-evaluation-loop/index.html b/site/loops/full-product-evaluation-loop/index.html
index c9dbb18..f30cb7c 100644
--- a/site/loops/full-product-evaluation-loop/index.html
+++ b/site/loops/full-product-evaluation-loop/index.html
@@ -132,7 +132,7 @@
]
}
-
+
Full Product Evaluation Loop for AI Systems | Loop Library
diff --git a/site/loops/goal-forge-loop/index.html b/site/loops/goal-forge-loop/index.html
index 28d0453..a310d34 100644
--- a/site/loops/goal-forge-loop/index.html
+++ b/site/loops/goal-forge-loop/index.html
@@ -133,7 +133,7 @@
]
}
-
+
Goal Forge Specification Loop for Codex | Loop Library
diff --git a/site/loops/housekeeper-loop/index.html b/site/loops/housekeeper-loop/index.html
index ca9048b..e430580 100644
--- a/site/loops/housekeeper-loop/index.html
+++ b/site/loops/housekeeper-loop/index.html
@@ -132,7 +132,7 @@
]
}
-
+
Repository Housekeeper Cleanup Loop | Loop Library
diff --git a/site/loops/infinite-clickbait-loop/index.html b/site/loops/infinite-clickbait-loop/index.html
index 1e6835d..eac5f02 100644
--- a/site/loops/infinite-clickbait-loop/index.html
+++ b/site/loops/infinite-clickbait-loop/index.html
@@ -132,7 +132,7 @@
]
}
-
+
Infinite Clickbait Thumbnail Iteration Loop | Loop Library
diff --git a/site/loops/loop-harness-verification-loop/index.html b/site/loops/loop-harness-verification-loop/index.html
index c7b0e1e..a073344 100644
--- a/site/loops/loop-harness-verification-loop/index.html
+++ b/site/loops/loop-harness-verification-loop/index.html
@@ -133,7 +133,7 @@
]
}
-
+
Loop Harness Second-Agent Verification Workflow | Loop Library
diff --git a/site/loops/multi-llm-convergence-loop/index.html b/site/loops/multi-llm-convergence-loop/index.html
index 9038086..0157df1 100644
--- a/site/loops/multi-llm-convergence-loop/index.html
+++ b/site/loops/multi-llm-convergence-loop/index.html
@@ -133,7 +133,7 @@
]
}
-
+
Multi-LLM Convergence Review Loop | Loop Library
diff --git a/site/loops/nightly-changelog-sweep/index.html b/site/loops/nightly-changelog-sweep/index.html
index 3c8c174..ab194b4 100644
--- a/site/loops/nightly-changelog-sweep/index.html
+++ b/site/loops/nightly-changelog-sweep/index.html
@@ -132,7 +132,7 @@
]
}
-
+
Nightly Changelog Loop for Coding Agents | Loop Library
diff --git a/site/loops/overnight-docs-sweep/index.html b/site/loops/overnight-docs-sweep/index.html
index 5338de2..4dfc406 100644
--- a/site/loops/overnight-docs-sweep/index.html
+++ b/site/loops/overnight-docs-sweep/index.html
@@ -132,7 +132,7 @@
]
}
-
+
Documentation Sweep for Coding Agents | Loop Library
diff --git a/site/loops/pixel-safe-css-trim-loop/index.html b/site/loops/pixel-safe-css-trim-loop/index.html
index 564fc4d..c84312d 100644
--- a/site/loops/pixel-safe-css-trim-loop/index.html
+++ b/site/loops/pixel-safe-css-trim-loop/index.html
@@ -133,7 +133,7 @@
]
}
-
+
Pixel-Safe CSS Reduction Loop | Loop Library
diff --git a/site/loops/post-release-baseline-loop/index.html b/site/loops/post-release-baseline-loop/index.html
index bb9bcf9..0770b56 100644
--- a/site/loops/post-release-baseline-loop/index.html
+++ b/site/loops/post-release-baseline-loop/index.html
@@ -132,7 +132,7 @@
]
}
-
+
Post-Release Benchmark Baseline Loop | Loop Library
diff --git a/site/loops/prepare-new-project-loop/index.html b/site/loops/prepare-new-project-loop/index.html
index f2e55ac..8e0d0c3 100644
--- a/site/loops/prepare-new-project-loop/index.html
+++ b/site/loops/prepare-new-project-loop/index.html
@@ -132,7 +132,7 @@
]
}
-
+
Prepare a New Project Documentation Loop | Loop Library
diff --git a/site/loops/product-update-podcast-loop/index.html b/site/loops/product-update-podcast-loop/index.html
index 04b07fd..bfd3752 100644
--- a/site/loops/product-update-podcast-loop/index.html
+++ b/site/loops/product-update-podcast-loop/index.html
@@ -133,7 +133,7 @@
]
}
-
+
Product Update Podcast Automation Loop | Loop Library
diff --git a/site/loops/production-data-cleanup-loop/index.html b/site/loops/production-data-cleanup-loop/index.html
index da4c5b9..2c84582 100644
--- a/site/loops/production-data-cleanup-loop/index.html
+++ b/site/loops/production-data-cleanup-loop/index.html
@@ -132,7 +132,7 @@
]
}
-
+
Production Data Cleanup Loop for AI Systems | Loop Library
diff --git a/site/loops/production-error-sweep/index.html b/site/loops/production-error-sweep/index.html
index c079cfd..adf0276 100644
--- a/site/loops/production-error-sweep/index.html
+++ b/site/loops/production-error-sweep/index.html
@@ -132,7 +132,7 @@
]
}
-
+
Production Error Triage Loop for Coding Agents | Loop Library
diff --git a/site/loops/promise-to-proof-loop/index.html b/site/loops/promise-to-proof-loop/index.html
index 7ae61c3..f726a3c 100644
--- a/site/loops/promise-to-proof-loop/index.html
+++ b/site/loops/promise-to-proof-loop/index.html
@@ -132,7 +132,7 @@
]
}
-
+
Promise-to-Proof Product Audit | Loop Library
diff --git a/site/loops/propagation-compliance-loop/index.html b/site/loops/propagation-compliance-loop/index.html
index ac1f400..47b0cea 100644
--- a/site/loops/propagation-compliance-loop/index.html
+++ b/site/loops/propagation-compliance-loop/index.html
@@ -132,7 +132,7 @@
]
}
-
+
Repository Propagation Compliance Loop | Loop Library
diff --git a/site/loops/quality-streak-loop/index.html b/site/loops/quality-streak-loop/index.html
index cb4fd06..b94f6cc 100644
--- a/site/loops/quality-streak-loop/index.html
+++ b/site/loops/quality-streak-loop/index.html
@@ -132,7 +132,7 @@
]
}
-
+
Quality Streak Evaluation Loop for AI Products | Loop Library
diff --git a/site/loops/recent-feedback-sweep/index.html b/site/loops/recent-feedback-sweep/index.html
index 08323aa..8ede343 100644
--- a/site/loops/recent-feedback-sweep/index.html
+++ b/site/loops/recent-feedback-sweep/index.html
@@ -132,7 +132,7 @@
]
}
-
+
Recent-Feedback Project Audit | Loop Library
diff --git a/site/loops/repository-cleanup-loop/index.html b/site/loops/repository-cleanup-loop/index.html
index fd20151..8c221d7 100644
--- a/site/loops/repository-cleanup-loop/index.html
+++ b/site/loops/repository-cleanup-loop/index.html
@@ -132,7 +132,7 @@
]
}
-
+
Repository Cleanup Loop for Coding Agents | Loop Library
diff --git a/site/loops/revolve-self-improvement-loop/index.html b/site/loops/revolve-self-improvement-loop/index.html
index edd8428..cafd98f 100644
--- a/site/loops/revolve-self-improvement-loop/index.html
+++ b/site/loops/revolve-self-improvement-loop/index.html
@@ -133,7 +133,7 @@
]
}
-
+
Revolve Versioned Experiment Loop | Loop Library
diff --git a/site/loops/self-improving-champion-loop/index.html b/site/loops/self-improving-champion-loop/index.html
index 0929f01..5fff1a3 100644
--- a/site/loops/self-improving-champion-loop/index.html
+++ b/site/loops/self-improving-champion-loop/index.html
@@ -132,7 +132,7 @@
]
}
-
+
Self-Improving Champion Evaluation Loop | Loop Library
diff --git a/site/loops/seo-geo-visibility-loop/index.html b/site/loops/seo-geo-visibility-loop/index.html
index 6104f51..acecb56 100644
--- a/site/loops/seo-geo-visibility-loop/index.html
+++ b/site/loops/seo-geo-visibility-loop/index.html
@@ -132,7 +132,7 @@
]
}
-
+
SEO and GEO Visibility Audit Loop | Loop Library
diff --git a/site/loops/stale-safe-batch-release-loop/index.html b/site/loops/stale-safe-batch-release-loop/index.html
index 613d241..bc9d931 100644
--- a/site/loops/stale-safe-batch-release-loop/index.html
+++ b/site/loops/stale-safe-batch-release-loop/index.html
@@ -132,7 +132,7 @@
]
}
-
+
Stale-Safe Batch Release Loop | Loop Library
diff --git a/site/loops/sub-50ms-page-load-loop/index.html b/site/loops/sub-50ms-page-load-loop/index.html
index 299feca..ae03d05 100644
--- a/site/loops/sub-50ms-page-load-loop/index.html
+++ b/site/loops/sub-50ms-page-load-loop/index.html
@@ -132,7 +132,7 @@
]
}
-
+
Sub-50 ms Page-Load Optimization Loop | Loop Library
diff --git a/site/loops/test-stabilizer-loop/index.html b/site/loops/test-stabilizer-loop/index.html
index af1123e..fe48a08 100644
--- a/site/loops/test-stabilizer-loop/index.html
+++ b/site/loops/test-stabilizer-loop/index.html
@@ -132,7 +132,7 @@
]
}
-
+
Flaky Test Stabilizer Loop | Loop Library
diff --git a/site/loops/test-suite-speed-loop/index.html b/site/loops/test-suite-speed-loop/index.html
index c524eb0..847cc0f 100644
--- a/site/loops/test-suite-speed-loop/index.html
+++ b/site/loops/test-suite-speed-loop/index.html
@@ -132,7 +132,7 @@
]
}
-
+
Test-Suite Speed Optimization Loop | Loop Library
diff --git a/site/loops/ticket-to-pr-ready-loop/index.html b/site/loops/ticket-to-pr-ready-loop/index.html
index 1e34821..d9c7c42 100644
--- a/site/loops/ticket-to-pr-ready-loop/index.html
+++ b/site/loops/ticket-to-pr-ready-loop/index.html
@@ -133,7 +133,7 @@
]
}
-
+
Ticket-to-PR-Ready Loop for Coding Agents | Loop Library
diff --git a/site/loops/ui-ux-score-loop/index.html b/site/loops/ui-ux-score-loop/index.html
index 6952466..d11ada7 100644
--- a/site/loops/ui-ux-score-loop/index.html
+++ b/site/loops/ui-ux-score-loop/index.html
@@ -133,7 +133,7 @@
]
}
-
+
Browser UI/UX Score Loop | Loop Library
diff --git a/site/loops/war-loops-frontend-designer/index.html b/site/loops/war-loops-frontend-designer/index.html
index 861af2e..ce0ae03 100644
--- a/site/loops/war-loops-frontend-designer/index.html
+++ b/site/loops/war-loops-frontend-designer/index.html
@@ -133,7 +133,7 @@
]
}
-
+
War Loops Frontend Reconstruction Workflow | Loop Library
diff --git a/site/script.js b/site/script.js
index cca734f..187d803 100644
--- a/site/script.js
+++ b/site/script.js
@@ -197,6 +197,71 @@ function updateLibrary() {
window.requestAnimationFrame(syncVisiblePromptToggles);
}
+// Keep the URL in sync with the search query, active category, and page so a
+// filtered view can be shared, bookmarked, and restored on reload or via the
+// browser's back/forward buttons. Defaults are omitted to keep clean URLs tidy.
+// `method` is "push" for deliberate category/pagination moves (so Back restores
+// the prior view) and "replace" for canonicalization and transient search typing.
+function syncUrlState(method = "replace") {
+ if (typeof window.history?.replaceState !== "function") {
+ return;
+ }
+
+ // Start from the current query string so parameters the library does not own
+ // (e.g. utm_source) survive; only q/category/page are managed here.
+ const params = new URLSearchParams(window.location.search);
+ const query = searchInput?.value.trim() ?? "";
+
+ if (query) {
+ params.set("q", query);
+ } else {
+ params.delete("q");
+ }
+
+ if (activeCategory && activeCategory !== "all") {
+ params.set("category", activeCategory);
+ } else {
+ params.delete("category");
+ }
+
+ if (currentPage > 1) {
+ params.set("page", String(currentPage));
+ } else {
+ params.delete("page");
+ }
+
+ const search = params.toString();
+ const nextUrl = `${window.location.pathname}${search ? `?${search}` : ""}${
+ window.location.hash
+ }`;
+ const currentUrl = `${window.location.pathname}${window.location.search}${window.location.hash}`;
+
+ if (nextUrl === currentUrl) {
+ return;
+ }
+
+ if (method === "push" && typeof window.history.pushState === "function") {
+ window.history.pushState(null, "", nextUrl);
+ } else {
+ window.history.replaceState(null, "", nextUrl);
+ }
+}
+
+function readUrlState() {
+ const params = new URLSearchParams(window.location.search);
+
+ if (searchInput) {
+ searchInput.value = params.get("q") ?? "";
+ }
+
+ applyCategory(params.get("category") ?? "all");
+
+ const requestedPage = Number.parseInt(params.get("page") ?? "1", 10);
+ currentPage = Number.isInteger(requestedPage) && requestedPage > 0
+ ? requestedPage
+ : 1;
+}
+
function focusFirstVisibleLoop() {
const firstVisibleTitle = loopRows
.find((row) => !row.hidden)
@@ -218,24 +283,32 @@ if (searchInput) {
const resetSearchPage = () => {
currentPage = 1;
updateLibrary();
+ syncUrlState("replace");
};
searchInput.addEventListener("input", resetSearchPage);
searchInput.addEventListener("search", resetSearchPage);
}
+function applyCategory(category) {
+ const known = categoryFilters.some(
+ (filter) => filter.dataset.categoryFilter === category,
+ );
+ activeCategory = known ? category : "all";
+
+ categoryFilters.forEach((candidate) => {
+ const isActive = candidate.dataset.categoryFilter === activeCategory;
+ candidate.classList.toggle("is-active", isActive);
+ candidate.setAttribute("aria-pressed", String(isActive));
+ });
+}
+
categoryFilters.forEach((filter) => {
filter.addEventListener("click", () => {
- activeCategory = filter.dataset.categoryFilter;
+ applyCategory(filter.dataset.categoryFilter);
currentPage = 1;
-
- categoryFilters.forEach((candidate) => {
- const isActive = candidate === filter;
- candidate.classList.toggle("is-active", isActive);
- candidate.setAttribute("aria-pressed", String(isActive));
- });
-
updateLibrary();
+ syncUrlState("push");
});
});
@@ -244,6 +317,7 @@ if (paginationPrevious) {
if (currentPage > 1) {
currentPage -= 1;
updateLibrary();
+ syncUrlState("push");
focusFirstVisibleLoop();
}
});
@@ -253,11 +327,19 @@ if (paginationNext) {
paginationNext.addEventListener("click", () => {
currentPage += 1;
updateLibrary();
+ syncUrlState("push");
focusFirstVisibleLoop();
});
}
+readUrlState();
updateLibrary();
+syncUrlState("replace");
+
+window.addEventListener("popstate", () => {
+ readUrlState();
+ updateLibrary();
+});
let promptResizeFrame;
window.addEventListener("resize", () => {