Commit c577e66
Fixes #20333
Clause-②: no
## Summary
`npm create objectstack`'s blank starter imported `./src/objects` alone,
so everything `os g view|action|flow|dashboard|app|skill` wrote was
never loaded and `os validate` counted 0 of it. The starter now wires
the seven generator barrels `os init` wires since PR #20329, in the
lines `os init` renders: `exportsOf` over `export {};` barrels, and
`requires: ['automation', 'triggers']`. The copy is bound to the CLI's
single source (`SCAFFOLD_WIRED_BARRELS` / `SCAFFOLD_WIRED_REQUIRES`,
derived from `GENERATOR_SCAFFOLD_TARGETS`) by a parity pin, so it is not
a second wiring rule. A per-PR pin drives `npm create objectstack` → `os
g object` (control) → `os g flow` → `os validate` and reads `Logic: 1
Flows`.
## What changed
-
`packages/create-objectstack/src/templates/blank/objectstack.config.ts`:
imports every wired barrel, declares the `exportsOf` helper, and hands
each barrel to its stack key. The objects import changes from
`'./src/objects/index.js'` to `'./src/objects'`, the extensionless form
`os init` renders, which the parity pin compares verbatim; the
template's `moduleResolution: bundler` resolves the directory index, and
a fresh scaffold type-checks. It carries `requires: ['automation',
'triggers']`. `automation` was already there for the three connector
plugins, and its comment keeps that reason.
- Six new `src/{views,actions,flows,dashboards,apps,skills}/index.ts`
barrels, byte-identical to what `os init` writes.
- Two pins in `packages/cli/test/` (below). The CLI is the only package
that can call the renderer, and it already depends on
`create-objectstack`.
- `packages/cli/package.json` gains
`@objectstack/connector-{rest,openapi,mcp}` as devDependencies (lockfile
+9 lines, one importer block). They exist only so the scaffolded project
the chain pin builds under the CLI's `node_modules` can resolve the
blank config's connector imports, and so CI builds them in
`@objectstack/cli#test`'s closure.
- `scripts/cross-package-test-inputs.mjs` and `turbo.json` declare the
blank config and `src/**` as inputs of `@objectstack/cli#test`, with a
witness for the barrel glob the scan cannot name.
- Docs this change made false (see below), and a `create-objectstack`
patch changeset.
## Why a static copy, and what binds it
`create-objectstack` cannot import the roster. The dependency edge runs
the other way, and the npx entry must not pull the CLI's closure: the
boundary `scripts/sync-scaffold-emission-policy.mjs` already documents.
Measured options:
- **Generate at build time.** The roster is computed from the
`GENERATORS` literal in `generate.ts`. Reading it at
`create-objectstack`'s build would need either text-parsing that
literal, or evaluating the CLI's source before the CLI's own
dependencies are built, which is a build-order cycle.
- **Parity pin over a static copy.** Chosen as the least machinery.
`create-objectstack-wiring-parity.test.ts` reads every expected line off
the CLI: the barrel import lines, the `exportsOf` line and the stack-key
lines of `TEMPLATES.app.configContent`, the `requires` tokens as a
superset of `SCAFFOLD_WIRED_REQUIRES`, and each empty barrel byte for
byte from `TEMPLATES.app.srcFiles`. A generator added to the roster, a
renderer change or a hand edit of the template reddens it (ablations A1
to A3).
## Measured before and after, through the real commands
The on-ramp's real `bin/` scaffolded `my-app --skip-install
--skip-skills` into a directory where the config's imports resolve, then
this repo's CLI ran.
| step | `origin/main` `c74de10a9` | this branch |
|:---|:---|:---|
| `os g object order_line` (control) | exit 0, reaches the stack | exit
0, reaches the stack |
| `os g flow order_line` | exit 0, **Not wired** | exit 0, reaches the
stack |
| `os validate` | exit 0, `Data: 2 Objects`, `Logic: 0 Flows` | exit 0,
`Data: 2 Objects`, `Logic: 1 Flows` |
- **`exportsOf` is required here too.** A fresh starter type-checks
(`tsc --noEmit`, 6.0.3, exit 0). The same starter with `Object.values`
on the empty barrels fails with 4 x TS2322 (actions, flows, dashboards,
apps). After generating the object and the flow it still type-checks.
- **`requires` boots.** `os dev --fresh` on a random port: the flow-less
fresh starter was healthy after about 22s, `/api/v1/ready` answered 200,
and `AutomationServicePlugin` and the record-change, schedule,
time-relative and api trigger plugins loaded, resolved through the CLI's
own dependencies. With the generated flow it was healthy after about 24s
and reported `Flows: 1 flow(s) 1 bound to triggers`. Neither boot
printed "not enabled" or "NOT installed".
- **Census.** `src/templates/` holds one starter, `blank`, which is also
the registry's only entry.
## Pins
- `packages/cli/test/create-objectstack-wiring-parity.test.ts` (unit,
per-PR): 20 cases, described above.
- `packages/cli/test/create-objectstack-stack-reach.test.ts`
(integration, per-PR, not `.e2e`): the chain above, with item names read
off the generator roster. It asserts the exit codes, the named subjects,
the absence of the wiring lines and of a `requires` line from `os g
flow`, and the `Data: 2 Objects` / `Logic: 1 Flows` counts. No prose is
pinned.
## Ablations
Each ran after the fix was committed. Mutations went through
`scripts/ablation-replace.mjs` in wrap mode, which verified the anchor
count and the blob change and restored with blob equal to HEAD and an
empty `git diff HEAD`.
- **A1, the wiring reverted** (the `flows: exportsOf(flows),` line
deleted, then `create-objectstack` rebuilt). `ablation-dist-preflight
--absent` confirmed the line was gone from `dist/`. Chain pin: 2 failed,
2 passed. The control and the scaffold stayed green, and `os g flow`
printed the wiring lines while validate read no `Logic: 1 Flows`. Parity
pin: 1 failed, 19 passed, on the stack-key comparison. Direction: red.
- **A1 restore.** Rebuilt; `ablation-dist-preflight` found the marker
present in `dist/templates/blank/objectstack.config.ts`, and the whole
tree was clean. Chain pin 4/4, parity pin 20/20.
- **A2, a barrel dropped from the template** (the `skills` key deleted):
parity 1 failed, 19 passed. Red.
- **A3, one barrel's bytes drifted from what `os init` writes**
(`views/index.ts` reworded): parity 1 failed, 19 passed. Red.
- After A2 and A3 the whole tree was clean, and parity was 20/20.
## Verification
Patch round 1, at HEAD `702a27775` (origin/main `a88a1bb39` merged at
`df0c0c846`): the 124 derived gates, `check-issue-citations --base
origin/main` and `check:scaffold-emission-policy` all exited 0 on the
first pass (`--ran`: 124 derived, 124 run, 0 NOT-MEASURED, 0 UNRUN),
including `check:doc-anchors`, `check:docs-audit-scope` and
`check-affected-docs`; `pnpm lint` exited 0; the parity pin 20/20, the
chain pin 4/4, and `create-objectstack` 16 files, 232 passed.
Round 0: all of the following ran at HEAD `d50d46fe0` (origin/main
`26daf0b03` merged).
- `pnpm --filter create-objectstack test`: 16 files, 232 passed.
`typecheck`: exit 0.
- `pnpm --filter @objectstack/cli typecheck`: exit 0, including
`check:test-typecheck`, whose ledger is unchanged.
- CLI `unit` project: 231 files, 3316 passed.
- CLI `integration`: this chain pin plus `generate-stack-reach.test.ts`,
2 files, 11 passed.
- `pnpm lint`: exit 0 over the whole repo, not narrowed.
- `node scripts/check-issue-citations.mjs --base origin/main`: exit 0.
- `node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack
--ran`: 124 derived, 124 run, 0 NOT-MEASURED, 0 UNRUN. Three gates first
exited 3 with PREREQUISITE NOT MET (`check:skill-examples`,
`check:dual-build-cjs-loads`, `check:i18n-coverage`) and exited 0 after
a full build.
- `pnpm check:scaffold-emission-policy`: exit 0.
## Docs this change made false, and a surface note
These published lines described an objects-only starter and are
corrected in place:
- the blank starter's `README.md` Layout, plus its app remedy, which now
says to export the file from `src/apps/index.ts`;
- the shipped `AGENTS.md` rule 3, which prescribed `Object.values()`
(measured TS2322 on the now-empty barrels);
- the package `README.md` tree;
- `content/docs/getting-started/your-first-project.mdx`: its section-2
tree and config block;
- `content/docs/getting-started/build-with-claude-code.mdx` (patch round
1): step 3 said the agent wires the action, view and app through
`actions:` / `views:` / `apps:` keys in `defineStack()`. It now says
each file is exported from its directory's barrel
(`src/actions/index.ts`, `src/views/index.ts`, `src/apps/index.ts`),
which the starter's config already hands to `defineStack()`, matching
the shipped `AGENTS.md` rule 3. A sweep of `content/docs/` found no
other sentence telling a starter author to add a collection key;
- `content/docs/deployment/cli.mdx`.
In `cli.mdx`, the `os generate` section's "Not wired" example named "the
`npm create objectstack` starter", and its first-app walkthrough ran `os
generate action approve`. On the wired starter that action is refused
with exit 1: "Action 'approve' references object 'my_app_approve' which
is not defined in objects". The walkthrough now runs `object customer`,
then `flow customer`, then `action customer`, measured `UI: 1 Actions`
and `Logic: 1 Flows`. Its fixture callout now names the extra action.
`content/docs/**` and `packages/create-objectstack/README.md` were
outside the claim's first file surface; the seat amended the claim in
place to name them. They are edited under the agent contract's rule that
a published line this change makes false is repaired in the same PR. PR
#20341 edits `cli.mdx` around lines 1619 to 1690, disjoint from these
hunks; PR #20258 edited lines 1 to 7 of `your-first-project.mdx` and
`build-with-claude-code.mdx`, has since landed, and merged into this
branch without conflict.
`skills/objectstack-platform/SKILL.md` line 192 says the template
declares `requires: ['automation']`. That is now stale, but `skills/**`
is a governed Tier H surface, so it is **not** edited here; the seat
files it for the skills lane once this PR lands.
## Acceptance notes
- Byte-identical barrels inherit the article slip in `init.ts`'s
`renderEmptyWiredBarrel` ("a action", "a app"). `init.ts` is read-only
here. Whoever next edits that renderer carries it, and the parity pin
will then require the starter to follow.
- The old walkthrough's `os generate flow onboarding` also bound its
flow to an undeclared object. That was not silent: `os dev` warned "the
flow will never fire". The new walkthrough binds to the object it
creates.
- Measured in patch round 1, on a scaffolded starter holding the Build
with Claude Code step-3 files: exporting each from its barrel, with the
config untouched, gives `os validate` exit 0 with `Data: 2 Objects 6
Fields` and `UI: 1 Apps 1 Views 1 Actions`, the page's step-4 counts.
Adding `actions:` / `views:` / `apps:` keys beside the wired ones
instead still validates (the later key wins), but the starter's `tsc
--noEmit` fails with 3 x TS1117, and a later `os g view customer` then
reports Not wired, while the barrel-wired project reports it reaches the
stack.
- The `requires` pair is PR #20329's shape. The standing family cards
for the rest of that seam are #20331 and #20332, both named on #20215.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01UYBdGBzWSrAMzpW8ah3GbP)_
---------
Co-authored-by: Claude <noreply@anthropic.com>
1 parent eee0974 commit c577e66
21 files changed
Lines changed: 510 additions & 33 deletions
File tree
- .changeset
- content/docs
- deployment
- getting-started
- packages
- cli
- test
- create-objectstack
- src
- templates
- blank
- src
- actions
- apps
- dashboards
- flows
- skills
- views
- scripts
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
33 | 33 | | |
34 | 34 | | |
35 | 35 | | |
36 | | - | |
37 | | - | |
| 36 | + | |
| 37 | + | |
38 | 38 | | |
39 | 39 | | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
40 | 45 | | |
41 | 46 | | |
42 | 47 | | |
| |||
739 | 744 | | |
740 | 745 | | |
741 | 746 | | |
742 | | - | |
743 | | - | |
| 747 | + | |
| 748 | + | |
744 | 749 | | |
745 | 750 | | |
746 | 751 | | |
| |||
1410 | 1415 | | |
1411 | 1416 | | |
1412 | 1417 | | |
1413 | | - | |
| 1418 | + | |
| 1419 | + | |
1414 | 1420 | | |
1415 | 1421 | | |
1416 | 1422 | | |
| |||
1421 | 1427 | | |
1422 | 1428 | | |
1423 | 1429 | | |
1424 | | - | |
1425 | | - | |
| 1430 | + | |
| 1431 | + | |
1426 | 1432 | | |
1427 | 1433 | | |
1428 | 1434 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
223 | 223 | | |
224 | 224 | | |
225 | 225 | | |
226 | | - | |
227 | | - | |
228 | | - | |
229 | | - | |
230 | | - | |
231 | | - | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
232 | 236 | | |
233 | 237 | | |
234 | 238 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
91 | 91 | | |
92 | 92 | | |
93 | 93 | | |
94 | | - | |
95 | | - | |
96 | | - | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
97 | 103 | | |
98 | 104 | | |
99 | 105 | | |
100 | 106 | | |
101 | 107 | | |
102 | | - | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
103 | 112 | | |
104 | 113 | | |
105 | 114 | | |
106 | 115 | | |
107 | 116 | | |
108 | 117 | | |
109 | | - | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
110 | 129 | | |
111 | 130 | | |
112 | 131 | | |
| |||
120 | 139 | | |
121 | 140 | | |
122 | 141 | | |
123 | | - | |
124 | | - | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
125 | 146 | | |
126 | 147 | | |
127 | 148 | | |
128 | 149 | | |
129 | 150 | | |
130 | | - | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
131 | 158 | | |
132 | 159 | | |
133 | 160 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
132 | 132 | | |
133 | 133 | | |
134 | 134 | | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
135 | 138 | | |
136 | 139 | | |
137 | 140 | | |
| |||
Lines changed: 164 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
0 commit comments