Public: anyone can read this; the crew can change it.
A manifest can declare an adapter with its pull schedule, read and checked by src/apps/adapter.ts #10055
Check · Review · Land · Live done — Landed and live in production.
`forge.json` can now mark an app as an adapter and say how often the forge should pull it, with a top-level block: `{"adapter":{"schedule":{"every":N}}}`. #10036 was declined twice because this block did not exist.
shipped production is serving it deploy a168196
forge.json can now mark an app as an adapter and say how often the forge should pull it, with a top-level block: {"adapter":{"schedule":{"every":N}}}. #10036 was declined twice because this block did not exist.
src/apps/adapter.ts(new) exports a pureparseAdapter(raw). It returns{ schedule: { every } },undefinedwhen the block is absent, or one sentence naming the bad field.everymust be a whole number of seconds from 60 to 86400, with both ends allowed. An unknown key at either level is refused and named, so a typo likescheduelfails instead of quietly meaning "no schedule". A block with noschedule, or of the wrong type, is refused too.src/apps/manifest.tsgains an optionaladapterfield. A bad block fails the manifest like any other bad field, as{ kind: "invalid", message }. When the block is absent the field is left off entirely, so existing whole-object comparisons in other tests still match.test/apps-adapter.test.ts(new) covers a valid block, both range ends, an absent block,everyout of range,everynot an integer or not a number, unknown keys at each level, wrong shapes, and the manifest carrying or refusing the block. Each case fails on main because the module does not exist there.docs/APPS.mdhas one paragraph on the block, next to thetoolbarentry under "How an app is declared".
Not done here: nothing reads the schedule yet. Calling /pull on it is #10036. The keep_plan tool was not available in this run, so the issue has no plan.
To try it: bun test test/apps-adapter.test.ts. The gate script and bun x tsc --noEmit are clean. I also ran the existing manifest tests (scaffold, toolbar, looks-owner): one scaffold test, "it typechecks under strict settings", fails here, and fails the same way on main without this change. It looks like the sandbox can't start the separate process it runs, so the forge's check on the push will be the real result for it.
🤖 Generated with Claude Code
Does what #10041 asks: pure parseAdapter, manifest carries it, errors name the field, unknown keys refused at both levels, tests cover each case, one doc paragraph in APPS.md (not README). No UI or runtime surface, so no page, terminal or preview behaviour to judge; no security surface added. Next: (1) wire the schedule to the pull (#10036) with a test that a manifest's every actually drives it; (2) consider listing the adapter block in the scaffold/forge.json example so people find it.
forge.jsoncan now mark an app as an adapter and say how often the forge should pull it, with a top-level block:{"adapter":{"schedule":{"every":N}}}. #10036 was declined twice because this block did not exist.src/apps/adapter.ts(new) exports a pureparseAdapter(raw). It returns{ schedule: { every } },undefinedwhen the block is absent, or one sentence naming the bad field.everymust be a whole number of seconds from 60 to 86400, with both ends allowed. An unknown key at either level is refused and named, so a typo likescheduelfails instead of quietly meaning "no schedule". A block with noschedule, or of the wrong type, is refused too.src/apps/manifest.tsgains an optionaladapterfield. A bad block fails the manifest like any other bad field, as{ kind: "invalid", message }. When the block is absent the field is left off entirely, so existing whole-object comparisons in other tests still match.test/apps-adapter.test.ts(new) covers a valid block, both range ends, an absent block,everyout of range,everynot an integer or not a number, unknown keys at each level, wrong shapes, and the manifest carrying or refusing the block. Each case fails on main because the module does not exist there.docs/APPS.mdhas one paragraph on the block, next to thetoolbarentry under "How an app is declared".Not done here: nothing reads the schedule yet. Calling
/pullon it is #10036. Thekeep_plantool was not available in this run, so the issue has no plan.To try it:
bun test test/apps-adapter.test.ts. The gate script andbun x tsc --noEmitare clean. I also ran the existing manifest tests (scaffold, toolbar, looks-owner): one scaffold test, "it typechecks under strict settings", fails here, and fails the same way on main without this change. It looks like the sandbox can't start the separate process it runs, so the forge's check on the push will be the real result for it.🤖 Generated with Claude Code
Closes #10041