Skip to content

Commit 9201e68

Browse files
authored
Move loop catalog to database (#61)
1 parent 5d234c8 commit 9201e68

929 files changed

Lines changed: 3929 additions & 30215 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -33,30 +33,11 @@ jobs:
3333
- name: Install Worker dependencies
3434
run: npm ci --prefix worker
3535

36-
- name: Verify generated artifacts
37-
run: |
38-
node scripts/build-skill-catalog.mjs
39-
node scripts/build-loop-pages.mjs
40-
node scripts/build-social-images.mjs
41-
if [[ -n "$(git status --porcelain --untracked-files=all)" ]]; then
42-
git status --short
43-
git diff
44-
exit 1
45-
fi
46-
4736
- name: Validate site and skill sources
4837
run: |
49-
node --check scripts/build-skill-catalog.mjs
50-
node --check scripts/build-loop-pages.mjs
51-
node --check scripts/build-social-images.mjs
52-
node --check scripts/audit-seo-geo.mjs
53-
node --check scripts/loop-data.mjs
54-
node --check scripts/validate-loop-data.mjs
5538
node --check site/script.js
56-
node scripts/audit-seo-geo.mjs
5739
node scripts/check.mjs
5840
python3 -m json.tool site/.herenow/data.json >/dev/null
59-
python3 -m json.tool site/catalog.json >/dev/null
6041
python3 -m json.tool scripts/seo-geo-query-benchmark.json >/dev/null
6142
git diff --check
6243

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
/.herenow/
33
site/.herenow/state.json
44
node_modules/
5+
.wrangler/
56
__pycache__/
67
*.py[cod]
78
/.playwright-mcp/

AGENTS.md

Lines changed: 46 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2,50 +2,49 @@
22

33
## Adding or editing loops
44

5-
- Treat `scripts/loop-data.mjs` as the canonical SEO/GEO content catalog for
6-
every public loop.
7-
- Keep the matching searchable row in `site/index.html` aligned with the
8-
catalog entry, including title, prompt, attribution, link, and visible
9-
count.
10-
- Every loop must have a stable slug, unique search title and description,
11-
contributor attribution, published and modified dates, practical context,
12-
verification criteria, and related-loop links.
13-
- After changing the catalog or homepage rows, run
14-
`node scripts/build-skill-catalog.mjs` and
15-
`node scripts/build-loop-pages.mjs`, capture the versioned page screenshots,
16-
and then run `node scripts/build-social-images.mjs`. Commit the skill catalog,
17-
public Markdown/JSON catalogs, screenshots, generated detail pages,
18-
`site/sitemap.xml`, and `site/feed.xml`.
19-
- Capture the homepage and every loop page in the light theme at 1200 x 630
20-
using the versioned filenames in `site/assets/social/`. Before recapturing
21-
published artwork, bump `site.socialImageVersion` in
22-
`scripts/loop-data.mjs`; the social-image builder refuses to replace a path
23-
already present in `HEAD`.
24-
- Preserve older versioned social cards so links that already use them keep
25-
their artwork. Remove an old card only as an explicit cleanup.
26-
- Run the full repository checks before committing:
5+
- The production catalog database is the source of truth for public loops.
6+
The current Git tree holds application code and the content-free site shell.
7+
Do not commit published loop records, bootstrap data, generated loop pages,
8+
catalogs, feeds, sitemaps, or offline catalog fallbacks. Legacy public
9+
records remain in pre-migration Git history intentionally; do not rewrite
10+
shared history as part of routine catalog work.
11+
- Publish a reviewed loop from a JSON file outside the repository with:
12+
13+
```bash
14+
LOOP_PUBLISH_TOKEN=... \
15+
npm --prefix worker run loop:publish -- /path/to/loop.json
16+
```
17+
18+
Use `worker/examples/loop.json` as the record template. The command validates
19+
the complete record before writing it, and the Worker records every revision.
20+
- Every loop must have a stable slug, unique number, search title and
21+
description, contributor attribution, published and modified dates,
22+
practical context, verification criteria, category, keywords, and valid
23+
related-loop slugs.
24+
- Do not hand-edit the homepage, detail pages, catalogs, feed, sitemap, or skill
25+
content when publishing a database record. The Worker renders those public
26+
surfaces from the same record. New loops use the shared social card unless a
27+
reviewed HTTPS `socialImageUrl` is supplied.
28+
- Keep bootstrap and backup exports outside the repository with owner-only
29+
permissions. The one-time bootstrap command requires an explicit private
30+
file path; routine recovery exports use `npm --prefix worker run loops:export`.
31+
Restore an export only into a fresh empty catalog with
32+
`npm --prefix worker run loops:restore`; never overwrite a live catalog.
33+
- Changes to the site shell, Worker, schema, or renderers still go through
34+
GitHub. Run the full repository checks before committing those code changes:
2735

2836
```bash
29-
node scripts/build-skill-catalog.mjs
30-
node scripts/build-loop-pages.mjs
31-
node scripts/build-social-images.mjs
32-
node --check scripts/audit-seo-geo.mjs
33-
node --check scripts/build-social-images.mjs
3437
node --check site/script.js
35-
node --check scripts/build-loop-pages.mjs
36-
node --check scripts/loop-data.mjs
37-
node --check scripts/validate-loop-data.mjs
38-
node scripts/audit-seo-geo.mjs
3938
node scripts/check.mjs
4039
npm --prefix worker run check
4140
python3 -m json.tool site/.herenow/data.json >/dev/null
4241
python3 -m json.tool scripts/seo-geo-query-benchmark.json >/dev/null
4342
git diff --check
4443
```
4544

46-
- Do not add a loop if the checks report drift between the homepage, source
47-
catalog, live catalogs, installable skill fallback, generated pages,
48-
structured data, sitemap, or feed.
45+
- Do not publish a loop unless its public homepage row, detail page,
46+
`catalog.json`, `catalog.md`, sitemap, and feed all read back from production
47+
with the expected slug and modified date.
4948

5049
## Protected forms
5150

@@ -85,6 +84,7 @@ npm exec -- wrangler secret put TURNSTILE_SECRET_KEY
8584
npm exec -- wrangler secret put TURNSTILE_HOSTNAMES
8685
npm exec -- wrangler secret put HERENOW_API_KEY
8786
npm exec -- wrangler secret put HERENOW_SITE_SLUG
87+
npm exec -- wrangler secret put LOOP_PUBLISH_TOKEN
8888
npm run deploy
8989
```
9090

@@ -123,10 +123,18 @@ curl -sS "https://here.now/api/v1/publishes/{slug}/data/weekly_signups?limit=50"
123123
active deployment, then fetch and fast-forward again before selecting the
124124
deployment revision.
125125
- Hold the lock through here.now finalize and production verification.
126-
- Deploy and verify the form Worker before publishing a site revision that
127-
changes Site Data form collections to owner-only.
128-
- Verify both `https://signals.forwardfuture.ai/loop-library/` and the backing
129-
here.now Site before reporting success.
126+
- Deploy and verify the Worker before publishing a site revision that changes
127+
Site Data form collections, catalog storage, or database-backed rendering.
128+
- For the initial database cutover, deploy the Worker, import the reviewed
129+
private bootstrap bundle, verify all canonical database surfaces, and only
130+
then deploy the content-free here.now shell. Never publish the empty shell
131+
before the database catalog is active.
132+
- The exact Worker routes at `signals.forwardfuture.ai/loop-library` and
133+
`signals.forwardfuture.ai/loop-library/*` render database content and pass
134+
site-shell assets through to the explicit `PUBLIC_ORIGIN_URL` here.now
135+
hostname. Update that variable if the backing Site changes. Verify the
136+
canonical URL for database content and the backing here.now Site for the
137+
static shell before reporting success.
130138
- After a production content deployment, submit
131139
`https://signals.forwardfuture.ai/loop-library/sitemap.xml` in Google Search
132140
Console and Bing Webmaster Tools. Verify that the custom domain's root

README.md

Lines changed: 60 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Loop Library has two separate but related parts in this repository:
44

55
| Part | What it is | Where it lives |
66
| --- | --- | --- |
7-
| **Loop Library website** | The public catalog where people and agents can browse published loops, read them, and copy their prompts. No installation is required. | [Live website](https://signals.forwardfuture.ai/loop-library/) · source in [`site/`](site/) and [`scripts/loop-data.mjs`](scripts/loop-data.mjs) |
7+
| **Loop Library website** | The public catalog where people and agents can browse published loops, read them, and copy their prompts. No installation is required. | [Live website](https://signals.forwardfuture.ai/loop-library/) · shell in [`site/`](site/), database and rendering in [`worker/`](worker/) |
88
| **Loop Library skill** | An optional installable guide that helps an AI agent find, audit, repair, adapt, or design loops through conversation. It uses the website's live catalog when recommending published loops. | source in [`skills/loop-library/`](skills/loop-library/) |
99

1010
The website is the library; the skill is a companion way to work with it. You
@@ -185,6 +185,63 @@ available under the [MIT License](LICENSE).
185185
<details>
186186
<summary>Notes for maintainers</summary>
187187

188+
### Publish a loop
189+
190+
Public loops are stored in the catalog database attached to the Cloudflare
191+
Worker. Publishing a reviewed loop does not require a GitHub commit or a static
192+
site deployment.
193+
194+
Copy `worker/examples/loop.json` somewhere outside the repository, fill in the
195+
record, and run:
196+
197+
```bash
198+
LOOP_PUBLISH_TOKEN=... \
199+
npm --prefix worker run loop:publish -- /path/to/loop.json
200+
```
201+
202+
The command validates the record and publishes the homepage row, detail page,
203+
JSON/Markdown/plain-text catalogs, feed, and sitemap from the same database
204+
write. Use `--draft` to save a non-public record or `--archive` to remove a
205+
record from public responses without deleting its revision history.
206+
207+
The first database-backed release needs one import from the private migration
208+
bundle. Loop records and bootstrap data are intentionally not committed to
209+
GitHub:
210+
211+
```bash
212+
LOOP_PUBLISH_TOKEN=... \
213+
npm --prefix worker run loops:import -- /private/path/bootstrap.json
214+
```
215+
216+
Set a long random `LOOP_PUBLISH_TOKEN` as a Worker secret. The catalog uses a
217+
SQLite-backed Durable Object and keeps an append-only revision for every
218+
publish. The reviewed bootstrap digest is enforced before the database can be
219+
activated.
220+
221+
Create a private backup of the current database with:
222+
223+
```bash
224+
LOOP_PUBLISH_TOKEN=... \
225+
npm --prefix worker run loops:export -- /private/path/catalog-backup.ndjson
226+
```
227+
228+
Restore that snapshot only into a fresh, empty catalog database:
229+
230+
```bash
231+
LOOP_PUBLISH_TOKEN=... \
232+
npm --prefix worker run loops:restore -- /private/path/catalog-backup.ndjson
233+
```
234+
235+
Bootstrap and backup files must be owner-only (`chmod 600`). Exports include
236+
drafts, archived records, and complete revision history; keep them outside the
237+
repository.
238+
239+
The current Git tree contains the site shell and rendering code, but no
240+
published loop records, generated loop pages, catalogs, feed, sitemap, or
241+
offline catalog fallback. The legacy catalog and source-attribution metadata
242+
were already public and intentionally remain in pre-migration Git history;
243+
this migration does not rewrite repository history or disrupt existing clones.
244+
188245
### Preview locally
189246

190247
```bash
@@ -197,16 +254,7 @@ Then open `http://localhost:4173`.
197254

198255
```bash
199256
npm ci --prefix worker
200-
node scripts/build-skill-catalog.mjs
201-
node scripts/build-loop-pages.mjs
202-
node scripts/build-social-images.mjs
203-
node --check scripts/audit-seo-geo.mjs
204-
node --check scripts/build-social-images.mjs
205257
node --check site/script.js
206-
node --check scripts/build-loop-pages.mjs
207-
node --check scripts/loop-data.mjs
208-
node --check scripts/validate-loop-data.mjs
209-
node scripts/audit-seo-geo.mjs
210258
node scripts/check.mjs
211259
npm --prefix worker run check
212260
python3 -m json.tool site/.herenow/data.json >/dev/null
@@ -215,7 +263,7 @@ git diff --check
215263
```
216264

217265
Read [AGENTS.md](AGENTS.md) before editing loops or publishing the site. It
218-
contains the source-of-truth rules for generated files, form security, and
219-
clean-main deployments.
266+
contains the source-of-truth rules for database publishing, generated
267+
responses, form security, and clean-main deployments.
220268

221269
</details>

0 commit comments

Comments
 (0)