create-objectstack 17.0.0-rc.0 → 17.0.0-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +659 -0
- package/dist/templates/blank/package.json +0 -1
- package/package.json +5 -3
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,659 @@
|
|
|
1
|
+
# create-objectstack
|
|
2
|
+
|
|
3
|
+
## 17.0.0-rc.2
|
|
4
|
+
|
|
5
|
+
## 17.0.0-rc.1
|
|
6
|
+
|
|
7
|
+
### Patch Changes
|
|
8
|
+
|
|
9
|
+
- 2e836de: chore(packaging): CHANGELOG.md ships in every npm tarball (#4261)
|
|
10
|
+
|
|
11
|
+
The AGENTS.md post-task checklist requires breaking changesets to carry their
|
|
12
|
+
FROM → TO migration because "this text ships to consumers as `CHANGELOG.md`
|
|
13
|
+
inside the npm package and is what an upgrading agent greps after the tombstone
|
|
14
|
+
error." That delivery path was severed for 68 of the 69 publishable packages:
|
|
15
|
+
npm packs `package.json` / `README*` / `LICENSE*` unconditionally but — unlike
|
|
16
|
+
older npm versions — not `CHANGELOG.md`, and the canonical
|
|
17
|
+
`"files": ["dist", "README.md"]` whitelist never named it. Measured on npm
|
|
18
|
+
10.9.7: `npm pack --dry-run` on `@objectstack/types` shipped 3 files while its
|
|
19
|
+
70KB `CHANGELOG.md` stayed behind. Only `@objectstack/spec` listed it
|
|
20
|
+
explicitly.
|
|
21
|
+
|
|
22
|
+
The tombstone-error scenario is precisely the one where the repo is out of
|
|
23
|
+
reach — the upgrading agent has `node_modules` and nothing else — so the
|
|
24
|
+
migration text has to ride in the tarball. Every publishable package now
|
|
25
|
+
declares `CHANGELOG.md` in `files`, and the canonical whitelist is
|
|
26
|
+
`["dist", "README.md", "CHANGELOG.md"]`.
|
|
27
|
+
|
|
28
|
+
The other half is the gate: `check:published-files` gains a fifth invariant,
|
|
29
|
+
COMPLETE — a whitelist that fails to cover `CHANGELOG.md` fails the
|
|
30
|
+
always-required lint job, so the next package cannot silently sever the path
|
|
31
|
+
again. `@objectstack/spec`'s per-package EXTRA_ENTRIES exemption dissolves
|
|
32
|
+
into the canonical set.
|
|
33
|
+
|
|
34
|
+
Consumer-visible change: one more file per install (the package's changelog,
|
|
35
|
+
e.g. 70.8KB for `@objectstack/types`), and `grep -r "removed key"
|
|
36
|
+
node_modules/@objectstack/*/CHANGELOG.md` now finds the migration it was
|
|
37
|
+
promised.
|
|
38
|
+
|
|
39
|
+
- 7309c81: chore(cli,create-objectstack): scaffolds no longer name a driver (#4065)
|
|
40
|
+
|
|
41
|
+
`os init` and the `create-objectstack` blank template both listed
|
|
42
|
+
`@objectstack/driver-memory` in the generated `dependencies`. It was the only
|
|
43
|
+
driver named, which read as an endorsement — "this is the driver your app runs
|
|
44
|
+
on" — when it is in fact the **last-resort rung** of the dev step-down (native
|
|
45
|
+
`better-sqlite3` → WASM SQLite → mingo). A new project's first impression of the
|
|
46
|
+
data layer should not be the engine that enforces no primary keys, no
|
|
47
|
+
uniqueness, no `NOT NULL` and no column types.
|
|
48
|
+
|
|
49
|
+
It was also redundant: `@objectstack/runtime` already depends on `driver-sql`,
|
|
50
|
+
`driver-sqlite-wasm` and `driver-memory`, and every script in both scaffolds runs
|
|
51
|
+
through the CLI, which carries all four. Removing the line changes nothing a
|
|
52
|
+
generated project can do — `objectstack dev` still resolves SQLite by default,
|
|
53
|
+
and `OS_DATABASE_URL` still selects Postgres / MySQL / MongoDB.
|
|
54
|
+
|
|
55
|
+
Docs updated to match: the "packages you depend on" table in _Your first project_
|
|
56
|
+
no longer lists a driver row (it now says where drivers come from), and the
|
|
57
|
+
Memory Driver section of _Database Drivers_ documents the opt-in persistence
|
|
58
|
+
default, carries a migration callout for the old `'auto'` behaviour, and points
|
|
59
|
+
test authors at in-memory SQLite. That section also claimed "Data is lost when
|
|
60
|
+
the process exits", which was simply false while `'auto'` was the default — it
|
|
61
|
+
wrote a file into the working directory.
|
|
62
|
+
|
|
63
|
+
## 17.0.0-rc.0
|
|
64
|
+
|
|
65
|
+
### Major Changes
|
|
66
|
+
|
|
67
|
+
- e47b342: feat!: require Node.js 22 — promise the runtime we actually test (#3825)
|
|
68
|
+
|
|
69
|
+
Every published package declared `engines.node: ">=18.0.0"`. **Node 18 reached
|
|
70
|
+
end-of-life on 2025-04-30 and Node 20 on 2026-04-30**, so the compatibility
|
|
71
|
+
promise covered two runtimes nobody patches — and, after #3830 moved CI to Node
|
|
72
|
+
22, two runtimes nothing in this repo verifies.
|
|
73
|
+
|
|
74
|
+
That left the promise and the evidence with **no overlap at all**:
|
|
75
|
+
|
|
76
|
+
| | Node version |
|
|
77
|
+
| ----------------------------------------------------------------------------------------------- | ------------ |
|
|
78
|
+
| What CI validates every PR on | **22** |
|
|
79
|
+
| What `release.yml` publishes from | **22** |
|
|
80
|
+
| What every shipped Docker image runs (`docker/Dockerfile`, `blank` template, self-hosting docs) | **22** |
|
|
81
|
+
| What `engines.node` promised users | **>=18** |
|
|
82
|
+
|
|
83
|
+
`engines.node` is now `>=22.0.0` across all 50 manifests. This is the honest
|
|
84
|
+
floor: it is the only runtime the packages are built, tested and shipped on.
|
|
85
|
+
|
|
86
|
+
## Migration
|
|
87
|
+
|
|
88
|
+
**If you are on Node 22 or newer, nothing changes.** Node 24 (Active LTS since
|
|
89
|
+
2025-10-28) and Node 26 both satisfy the new range.
|
|
90
|
+
|
|
91
|
+
If you are on Node 18 or 20, upgrade to Node 22+. Both are past end-of-life and
|
|
92
|
+
receive no security patches:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
nvm install 22 && nvm use 22
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
npm and pnpm surface an unsatisfied `engines` as an **`EBADENGINE` warning**, not
|
|
99
|
+
a hard failure, so an existing install will not break the moment you upgrade —
|
|
100
|
+
but the package is no longer tested on that runtime, and the failures are the
|
|
101
|
+
kind that do not announce themselves. #3812 is the worked example: a native
|
|
102
|
+
dependency whose `engines` required a newer Node loaded anyway on the older one
|
|
103
|
+
and then killed the test worker at the process level, with no JS error and a
|
|
104
|
+
summary that still said "passed".
|
|
105
|
+
|
|
106
|
+
If your CI pins Node, pin it to 22 as well — running your gates on a runtime
|
|
107
|
+
your dependencies no longer support is exactly the split this change closes.
|
|
108
|
+
|
|
109
|
+
## Also updated
|
|
110
|
+
|
|
111
|
+
The "Node 18+" prerequisite was restated in ten user-facing places
|
|
112
|
+
(`README.md`, `CONTRIBUTING.md`, the getting-started and deployment docs, the
|
|
113
|
+
todo example, and the `objectstack-platform` skill's `compatibility` field).
|
|
114
|
+
All now say 22. Changelogs and ADRs are historical records and were left alone.
|
|
115
|
+
|
|
116
|
+
### Patch Changes
|
|
117
|
+
|
|
118
|
+
- 9f060e5: chore(deps)!: better-auth 1.7.0-rc.2 (account identity restructuring) + the
|
|
119
|
+
production-dependency batch from #3517
|
|
120
|
+
|
|
121
|
+
**better-auth 1.7.0-rc.1 → 1.7.0-rc.2** across the family (`better-auth`,
|
|
122
|
+
`@better-auth/core`, `@better-auth/oauth-provider`, `@better-auth/sso`, and the
|
|
123
|
+
adapter/telemetry overrides). `@better-auth/scim` deliberately stays on
|
|
124
|
+
1.7.0-rc.1 — rc.2 replaces its whole model (code-defined connections; the
|
|
125
|
+
`scimProvider` model and the generate-token endpoint are gone), which is a
|
|
126
|
+
feature migration, not a version bump. Its peer range accepts rc.2 core, and the
|
|
127
|
+
advisory that forced the original pin (GHSA-j8v8-g9cx-5qf4) is still fixed.
|
|
128
|
+
|
|
129
|
+
**BREAKING — account identity.** better-auth renamed `account.accountId` to
|
|
130
|
+
`account.providerAccountId` and added a REQUIRED `account.issuer`; sign-in now
|
|
131
|
+
resolves accounts by `(issuer, providerAccountId)`.
|
|
132
|
+
|
|
133
|
+
- FROM `fields: { accountId: 'account_id' }` → TO
|
|
134
|
+
`fields: { issuer: 'issuer', providerAccountId: 'account_id' }`. The provider
|
|
135
|
+
account id keeps its `account_id` column — only the better-auth-side name
|
|
136
|
+
moved — and `sys_account` gains an `issuer` column.
|
|
137
|
+
- FROM `internalAdapter.createAccount({ providerId, accountId, … })` → TO
|
|
138
|
+
`createAccount({ providerId, issuer, providerAccountId, … })`. A local
|
|
139
|
+
password account carries the issuer better-auth mints for itself,
|
|
140
|
+
`local:credential`.
|
|
141
|
+
- FROM `client.auth.accounts.unlink({ providerId, accountId })` → TO
|
|
142
|
+
`unlink({ accountId })`, where `accountId` is now the account ROW id (the `id`
|
|
143
|
+
from `accounts.list()`), matching better-auth's narrowed body.
|
|
144
|
+
`accounts.list()` returns `issuer` + `providerAccountId` in place of
|
|
145
|
+
`accountId`.
|
|
146
|
+
|
|
147
|
+
**Existing deployments:** rows written before 1.7 have no issuer and are
|
|
148
|
+
invisible to sign-in until stamped. The auth plugin now runs an idempotent
|
|
149
|
+
boot-time backfill that stamps what it can derive — `local:credential` for
|
|
150
|
+
password accounts, `local:oauth:<providerId>` for configured social providers,
|
|
151
|
+
and the registered IdP's real `iss` from `sys_sso_provider` for federated ones.
|
|
152
|
+
Accounts from a federated IdP that is no longer registered cannot be derived;
|
|
153
|
+
they are logged with their provider id and row count rather than guessed, and
|
|
154
|
+
those users cannot sign in through that provider until the row is stamped with
|
|
155
|
+
the IdP's issuer or removed so a fresh login re-links it.
|
|
156
|
+
|
|
157
|
+
**Also required by 1.7:** `SecondaryStorage` gained two mandatory methods, both
|
|
158
|
+
now implemented over the kernel cache service — `getAndDelete` (single-use
|
|
159
|
+
verification values) and `increment` (fixed-window rate-limit counter;
|
|
160
|
+
`rateLimit.storage: 'secondary-storage'` throws at boot without it).
|
|
161
|
+
|
|
162
|
+
The rest of #3517's production-dependency batch rides along: `@oclif/core`
|
|
163
|
+
4.13.0, `@hono/node-server` 2.0.12, `hono` 4.12.32, `tar` 7.5.22, `jose` 6.2.4,
|
|
164
|
+
`pinyin-pro` 3.28.2, plus the private docs app's fumadocs/next/react bumps.
|
|
165
|
+
|
|
166
|
+
- 4e9e184: chore(deps): OSV security batch — bump tar to ^7.5.21 (GHSA-r292-9mhp-454m) and
|
|
167
|
+
js-yaml to ^5.2.2 (GHSA-pm4m-ph32-ghv5)
|
|
168
|
+
|
|
169
|
+
Both are declared-range bumps to the patched releases, so downstream installs
|
|
170
|
+
resolve the fixed versions from the published manifests, not just this
|
|
171
|
+
workspace's lockfile. The same batch clears the remaining transitive advisories
|
|
172
|
+
(next 16.2.11 in apps/docs; workspace overrides for brace-expansion, sharp,
|
|
173
|
+
react-router, @sveltejs/kit, @hono/node-server) — those live in pnpm-workspace.yaml
|
|
174
|
+
and the private docs app, which do not ship.
|
|
175
|
+
|
|
176
|
+
## 16.1.0
|
|
177
|
+
|
|
178
|
+
## 16.0.0
|
|
179
|
+
|
|
180
|
+
### Minor Changes
|
|
181
|
+
|
|
182
|
+
- 3f218e4: feat(create-objectstack): the blank scaffold ships the three generic connector executors by default
|
|
183
|
+
|
|
184
|
+
`npm create objectstack` now generates an `objectstack.config.ts` that wires the
|
|
185
|
+
`rest`, `openapi`, and `mcp` connector executor plugins (ADR-0022/0023/0024 +
|
|
186
|
+
ADR-0097) into `plugins:`, alongside `requires: ['automation']`. This closes the
|
|
187
|
+
last authoring gap in the ADR-0097 promise that integrations are expressible
|
|
188
|
+
**and executable** as pure metadata: an author (human or AI) can now add a
|
|
189
|
+
declarative `connectors:` entry naming `provider: 'rest' | 'openapi' | 'mcp'`
|
|
190
|
+
and have it materialize into a live, dispatchable connector at boot — with no
|
|
191
|
+
host-code edit.
|
|
192
|
+
|
|
193
|
+
- `plugins:` — `new ConnectorRestPlugin()`, `new ConnectorOpenApiPlugin()`,
|
|
194
|
+
`new ConnectorMcpPlugin()` (zero-arg = contribute the provider factory only).
|
|
195
|
+
- `requires: ['automation']` — the automation service performs the
|
|
196
|
+
materialization and owns the registry the executors register into. It is also
|
|
197
|
+
a hard dependency of the connector plugins, so a scaffold that lists them in
|
|
198
|
+
`plugins:` without it fails boot; automation ships transitively via
|
|
199
|
+
`@objectstack/cli`.
|
|
200
|
+
- deps — `@objectstack/connector-rest`, `@objectstack/connector-openapi`,
|
|
201
|
+
`@objectstack/connector-mcp`.
|
|
202
|
+
- Security (#3055): declarative `mcp` stdio transports stay denied by default —
|
|
203
|
+
opt in per host with `new ConnectorMcpPlugin({ declarativeStdio: ['node'] })`.
|
|
204
|
+
|
|
205
|
+
Brand connectors (Slack, …) remain marketplace/opt-in.
|
|
206
|
+
|
|
207
|
+
### Patch Changes
|
|
208
|
+
|
|
209
|
+
- 83e8f7d: feat(mcp): decouple the stdio auto-start switch from the HTTP surface + surface the MCP endpoint on `os dev` boot (#3167)
|
|
210
|
+
|
|
211
|
+
The MCP HTTP surface (`/api/v1/mcp`) and the long-lived stdio transport used to
|
|
212
|
+
share one env var: `OS_MCP_SERVER_ENABLED=true` turned the HTTP surface on **and**
|
|
213
|
+
silently auto-started the stdio transport — which bridges the raw metadata service
|
|
214
|
+
|
|
215
|
+
- data engine with no per-request principal (unscoped). An operator setting it to
|
|
216
|
+
"make sure MCP is on" got an unscoped transport as a side effect.
|
|
217
|
+
|
|
218
|
+
* **`@objectstack/types`** — new `resolveMcpStdioAutoStart()`. Stdio auto-start is
|
|
219
|
+
now its own switch, `OS_MCP_STDIO_ENABLED` (default off); `OS_MCP_SERVER_ENABLED`
|
|
220
|
+
governs only the HTTP surface. The legacy `OS_MCP_SERVER_ENABLED=true` trigger
|
|
221
|
+
still starts stdio for one release, flagged as deprecated. `=false` is unchanged
|
|
222
|
+
(it only ever gated HTTP).
|
|
223
|
+
* **`@objectstack/mcp`** — `MCPServerPlugin.start()` gates stdio on the new switch
|
|
224
|
+
and logs a one-time deprecation warning when started via the legacy alias.
|
|
225
|
+
* **`@objectstack/cli`** — `os dev` now prints the MCP endpoint, the agent-skill
|
|
226
|
+
URL, and a ready-to-paste `claude mcp add` command on boot (gated on the HTTP
|
|
227
|
+
surface being on), so the "an agent operates the app it's building" loop is
|
|
228
|
+
discoverable at dev time.
|
|
229
|
+
* **`create-objectstack`** — the blank scaffold README documents that the app is
|
|
230
|
+
itself an MCP server (the serve side), distinct from the consume-side connector.
|
|
231
|
+
|
|
232
|
+
- 3b6ef8a: Scaffolded projects ship with a `.gitignore` again — `npx create-objectstack` produced none, leaving `node_modules/` and `.env` un-ignored for every new user.
|
|
233
|
+
|
|
234
|
+
`npm pack` / `pnpm pack` strip `.gitignore` from a tarball unconditionally, at every depth. The blank template committed one at `src/templates/blank/.gitignore` and the build faithfully copied it to `dist/templates/blank/.gitignore`, but `files: ["dist"]` publishing dropped it on the way to the registry — so the file was present in the repo, present in every local build, and absent from all 11 files of a real scaffold. Verified against the published 15.1.1 tarball, which ships `dist/templates/blank/.dockerignore` and no `.gitignore`.
|
|
235
|
+
|
|
236
|
+
The template is now committed as `_gitignore` (a name npm does not strip) and restored to `.gitignore` when the template is copied, via a `TEMPLATE_FILE_ALIASES` map in the new `template-copy.ts`. Only `.gitignore` is aliased: the strip list is `.gitignore` and `.npmrc`, not "every dotfile" — `.dockerignore` packs fine and stays literal.
|
|
237
|
+
|
|
238
|
+
The restored ignore rules also cover `.env` / `.env.*`, which they never did. The template README has users write `OS_AUTH_SECRET` and `OS_SECRET_KEY` into a `.env`, and `docker-compose.yml` calls that file "never committed" — but only the prose said so, and `.dockerignore` was the only file that listed it.
|
|
239
|
+
|
|
240
|
+
A packing ratchet in `template-consistency.test.ts` guards both halves: it packs the real package, scaffolds from the extracted tarball with the real copy logic, and asserts every template file lands under its intended name. Source-level assertions cannot see this class of bug — the file only vanishes at publish.
|
|
241
|
+
|
|
242
|
+
- 3a8ce9d: fix(create-objectstack): the blank scaffold declares pnpm build approvals, so a fresh `pnpm install` no longer exits 1 on pnpm 11
|
|
243
|
+
|
|
244
|
+
pnpm 11 turned an unapproved dependency build script from a warning into a hard
|
|
245
|
+
error. The blank template declared no build approvals, so the very first command
|
|
246
|
+
a new user runs failed on any current pnpm:
|
|
247
|
+
|
|
248
|
+
```
|
|
249
|
+
npx create-objectstack myapp && cd myapp && pnpm install
|
|
250
|
+
# [ERR_PNPM_IGNORED_BUILDS] Ignored build scripts: better-sqlite3@12.11.1, esbuild@0.28.1
|
|
251
|
+
# exit 1
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
The scaffold now ships a `pnpm-workspace.yaml` approving the two packages it
|
|
255
|
+
actually depends on building — `better-sqlite3` (the native sqlite driver behind
|
|
256
|
+
`@objectstack/driver-sql`) and `esbuild` (compiles `objectstack.config.ts`).
|
|
257
|
+
|
|
258
|
+
Both approval keys are present because pnpm reads them by version, and neither
|
|
259
|
+
alone covers the supported range:
|
|
260
|
+
|
|
261
|
+
- `allowBuilds` (a package → boolean map) — the only key pnpm 11 honors, and
|
|
262
|
+
understood back to pnpm 10.31. `onlyBuiltDependencies` alone still errors.
|
|
263
|
+
- `onlyBuiltDependencies` (a list) — pnpm 10.0–10.30, which ignore `allowBuilds`.
|
|
264
|
+
|
|
265
|
+
npm and yarn ignore the file, so the npm install path is unaffected. Both
|
|
266
|
+
packages ship prebuilt binaries, so this was an install-time hard stop rather
|
|
267
|
+
than a runtime defect — the project ran fine once installed.
|
|
268
|
+
|
|
269
|
+
This is the #3091 failure class (in-repo settings masking what users resolve)
|
|
270
|
+
and was caught by the publish smoke gate added in #3100, which installs the
|
|
271
|
+
release candidate the way a user does — on whatever pnpm corepack hands a fresh
|
|
272
|
+
machine.
|
|
273
|
+
|
|
274
|
+
- 809214f: Stop leaking repo-internal skills into scaffolded projects. The scaffolder (and the docs) advertised `npx skills add objectstack-ai/objectstack --all`, and the skills CLI's `--all` implies `--skill '*'` — which includes even `metadata.internal` skills — so repo-internal tooling like `.claude/skills/dogfood-verification` landed in every new project's `.agents/skills/`. All install commands are now scoped to the published catalog via the `/skills` subpath (`npx skills add objectstack-ai/objectstack/skills --all`), the internal skill is additionally marked `metadata.internal: true` to hide it from interactive discovery, and a template-consistency ratchet plus a scaffold-e2e assertion keep the boundary from regressing.
|
|
275
|
+
|
|
276
|
+
## 16.0.0-rc.1
|
|
277
|
+
|
|
278
|
+
## 16.0.0-rc.0
|
|
279
|
+
|
|
280
|
+
### Minor Changes
|
|
281
|
+
|
|
282
|
+
- 3f218e4: feat(create-objectstack): the blank scaffold ships the three generic connector executors by default
|
|
283
|
+
|
|
284
|
+
`npm create objectstack` now generates an `objectstack.config.ts` that wires the
|
|
285
|
+
`rest`, `openapi`, and `mcp` connector executor plugins (ADR-0022/0023/0024 +
|
|
286
|
+
ADR-0097) into `plugins:`, alongside `requires: ['automation']`. This closes the
|
|
287
|
+
last authoring gap in the ADR-0097 promise that integrations are expressible
|
|
288
|
+
**and executable** as pure metadata: an author (human or AI) can now add a
|
|
289
|
+
declarative `connectors:` entry naming `provider: 'rest' | 'openapi' | 'mcp'`
|
|
290
|
+
and have it materialize into a live, dispatchable connector at boot — with no
|
|
291
|
+
host-code edit.
|
|
292
|
+
|
|
293
|
+
- `plugins:` — `new ConnectorRestPlugin()`, `new ConnectorOpenApiPlugin()`,
|
|
294
|
+
`new ConnectorMcpPlugin()` (zero-arg = contribute the provider factory only).
|
|
295
|
+
- `requires: ['automation']` — the automation service performs the
|
|
296
|
+
materialization and owns the registry the executors register into. It is also
|
|
297
|
+
a hard dependency of the connector plugins, so a scaffold that lists them in
|
|
298
|
+
`plugins:` without it fails boot; automation ships transitively via
|
|
299
|
+
`@objectstack/cli`.
|
|
300
|
+
- deps — `@objectstack/connector-rest`, `@objectstack/connector-openapi`,
|
|
301
|
+
`@objectstack/connector-mcp`.
|
|
302
|
+
- Security (#3055): declarative `mcp` stdio transports stay denied by default —
|
|
303
|
+
opt in per host with `new ConnectorMcpPlugin({ declarativeStdio: ['node'] })`.
|
|
304
|
+
|
|
305
|
+
Brand connectors (Slack, …) remain marketplace/opt-in.
|
|
306
|
+
|
|
307
|
+
### Patch Changes
|
|
308
|
+
|
|
309
|
+
- 83e8f7d: feat(mcp): decouple the stdio auto-start switch from the HTTP surface + surface the MCP endpoint on `os dev` boot (#3167)
|
|
310
|
+
|
|
311
|
+
The MCP HTTP surface (`/api/v1/mcp`) and the long-lived stdio transport used to
|
|
312
|
+
share one env var: `OS_MCP_SERVER_ENABLED=true` turned the HTTP surface on **and**
|
|
313
|
+
silently auto-started the stdio transport — which bridges the raw metadata service
|
|
314
|
+
|
|
315
|
+
- data engine with no per-request principal (unscoped). An operator setting it to
|
|
316
|
+
"make sure MCP is on" got an unscoped transport as a side effect.
|
|
317
|
+
|
|
318
|
+
* **`@objectstack/types`** — new `resolveMcpStdioAutoStart()`. Stdio auto-start is
|
|
319
|
+
now its own switch, `OS_MCP_STDIO_ENABLED` (default off); `OS_MCP_SERVER_ENABLED`
|
|
320
|
+
governs only the HTTP surface. The legacy `OS_MCP_SERVER_ENABLED=true` trigger
|
|
321
|
+
still starts stdio for one release, flagged as deprecated. `=false` is unchanged
|
|
322
|
+
(it only ever gated HTTP).
|
|
323
|
+
* **`@objectstack/mcp`** — `MCPServerPlugin.start()` gates stdio on the new switch
|
|
324
|
+
and logs a one-time deprecation warning when started via the legacy alias.
|
|
325
|
+
* **`@objectstack/cli`** — `os dev` now prints the MCP endpoint, the agent-skill
|
|
326
|
+
URL, and a ready-to-paste `claude mcp add` command on boot (gated on the HTTP
|
|
327
|
+
surface being on), so the "an agent operates the app it's building" loop is
|
|
328
|
+
discoverable at dev time.
|
|
329
|
+
* **`create-objectstack`** — the blank scaffold README documents that the app is
|
|
330
|
+
itself an MCP server (the serve side), distinct from the consume-side connector.
|
|
331
|
+
|
|
332
|
+
- 3b6ef8a: Scaffolded projects ship with a `.gitignore` again — `npx create-objectstack` produced none, leaving `node_modules/` and `.env` un-ignored for every new user.
|
|
333
|
+
|
|
334
|
+
`npm pack` / `pnpm pack` strip `.gitignore` from a tarball unconditionally, at every depth. The blank template committed one at `src/templates/blank/.gitignore` and the build faithfully copied it to `dist/templates/blank/.gitignore`, but `files: ["dist"]` publishing dropped it on the way to the registry — so the file was present in the repo, present in every local build, and absent from all 11 files of a real scaffold. Verified against the published 15.1.1 tarball, which ships `dist/templates/blank/.dockerignore` and no `.gitignore`.
|
|
335
|
+
|
|
336
|
+
The template is now committed as `_gitignore` (a name npm does not strip) and restored to `.gitignore` when the template is copied, via a `TEMPLATE_FILE_ALIASES` map in the new `template-copy.ts`. Only `.gitignore` is aliased: the strip list is `.gitignore` and `.npmrc`, not "every dotfile" — `.dockerignore` packs fine and stays literal.
|
|
337
|
+
|
|
338
|
+
The restored ignore rules also cover `.env` / `.env.*`, which they never did. The template README has users write `OS_AUTH_SECRET` and `OS_SECRET_KEY` into a `.env`, and `docker-compose.yml` calls that file "never committed" — but only the prose said so, and `.dockerignore` was the only file that listed it.
|
|
339
|
+
|
|
340
|
+
A packing ratchet in `template-consistency.test.ts` guards both halves: it packs the real package, scaffolds from the extracted tarball with the real copy logic, and asserts every template file lands under its intended name. Source-level assertions cannot see this class of bug — the file only vanishes at publish.
|
|
341
|
+
|
|
342
|
+
- 3a8ce9d: fix(create-objectstack): the blank scaffold declares pnpm build approvals, so a fresh `pnpm install` no longer exits 1 on pnpm 11
|
|
343
|
+
|
|
344
|
+
pnpm 11 turned an unapproved dependency build script from a warning into a hard
|
|
345
|
+
error. The blank template declared no build approvals, so the very first command
|
|
346
|
+
a new user runs failed on any current pnpm:
|
|
347
|
+
|
|
348
|
+
```
|
|
349
|
+
npx create-objectstack myapp && cd myapp && pnpm install
|
|
350
|
+
# [ERR_PNPM_IGNORED_BUILDS] Ignored build scripts: better-sqlite3@12.11.1, esbuild@0.28.1
|
|
351
|
+
# exit 1
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
The scaffold now ships a `pnpm-workspace.yaml` approving the two packages it
|
|
355
|
+
actually depends on building — `better-sqlite3` (the native sqlite driver behind
|
|
356
|
+
`@objectstack/driver-sql`) and `esbuild` (compiles `objectstack.config.ts`).
|
|
357
|
+
|
|
358
|
+
Both approval keys are present because pnpm reads them by version, and neither
|
|
359
|
+
alone covers the supported range:
|
|
360
|
+
|
|
361
|
+
- `allowBuilds` (a package → boolean map) — the only key pnpm 11 honors, and
|
|
362
|
+
understood back to pnpm 10.31. `onlyBuiltDependencies` alone still errors.
|
|
363
|
+
- `onlyBuiltDependencies` (a list) — pnpm 10.0–10.30, which ignore `allowBuilds`.
|
|
364
|
+
|
|
365
|
+
npm and yarn ignore the file, so the npm install path is unaffected. Both
|
|
366
|
+
packages ship prebuilt binaries, so this was an install-time hard stop rather
|
|
367
|
+
than a runtime defect — the project ran fine once installed.
|
|
368
|
+
|
|
369
|
+
This is the #3091 failure class (in-repo settings masking what users resolve)
|
|
370
|
+
and was caught by the publish smoke gate added in #3100, which installs the
|
|
371
|
+
release candidate the way a user does — on whatever pnpm corepack hands a fresh
|
|
372
|
+
machine.
|
|
373
|
+
|
|
374
|
+
- 809214f: Stop leaking repo-internal skills into scaffolded projects. The scaffolder (and the docs) advertised `npx skills add objectstack-ai/objectstack --all`, and the skills CLI's `--all` implies `--skill '*'` — which includes even `metadata.internal` skills — so repo-internal tooling like `.claude/skills/dogfood-verification` landed in every new project's `.agents/skills/`. All install commands are now scoped to the published catalog via the `/skills` subpath (`npx skills add objectstack-ai/objectstack/skills --all`), the internal skill is additionally marked `metadata.internal: true` to hide it from interactive discovery, and a template-consistency ratchet plus a scaffold-e2e assertion keep the boundary from regressing.
|
|
375
|
+
|
|
376
|
+
## 15.1.1
|
|
377
|
+
|
|
378
|
+
## 15.1.0
|
|
379
|
+
|
|
380
|
+
### Minor Changes
|
|
381
|
+
|
|
382
|
+
- f531a26: feat(protocol): complete ADR-0087 — load-seam handshake, chain backfill 12–15, release artifacts (#2643)
|
|
383
|
+
|
|
384
|
+
Closes the remaining ADR-0087 gaps (see the ADR's as-built Addendum):
|
|
385
|
+
|
|
386
|
+
- **P0 load seams (D1).** The protocol handshake now runs on the boot-time
|
|
387
|
+
durable-package rehydration path (`@objectstack/service-package` refuses an
|
|
388
|
+
incompatible `sys_packages` row with the structured `OS_PROTOCOL_INCOMPATIBLE`
|
|
389
|
+
diagnostic and keeps booting) and on `AppPlugin` for code-defined stacks
|
|
390
|
+
(fail-fast before the manifest is decomposed). `objectstack lint` gains
|
|
391
|
+
`protocol/missing-engines-range` (warning + fix-it) and the
|
|
392
|
+
`create-objectstack` blank template stamps `engines: { protocol: '^<major>' }`
|
|
393
|
+
(re-stamped at version time by `scripts/sync-template-versions.mjs`) — the
|
|
394
|
+
two ends of the grandfathering ratchet.
|
|
395
|
+
- **Chain backfill (D2/D3).** `MetadataConversion.retiredFromLoadPath`
|
|
396
|
+
implements the load-window's second half (retired entries replay only via
|
|
397
|
+
`migrate meta` / fixture CI). Steps 12–15 land: the `api.requireAuth` flip
|
|
398
|
+
(semantic), the ADR-0090 wave (3 retired conversions + 5 semantic TODOs), the
|
|
399
|
+
`BookAudience` rename (retired conversion), and the ADR-0089 visibility
|
|
400
|
+
unification (`visibleOn`/`visibility` → `visibleWhen` as LIVE load-window
|
|
401
|
+
conversions) + the `.strict()` flip (semantic). The protocol-11
|
|
402
|
+
`compactLayout` → `highlightFields` rename is backfilled as a retired step-11
|
|
403
|
+
conversion. `migrate meta --from 10` now reaches protocol 15.
|
|
404
|
+
- **Release artifacts (D4).** `spec-changes.json` is generated from the
|
|
405
|
+
registries (`gen:spec-changes`, CI drift-checked), ships in the npm artifact
|
|
406
|
+
together with `api-surface.json`, and is attached to each `@objectstack/spec`
|
|
407
|
+
GitHub Release with `added[]`/`removed[]` filled from the api-surface diff
|
|
408
|
+
against the previously published release. The upgrade guide
|
|
409
|
+
(`docs/protocol-upgrade-guide.md`) is generated from the same registries and
|
|
410
|
+
CI drift-checked — a projection that cannot drift.
|
|
411
|
+
|
|
412
|
+
- f531a26: Scaffolded projects are now container-ready out of the box: the `blank` template ships a `Dockerfile` (two-stage build onto the official `ghcr.io/objectstack-ai/objectstack` runtime image), a `docker-compose.yml` (app + Postgres single-host stack), and a `.dockerignore`, plus a Deploy section in the project README. `docker build -t my-app .` works immediately after `npm create objectstack`.
|
|
413
|
+
|
|
414
|
+
## 15.0.0
|
|
415
|
+
|
|
416
|
+
## 14.8.0
|
|
417
|
+
|
|
418
|
+
### Patch Changes
|
|
419
|
+
|
|
420
|
+
- eaff014: Scaffolded projects now install the current framework release instead of a stale major. The bundled `blank` template had `^6.0.0` ranges frozen in while the registry was publishing 14.x, so `npm create objectstack` produced a project eight majors behind the docs — and the template's code no longer compiled against 14.x anyway (`Field.longText` removed, `api.rest` no longer a `defineStack` key, `sharingModel` now required by the ADR-0090 security gate). The template is updated to the current API, and the scaffolder now rewrites every `@objectstack/*` range in the generated `package.json` to `^<its own version>` (all packages version in lockstep), so generated projects track the release even if the committed template drifts again. A consistency test ratchets the template's major and the README's template table against the registry. The template README also documents the seeded dev-admin sign-in that data-API curls need.
|
|
421
|
+
|
|
422
|
+
## 14.7.0
|
|
423
|
+
|
|
424
|
+
## 14.6.0
|
|
425
|
+
|
|
426
|
+
## 14.5.0
|
|
427
|
+
|
|
428
|
+
## 14.4.0
|
|
429
|
+
|
|
430
|
+
## 14.3.0
|
|
431
|
+
|
|
432
|
+
## 14.2.0
|
|
433
|
+
|
|
434
|
+
## 14.1.0
|
|
435
|
+
|
|
436
|
+
## 14.0.0
|
|
437
|
+
|
|
438
|
+
## 13.0.0
|
|
439
|
+
|
|
440
|
+
## 12.6.0
|
|
441
|
+
|
|
442
|
+
## 12.5.0
|
|
443
|
+
|
|
444
|
+
## 12.4.0
|
|
445
|
+
|
|
446
|
+
## 12.3.0
|
|
447
|
+
|
|
448
|
+
## 12.2.0
|
|
449
|
+
|
|
450
|
+
## 12.1.0
|
|
451
|
+
|
|
452
|
+
## 12.0.0
|
|
453
|
+
|
|
454
|
+
## 11.10.0
|
|
455
|
+
|
|
456
|
+
## 11.9.0
|
|
457
|
+
|
|
458
|
+
## 11.8.0
|
|
459
|
+
|
|
460
|
+
## 11.7.0
|
|
461
|
+
|
|
462
|
+
## 11.6.0
|
|
463
|
+
|
|
464
|
+
## 11.5.0
|
|
465
|
+
|
|
466
|
+
## 11.4.0
|
|
467
|
+
|
|
468
|
+
## 11.3.0
|
|
469
|
+
|
|
470
|
+
## 11.2.0
|
|
471
|
+
|
|
472
|
+
## 11.1.0
|
|
473
|
+
|
|
474
|
+
## 11.0.0
|
|
475
|
+
|
|
476
|
+
## 10.3.0
|
|
477
|
+
|
|
478
|
+
## 10.2.0
|
|
479
|
+
|
|
480
|
+
## 10.1.0
|
|
481
|
+
|
|
482
|
+
### Minor Changes
|
|
483
|
+
|
|
484
|
+
- 7cf283a: Make `os validate` the author-time verification gate and steer scaffolds toward it.
|
|
485
|
+
|
|
486
|
+
- **`os validate`** now runs the same CEL/predicate gate as `os build`/`os compile`
|
|
487
|
+
(ADR-0032): every `visible`/`disabled`/`requiredWhen`/validation/flow/sharing
|
|
488
|
+
predicate is checked for CEL syntax and `record.<field>` existence on the target
|
|
489
|
+
object. It already ran the protocol schema and widget-binding checks; the
|
|
490
|
+
expression gate closes the gap so a bare field ref (`done` instead of
|
|
491
|
+
`record.done`) — which silently hides an action on every record at runtime
|
|
492
|
+
(#2183/#2185) — fails validation instead of shipping. `os validate` is now a
|
|
493
|
+
read-only superset of the build's checks (no artifact emitted).
|
|
494
|
+
- **`create-objectstack`** now emits an `AGENTS.md` (and `.github/copilot-instructions.md`)
|
|
495
|
+
into every generated project instructing coding agents to run `npm run validate`
|
|
496
|
+
after editing metadata, aligns the blank template's `dev`/`start` scripts with the
|
|
497
|
+
example apps (`objectstack dev`/`objectstack start`), and sharpens the post-create
|
|
498
|
+
"Next steps" output.
|
|
499
|
+
|
|
500
|
+
## 10.0.0
|
|
501
|
+
|
|
502
|
+
## 9.11.0
|
|
503
|
+
|
|
504
|
+
## 9.10.0
|
|
505
|
+
|
|
506
|
+
## 9.9.1
|
|
507
|
+
|
|
508
|
+
## 9.9.0
|
|
509
|
+
|
|
510
|
+
## 9.8.0
|
|
511
|
+
|
|
512
|
+
## 9.7.0
|
|
513
|
+
|
|
514
|
+
## 9.6.0
|
|
515
|
+
|
|
516
|
+
## 9.5.1
|
|
517
|
+
|
|
518
|
+
## 9.5.0
|
|
519
|
+
|
|
520
|
+
## 9.4.0
|
|
521
|
+
|
|
522
|
+
## 9.3.0
|
|
523
|
+
|
|
524
|
+
## 9.2.0
|
|
525
|
+
|
|
526
|
+
## 9.1.0
|
|
527
|
+
|
|
528
|
+
## 9.0.1
|
|
529
|
+
|
|
530
|
+
## 9.0.0
|
|
531
|
+
|
|
532
|
+
## 8.0.1
|
|
533
|
+
|
|
534
|
+
## 8.0.0
|
|
535
|
+
|
|
536
|
+
## 7.9.0
|
|
537
|
+
|
|
538
|
+
## 7.8.0
|
|
539
|
+
|
|
540
|
+
## 7.7.0
|
|
541
|
+
|
|
542
|
+
## 7.6.0
|
|
543
|
+
|
|
544
|
+
## 7.5.0
|
|
545
|
+
|
|
546
|
+
## 7.4.1
|
|
547
|
+
|
|
548
|
+
## 7.4.0
|
|
549
|
+
|
|
550
|
+
## 7.3.0
|
|
551
|
+
|
|
552
|
+
## 7.2.1
|
|
553
|
+
|
|
554
|
+
## 7.2.0
|
|
555
|
+
|
|
556
|
+
## 7.1.0
|
|
557
|
+
|
|
558
|
+
## 7.0.0
|
|
559
|
+
|
|
560
|
+
## 6.9.0
|
|
561
|
+
|
|
562
|
+
## 6.8.1
|
|
563
|
+
|
|
564
|
+
## 6.8.0
|
|
565
|
+
|
|
566
|
+
## 6.7.1
|
|
567
|
+
|
|
568
|
+
## 6.7.0
|
|
569
|
+
|
|
570
|
+
## 6.6.0
|
|
571
|
+
|
|
572
|
+
## 6.5.1
|
|
573
|
+
|
|
574
|
+
## 6.5.0
|
|
575
|
+
|
|
576
|
+
## 6.4.0
|
|
577
|
+
|
|
578
|
+
### Patch Changes
|
|
579
|
+
|
|
580
|
+
- 15fc484: Upgrade `@object-ui/*` packages to **v6.0**.
|
|
581
|
+
|
|
582
|
+
- `@objectstack/cli`: `@object-ui/console` and `@object-ui/studio` from `^5.4.2` → `^6.0.0` — bundled Studio + Console assets now ship the v6 UI shell (new design language, refreshed sidebar, redesigned record header).
|
|
583
|
+
- `@objectstack/account`: `@object-ui/i18n` from `^5.4.2` → `^6.0.0` — i18n runtime now matches the v6 console/studio API.
|
|
584
|
+
- Root devDependency `@object-ui/console` from `^5.4.2` → `^6.0.0` so workspace scripts and the docs build pick up v6.
|
|
585
|
+
- `create-objectstack`: `tar` from `^7.4.3` → `^7.5.15` (security + perf fixes when unpacking remote templates).
|
|
586
|
+
|
|
587
|
+
**Heads-up for consumers:** `@object-ui/*` v6 is a major release of the bundled UI; pages rendered through the CLI's `studio` / `console` mounts may look different from v5. The protocol surface is unchanged.
|
|
588
|
+
|
|
589
|
+
## 6.3.0
|
|
590
|
+
|
|
591
|
+
## 6.2.0
|
|
592
|
+
|
|
593
|
+
## 6.1.1
|
|
594
|
+
|
|
595
|
+
## 6.1.0
|
|
596
|
+
|
|
597
|
+
## 6.0.0
|
|
598
|
+
|
|
599
|
+
## 5.2.0
|
|
600
|
+
|
|
601
|
+
## 5.1.0
|
|
602
|
+
|
|
603
|
+
## 5.0.0
|
|
604
|
+
|
|
605
|
+
## 4.2.0
|
|
606
|
+
|
|
607
|
+
## 4.1.1
|
|
608
|
+
|
|
609
|
+
## 4.1.0
|
|
610
|
+
|
|
611
|
+
## 4.0.5
|
|
612
|
+
|
|
613
|
+
### Patch Changes
|
|
614
|
+
|
|
615
|
+
- 15e0df6: chore: unify all package versions to a single patch release
|
|
616
|
+
|
|
617
|
+
## 4.0.4
|
|
618
|
+
|
|
619
|
+
## 4.0.3
|
|
620
|
+
|
|
621
|
+
## 4.0.2
|
|
622
|
+
|
|
623
|
+
## 4.0.0
|
|
624
|
+
|
|
625
|
+
## 3.3.1
|
|
626
|
+
|
|
627
|
+
## 3.3.0
|
|
628
|
+
|
|
629
|
+
## 3.2.9
|
|
630
|
+
|
|
631
|
+
## 3.2.8
|
|
632
|
+
|
|
633
|
+
## 3.2.7
|
|
634
|
+
|
|
635
|
+
## 3.2.6
|
|
636
|
+
|
|
637
|
+
## 3.2.5
|
|
638
|
+
|
|
639
|
+
## 3.2.4
|
|
640
|
+
|
|
641
|
+
## 3.2.3
|
|
642
|
+
|
|
643
|
+
## 3.2.2
|
|
644
|
+
|
|
645
|
+
## 3.2.1
|
|
646
|
+
|
|
647
|
+
## 3.2.0
|
|
648
|
+
|
|
649
|
+
## 3.1.1
|
|
650
|
+
|
|
651
|
+
## 3.1.0
|
|
652
|
+
|
|
653
|
+
## 3.0.11
|
|
654
|
+
|
|
655
|
+
## 3.0.10
|
|
656
|
+
|
|
657
|
+
## 3.0.9
|
|
658
|
+
|
|
659
|
+
## 3.0.8
|
|
@@ -13,7 +13,6 @@
|
|
|
13
13
|
"dependencies": {
|
|
14
14
|
"@objectstack/spec": "^17.0.0",
|
|
15
15
|
"@objectstack/runtime": "^17.0.0",
|
|
16
|
-
"@objectstack/driver-memory": "^17.0.0",
|
|
17
16
|
"@objectstack/plugin-hono-server": "^17.0.0",
|
|
18
17
|
"@objectstack/connector-rest": "^17.0.0",
|
|
19
18
|
"@objectstack/connector-openapi": "^17.0.0",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-objectstack",
|
|
3
|
-
"version": "17.0.0-rc.
|
|
3
|
+
"version": "17.0.0-rc.2",
|
|
4
4
|
"description": "Create a new ObjectStack project — npx create-objectstack",
|
|
5
5
|
"bin": {
|
|
6
6
|
"create-objectstack": "./bin/create-objectstack.js"
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"tar": "^7.5.22"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
|
-
"@types/node": "^26.1.
|
|
23
|
+
"@types/node": "^26.1.2",
|
|
24
24
|
"tsup": "^8.5.1",
|
|
25
25
|
"typescript": "^6.0.3",
|
|
26
26
|
"vitest": "^4.1.10"
|
|
@@ -37,13 +37,15 @@
|
|
|
37
37
|
},
|
|
38
38
|
"files": [
|
|
39
39
|
"dist",
|
|
40
|
-
"README.md"
|
|
40
|
+
"README.md",
|
|
41
|
+
"CHANGELOG.md"
|
|
41
42
|
],
|
|
42
43
|
"engines": {
|
|
43
44
|
"node": ">=22.0.0"
|
|
44
45
|
},
|
|
45
46
|
"scripts": {
|
|
46
47
|
"build": "tsup",
|
|
48
|
+
"typecheck": "tsc --noEmit",
|
|
47
49
|
"dev": "tsup --watch",
|
|
48
50
|
"test": "vitest run"
|
|
49
51
|
}
|