Skip to content

Commit 2331b1e

Browse files
os-trumpclaude
andauthored
feat(cli): os meta delete can pin its reset and can discard only the pending draft (#13346)
* wip(cli): declare --if-match and --draft on os meta delete * test(cli): drive the real reset door through os meta delete for the pin and draft flags * feat(cli): forward the reset door's OCC pin and draft-only carriers from `os meta delete` `os meta delete <type> <name>` was the only in-repo caller of the SDK reset and called it with two arguments, so every CLI reset was the unpinned, full one: a concurrent edit was silently destroyed instead of answering `409 metadata_conflict` (ADR-0008), and the published overlay went with any pending draft. `DeleteMetaItemOptions` landed on both `deleteItem` declarations in #12181; only the CLI surface was missing. Adds `--if-match <version>` (string, forwarded to `options.ifMatch`) and `--draft` (boolean, forwarded as `options.state = 'draft'`). An empty `--if-match` is refused before the client is built rather than silently downgraded to the unpinned reset. `?dropStorage` stays withheld. A run with neither flag sends byte-identical bytes to what it always sent. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TvqBFLRzXdSPcbusDoED9k --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 200d255 commit 2331b1e

3 files changed

Lines changed: 903 additions & 2 deletions

File tree

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
---
2+
"@objectstack/cli": minor
3+
---
4+
5+
feat(cli): `os meta delete` can pin its reset and can discard only the pending draft (#13024)
6+
7+
`os meta delete <type> <name>` was the only in-repo caller of the SDK reset and
8+
called it with two arguments, so **every** CLI reset was the unpinned, full one:
9+
10+
- **unpinned** — a concurrent edit was silently destroyed instead of answering
11+
`409 metadata_conflict`, on the one verb whose whole job is destroying a
12+
customization overlay row (ADR-0008; the reset door reads `If-Match` and
13+
threads it as `parentVersion`);
14+
- **full** — it dropped the published overlay as well as any pending draft, so
15+
an operator who wanted to throw away only an unpublished draft had to take the
16+
more destructive path.
17+
18+
Both carriers already existed one layer down — `DeleteMetaItemOptions`
19+
(`ifMatch`, `state`) landed on both `@objectstack/client` `deleteItem`
20+
declarations in #12181 — and only the CLI surface was missing.
21+
22+
Two new flags, additive; a run with neither is byte-identical to before (no
23+
query string, no extra header):
24+
25+
- `--if-match <version>` — echo the `version` a previous save or publish
26+
resolved and a stale reset is refused with `409 metadata_conflict` instead of
27+
destroying the other author's edit. Unpinned stays the default, and stays
28+
last-write-wins.
29+
- `--draft` — discard only the pending draft overlay, leaving the published
30+
overlay serving. Without it the reset is the full one, unchanged.
31+
32+
An **empty** `--if-match` is refused before anything reaches the server, rather
33+
than being forwarded as "no pin". `os meta delete view v --if-match "$VERSION"`
34+
with `VERSION` unset expands to an empty argument, and silently running the
35+
unpinned reset there is exactly the destruction the flag exists to prevent. The
36+
refusal names the remedy, and reaches both the human output and the
37+
`--format json` error envelope.
38+
39+
In human (`table`) mode a `--draft` run now prints `Pending draft discarded:
40+
<type>/<name>` instead of `Metadata deleted: <type>/<name>`, which would be a
41+
false report of what happened on the narrower verb. The `json`/`yaml` payload
42+
keys are unchanged (`success`, `type`, `name`, `deleted`).
43+
44+
⛔ Not added, deliberately: `?dropStorage`, the door's third carrier. #12181
45+
withheld it because it is the one that ADDS destructive reach (it drops the
46+
object's physical table), and no caller has been measured needing it. Publishing
47+
it from the CLI would reverse that ruling from the layer above.

0 commit comments

Comments
 (0)