Skip to content

Commit cbcab4e

Browse files
committed
Merge remote-tracking branch 'origin/main' into claude/issue-24939-bu-parent-delete-restrict
2 parents 446fefc + 3a7a60a commit cbcab4e

9 files changed

Lines changed: 49 additions & 30 deletions

File tree

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
'@objectstack/spec': patch
3+
---
4+
5+
fix(spec): `os lint` no longer tells authors to remove a declared webhook's `label` or `description`
6+
7+
Clause-②: no (a liveness-ledger re-grade: no schema, accept set, served body or error code moves; only the advisory `liveness-dead-property` warning on these two keys stops)
8+
9+
The shipped liveness ledger (`liveness/webhook.json`) graded a declared webhook's `label` and `description` `dead` once the boot seeder that copied them into a `sys_webhook` row retired, and the advisory lint warned "Remove it" on every webhook that authored them. They are read: the Studio metadata list and quick-find show both keys, read off `GET /api/v1/meta/webhook`. Both rows are now `live`, so a declared webhook may keep its `label` and `description` and no warning is printed for them. Nothing else changes: the dispatcher still delivers on the same props as before.

‎content/docs/ai/skills-reference.mdx‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,20 @@ The catalog ships as the npm package [`@objectstack/skills`](https://www.npmjs.c
1818

1919
```bash
2020
# 1 · the catalog, at the version of your installed @objectstack/spec
21-
npm install --save-dev "@objectstack/skills@$(node -p "require('@objectstack/spec/package.json').version")"
21+
pnpm add -D "@objectstack/skills@$(node -p "require('@objectstack/spec/package.json').version")"
22+
# npm: npm install --save-dev "@objectstack/skills@…" · yarn: yarn add -D "@objectstack/skills@…"
2223

2324
# 2 · copy it from node_modules into your agent's skills directory
2425
npx skills@1.7.2 experimental_sync --agent claude-code --copy -y
2526
```
2627

28+
Add the package with the manager that installed the project: in a pnpm project, `npm install --save-dev` exits `1` with `npm error Cannot read properties of null (reading 'edgesOut')`.
29+
2730
Step 2 is the [skills CLI](https://www.npmjs.com/package/skills)'s sync from `node_modules`: it finds the skills under `node_modules/@objectstack/skills/dist/skills/`, copies each one into your agent's directory — for `claude-code`, real files in `.claude/skills/<skill>` and nowhere else — and records the source and version in `skills-lock.json`. Commit both with the project. Keep `--copy`: without it the sync writes links into `node_modules`, which is not committed, so a clone of the project gets dangling links and no skills. The CLI is pinned because `experimental_sync` is that tool's own unstable interface; `create-objectstack` runs the same version. Name your own runtime after `--agent` (`codex`, `cursor`, …), one runtime per run — never `--agent '*'`, which copies the catalog into dozens of agent directories at once. A bare `npm install --save-dev @objectstack/skills` installs whichever version the registry tags `latest`, not your spec's — keep the version in step 1.
2831

2932
**Updating.** The catalog is versioned as **one bundle**, and it moves only with your ObjectStack version — you never track or update a skill on its own: bump `@objectstack/skills` with the other `@objectstack/*` packages, then re-run the sync (step 2, same flags) and commit what it changed.
3033

31-
**Which versions exist.** `@objectstack/skills` is published from `18.0.0-next.0` on; there is no 17.x release of it. A project on `@objectstack/spec` 17.x therefore has no catalog bound to its version: step 1 refuses with `ETARGET` (`No matching version found`), and moving it to 18 includes [a skills step](/docs/upgrading#moving-the-dependency-pins). One scaffolder is the exception to the next paragraph: `create-objectstack@18.0.0-next.0` still installed the skills from the repository's `main` with `skills add`, and step 2 skips every skill a `skills add` installed (it prints `Skipped … installed with skills add` and exits 0), so in a project it scaffolded run `npx skills remove --all` — or remove the `objectstack-*` skills by name, as the [upgrade step](/docs/upgrading#moving-the-dependency-pins) does, if you added others — and then steps 1 and 2.
34+
**Which versions exist.** `@objectstack/skills` is published from `18.0.0-next.0` on; there is no 17.x release of it. A project on `@objectstack/spec` 17.x therefore has no catalog bound to its version: step 1 refuses with `ERR_PNPM_NO_MATCHING_VERSION` (npm: `ETARGET`; both print `No matching version found`), and moving it to 18 includes [a skills step](/docs/upgrading#moving-the-dependency-pins). One scaffolder is the exception to the next paragraph: `create-objectstack@18.0.0-next.0` still installed the skills from the repository's `main` with `skills add`, and step 2 skips every skill a `skills add` installed (it prints `Skipped … installed with skills add` and exits 0), so in a project it scaffolded run `npx skills list` first, because `npx skills remove --all` removes every installed skill without asking; run that when the list shows only the `objectstack-*` skills — or remove those by name, as the [upgrade step](/docs/upgrading#moving-the-dependency-pins) does, if you added others — and then steps 1 and 2.
3235

3336
**New projects.** `create-objectstack` runs both steps while it scaffolds: the `package.json` it writes depends on `@objectstack/skills` at the same version as `@objectstack/spec`, its dependency install puts the catalog in `node_modules`, and step 2 copies it for one agent runtime, into `.claude/skills/`. Its closing summary prints step 2 again — to re-run after an upgrade, and with another `--agent` for any other runtime you use.
3437

‎content/docs/ai/skills.mdx‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,13 @@ See [Agents](/docs/ai/agents#you-extend-the-platform-with-skills-not-agents) for
2929
Skills ship as the npm package `@objectstack/skills`, released with the other `@objectstack/*` packages at one shared version. Install it at your installed `@objectstack/spec`'s version — the catalog's version is then your spec's — and copy it from `node_modules` into your agent's directory, the two steps `create-objectstack` runs when it scaffolds a project:
3030

3131
```bash
32-
npm install --save-dev "@objectstack/skills@$(node -p "require('@objectstack/spec/package.json').version")"
32+
pnpm add -D "@objectstack/skills@$(node -p "require('@objectstack/spec/package.json').version")"
33+
# npm: npm install --save-dev "@objectstack/skills@…" · yarn: yarn add -D "@objectstack/skills@…"
3334
npx skills@1.7.2 experimental_sync --agent claude-code --copy -y
3435
```
3536

37+
Add the package with the manager that installed the project: in a pnpm project, `npm install --save-dev` exits `1` with `npm error Cannot read properties of null (reading 'edgesOut')`.
38+
3639
The skills land as real files in `.claude/skills/`; commit them with the project, and keep `--copy` — without it they are links into `node_modules`, which a clone does not have. Name your own runtime after `--agent` (`codex`, `cursor`, …). The catalog is versioned and updated as **one unit**, with ObjectStack itself: bump `@objectstack/skills` with the other `@objectstack/*` packages, then re-run the sync. The package is published from `18.0.0-next.0` on (there is no 17.x release); for what the sync writes, the versions, the one scaffolder that is an exception and the `next` channel, see the [AI Skills Reference](/docs/ai/skills-reference#installing-skills).
3740

3841
---

‎content/docs/upgrading.mdx‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,14 @@ command for this move; it is four steps you run yourself.
108108
npx skills remove objectstack-ai objectstack-api objectstack-automation \
109109
objectstack-data objectstack-formula objectstack-i18n objectstack-platform \
110110
objectstack-pm-dispatch objectstack-query objectstack-ui objectstack-upgrade -y
111-
npm install --save-dev "@objectstack/skills@$(node -p "require('@objectstack/spec/package.json').version")"
111+
pnpm add -D "@objectstack/skills@$(node -p "require('@objectstack/spec/package.json').version")"
112+
# npm: npm install --save-dev "@objectstack/skills@…" · yarn: yarn add -D "@objectstack/skills@…"
112113
npx skills@1.7.2 experimental_sync --agent claude-code --copy -y
113114
```
114115

116+
Add the package with the manager that installed the project: in a pnpm
117+
project, `npm install --save-dev` exits `1` with
118+
`npm error Cannot read properties of null (reading 'edgesOut')`.
115119
The list names every skill the catalog carried during 17.x, and a name that
116120
is not installed is skipped; `npx skills remove --all` does the same when
117121
these are the only skills the project has. Run `npx skills list` first:

‎docs/qa/platform-checklist/areas/integration-system.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -642,7 +642,7 @@
642642
],
643643
"source": [
644644
"packages/spec/src/automation/webhook.zod.ts#WebhookTriggerType (WebhookTriggerType enum + why undelete/api are absent; materialization contract; strict shape #4001)",
645-
"packages/spec/liveness/webhook.json (9 props live on the registry read; label/description dead since the boot seeder retired)",
645+
"packages/spec/liveness/webhook.json (9 props live on the registry read; label/description live on the Studio metadata list and quick-find, which read the declared item over GET /api/v1/meta/webhook)",
646646
"packages/plugins/plugin-webhooks/src/declared-webhooks.ts + auto-enqueuer.ts (the registry read and its remaps; trigger→event mapping incl. the #4639 bulk pair; #3196 unknown-trigger warn; the activation-ledger switch; an 18.0 database's seeded rows read beside the declaration)",
647647
"packages/services/service-messaging/src/http-outbox.ts#HttpRedeliverError (delivery statuses, attempts; HttpRedeliverError + assertHttpRedeliverable/assertRedeliverAllowed — terminal-only, the attempts===0 parked-row refusal, the fail-closed guard) + packages/services/service-messaging/src/http-signature-at-rest.integration.test.ts (redelivery replays the stored signature byte-for-byte)",
648648
"packages/plugins/plugin-webhooks/src/webhook-outbox-plugin.ts#session (POST /api/v1/webhooks/redeliver — session auth with NO capability gate by design ('every authenticated user counts'), #10740 activeOrganizationId threading, the 401/400/404/409/500 arms) + (the #8069 redeliver-guard install; its ABSENCE is an error-level log, not a silent pass)",

‎examples/app-showcase/src/automation/webhooks/index.ts‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ import { defineWebhook } from '@objectstack/spec/automation';
44

55
/**
66
* Outbound webhook — fans out task lifecycle events (create/update/delete)
7-
* to an external endpoint. No `label` / `description`: a declared webhook has
8-
* no Setup row to show them on, and the liveness ledger marks both dead.
7+
* to an external endpoint. A declared webhook has no Setup row, but a `label` /
8+
* `description` authored here is not inert: the liveness ledger grades both
9+
* `live`, because the Studio metadata list and quick-find show them, read off
10+
* `GET /api/v1/meta/webhook`.
911
* Authored via `defineStack({ webhooks })`; the webhooks plugin's dispatcher
1012
* reads this declaration from the registry (ADR-0131 D2) — no `sys_webhook`
1113
* row is written for it.

‎packages/lint/src/lint-liveness-properties.test.ts‎

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -251,12 +251,13 @@ describe('lintLivenessProperties', () => {
251251
// #3494 PRUNED the aspirational dead props from the schema and the #3489
252252
// materializer bridge made every remaining prop live. ADR-0131 D2 then
253253
// retired that bridge: a declared webhook is read from the registry and has
254-
// no Setup row, so the two display-only props, `label` and `description`,
255-
// lost their only reader and the ledger marks them dead. Every delivery-
256-
// bearing prop stays silent. Runs against the REAL webhook.json, so a ledger
257-
// flip that is not carried to authors fails here.
254+
// no Setup row. The two display-only props, `label` and `description`, stay
255+
// live all the same: the Studio metadata list and quick-find draw them off
256+
// `GET /api/v1/meta/webhook`, so the ledger grades them live and nothing
257+
// warns. Runs against the REAL webhook.json, so a ledger flip that is not
258+
// carried to authors fails here.
258259

259-
it('warns on a declared webhook\'s label and description only — every delivery-bearing prop is live', () => {
260+
it('stays silent on a declared webhook that authors every prop, label and description included', () => {
260261
const findings = lintLivenessProperties({
261262
webhooks: [{
262263
name: 'showcase_task_changed',
@@ -272,14 +273,7 @@ describe('lintLivenessProperties', () => {
272273
description: 'Sends task lifecycle events to an external system.',
273274
}],
274275
});
275-
expect(findings.map((f) => [f.rule, f.message.match(/`(\w+)`/)?.[1]])).toEqual([
276-
['liveness-dead-property', 'label'],
277-
['liveness-dead-property', 'description'],
278-
]);
279-
for (const f of findings) {
280-
expect(f.where).toBe("webhook 'showcase_task_changed'");
281-
expect(f.hint).toContain('no Setup row');
282-
}
276+
expect(findings).toEqual([]);
283277
});
284278

285279
it('stays silent on a declared webhook that authors only what is delivered on', () => {

‎packages/spec/liveness/state-counts/webhook.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@ committed anywhere: `check:liveness` sums the shards when it reads them.
1212

1313
| Type | live | exp | elsewhere | dead | planned | classified |
1414
|---|---|---|---|---|---|---|
15-
| `webhook` | 17 | 0 | 0 | 2 | 0 | 19 |
15+
| `webhook` | 19 | 0 | 0 | 0 | 0 | 19 |

0 commit comments

Comments
 (0)