sdoc-editor-cli 0.9.2 → 0.9.3

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.
Files changed (3) hide show
  1. package/README.md +221 -221
  2. package/dist/sdoc.js +1 -1
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -4,86 +4,86 @@
4
4
  validating, creating, and safely changing Structured Doc Editor `.sdoc` and
5
5
  legacy `.tiptap.json` documents. It requires Node.js 22.22.2 or newer.
6
6
 
7
- The package is distributed as a GitHub Release tarball, not through the public
8
- npm registry. The similarly named registry package `sdoc` is unrelated.
7
+ The official package is published to the public npm registry as
8
+ [`sdoc-editor-cli`](https://www.npmjs.com/package/sdoc-editor-cli). Its installed
9
+ command is `sdoc`. The separate registry package named `sdoc` is unrelated.
9
10
 
10
- ## Safe installation and verification
11
+ ## Install and run
11
12
 
12
- Discover the current versioned tarball from the latest non-prerelease GitHub
13
- Release. This PowerShell example uses the anonymous GitHub Releases REST API
14
- and refuses to continue unless exactly one CLI asset matches:
13
+ Try the current stable release without adding a project dependency:
15
14
 
16
15
  ```powershell
17
- $release = Invoke-RestMethod `
18
- -Headers @{
19
- Accept = 'application/vnd.github+json'
20
- 'X-GitHub-Api-Version' = '2022-11-28'
21
- } `
22
- -Uri 'https://api.github.com/repos/SWBaek/sdoc-editor/releases/latest'
23
- $cliAssets = @($release.assets | Where-Object {
24
- $_.name -match '^sdoc-editor-cli-[0-9]+\.[0-9]+\.[0-9]+(?:-[0-9A-Za-z.-]+)?\.tgz$'
25
- })
26
- if ($cliAssets.Count -ne 1) {
27
- throw "Expected exactly one sdoc-editor-cli-*.tgz asset, found $($cliAssets.Count)."
28
- }
29
- $env:SDOC_CLI_TGZ_URL = $cliAssets[0].browser_download_url
16
+ npx sdoc-editor-cli@latest --help
30
17
  ```
31
18
 
32
- The equivalent POSIX flow requires `curl` and `jq`:
33
-
34
- ```bash
35
- SDOC_CLI_TGZ_URL="$(
36
- curl -fsSL \
37
- -H 'Accept: application/vnd.github+json' \
38
- -H 'X-GitHub-Api-Version: 2022-11-28' \
39
- https://api.github.com/repos/SWBaek/sdoc-editor/releases/latest |
40
- jq -er '
41
- [.assets[] | select(.name | test("^sdoc-editor-cli-[0-9]+[.][0-9]+[.][0-9]+(-[0-9A-Za-z.-]+)?[.]tgz$"))]
42
- | if length == 1 then .[0].browser_download_url
43
- else error("expected exactly one sdoc-editor-cli-*.tgz asset")
44
- end
45
- '
46
- )"
47
- export SDOC_CLI_TGZ_URL
19
+ For a project-pinned version, install the official package as a development
20
+ dependency and invoke it by its exact package name:
21
+
22
+ ```powershell
23
+ npm install --save-dev sdoc-editor-cli
24
+ npx sdoc-editor-cli --version
25
+ npx sdoc-editor-cli capabilities --json
48
26
  ```
49
27
 
50
- Anonymous GitHub REST requests are rate-limited (typically 60 requests per
51
- hour per source IP). Authenticate the API request when a shared runner may
52
- exceed that limit. The CLI is not published to npm, and releases do not
53
- provide an unversioned `latest` download alias; always use the selected
54
- asset's `browser_download_url`.
28
+ Update that dependency explicitly when the project is ready to adopt the
29
+ current stable release:
30
+
31
+ ```powershell
32
+ npm install --save-dev sdoc-editor-cli@latest
33
+ ```
55
34
 
56
- For a project-local install, run these commands from the project that owns the
57
- dependency:
35
+ For repeatable CI or Agent automation, commit `package.json` and the lockfile,
36
+ run `npm ci`, and add a project script:
37
+
38
+ ```json
39
+ {
40
+ "scripts": {
41
+ "sdoc": "sdoc"
42
+ }
43
+ }
44
+ ```
45
+
46
+ Pass CLI arguments after npm's `--` separator:
58
47
 
59
48
  ```powershell
60
- npm install --save-dev "$env:SDOC_CLI_TGZ_URL"
61
- npm ls sdoc-editor-cli --depth=0
62
- node .\node_modules\sdoc-editor-cli\dist\sdoc.js --version
49
+ npm run sdoc -- capabilities --json
63
50
  ```
64
51
 
65
- > **Package name collision warning:** The npm public registry contains an
66
- > unrelated package named `sdoc`. Even `npx --no-install sdoc` can resolve a
67
- > cached copy of that unrelated package when the project-local CLI is absent.
68
- > For deterministic local execution, invoke the installed package entry point
69
- > directly with `node ./node_modules/sdoc-editor-cli/dist/sdoc.js ...` and verify
70
- > the dependency first with `npm ls sdoc-editor-cli --depth=0`. A missing local
71
- > package then fails with a path/module error instead of running another
72
- > package. Do not install the registry package `sdoc`; it is not part of
73
- > Structured Doc Editor. Check the current directory before invoking the CLI
74
- > when an agent may be operating in more than one project.
52
+ `npm run` uses the project-local binary and fails when the dependency is
53
+ missing; it does not fetch a command from the registry.
54
+
55
+ > **Package name collision warning:** Use `sdoc-editor-cli` with `npx`. Do not
56
+ > run `npx sdoc` or install the public package named `sdoc`; it is unrelated to
57
+ > Structured Doc Editor.
58
+
59
+ The CLI does not replace itself automatically. Use the explicit npm update
60
+ command above, or let the owning project's dependency automation update its
61
+ manifest and lockfile.
75
62
 
76
- Use a global install only when that scope was explicitly requested:
63
+ ### Version-pinned GitHub Release fallback
64
+
65
+ Every tagged release also attaches a versioned `sdoc-editor-cli-*.tgz` to
66
+ [GitHub Releases](https://github.com/SWBaek/sdoc-editor/releases/latest). Use
67
+ this path when an installation must be pinned to a downloaded release asset.
68
+ After downloading the selected tarball, install it from the project that owns
69
+ the dependency:
70
+
71
+ ```powershell
72
+ npm install --save-dev .\sdoc-editor-cli-X.Y.Z.tgz
73
+ npx sdoc-editor-cli --version
74
+ ```
75
+
76
+ For frequent interactive use across projects, a global install provides the
77
+ short `sdoc` command:
77
78
 
78
79
  ```powershell
79
- npm install --global "$env:SDOC_CLI_TGZ_URL"
80
- npm list --global sdoc-editor-cli --depth=0
80
+ npm install --global sdoc-editor-cli
81
81
  sdoc --version
82
82
  ```
83
83
 
84
- The remaining examples use `sdoc` for readability. For a local installation,
85
- replace it with `node ./node_modules/sdoc-editor-cli/dist/sdoc.js`. Do not use
86
- `npx sdoc` or `npx --no-install sdoc` as a local-presence check.
84
+ The remaining examples use `sdoc` for readability. After a project-local
85
+ install, replace that prefix with `npx sdoc-editor-cli`, or use the `npm run
86
+ sdoc --` script above. A global installation can run `sdoc` directly.
87
87
 
88
88
  ## Help and output
89
89
 
@@ -93,71 +93,71 @@ sdoc help apply
93
93
  sdoc inspect --help
94
94
  ```
95
95
 
96
- JSON is the default and stable machine-readable output. `--json` states that
97
- choice explicitly. `--human` provides concise interactive output and is not a
98
- stable machine API; its wording and layout may change between releases. Never
99
- parse human output in an Agent or script. Success is written to stdout;
100
- structured errors are written to stderr.
101
-
102
- Every JSON success and failure is one line with the top-level contract
103
- `sdoc.cli.response/1`. The packaged schema is
104
- `dist/schemas/sdoc.cli.response.schema.json`. Consumers must ignore unknown
105
- fields: compatible updates may add fields, commands, operations, diagnostics,
106
- and capability values, while existing fields retain their documented meaning.
107
-
108
- ```json
109
- {"contract":"sdoc.cli.response/1","ok":true,"command":"validate","revision":"sha256:..."}
110
- ```
111
-
112
- Failures always include `category` and a non-empty `diagnostics` array:
113
-
114
- ```json
115
- {"contract":"sdoc.cli.response/1","ok":false,"category":"argument","diagnostics":[{"code":"CLI_MISSING_DOCUMENT","message":"..."}]}
116
- ```
117
-
118
- ## Commands
119
-
120
- ### `capabilities`
121
-
122
- Reports the installed CLI version, supported contracts and commands, semantic
123
- operation names, safety limits, read projections/catalog kinds, and built-in
124
- template IDs. It does not accept a document path. JSON is the default:
125
-
126
- ```powershell
127
- sdoc capabilities
128
- sdoc capabilities --json
129
- sdoc capabilities --human
130
- ```
131
-
132
- ```json
133
- {
134
- "contract": "sdoc.cli.response/1",
135
- "ok": true,
136
- "command": "capabilities",
137
- "cliVersion": "0.9.2",
138
- "contracts": {
139
- "document": "sdoc/1.0",
140
- "operations": "sdoc.operations/1",
141
- "read": "sdoc.read/1",
142
- "response": "sdoc.cli.response/1"
143
- },
144
- "commands": ["capabilities", "inspect", "validate", "apply", "rename-heading", "set-document-title", "create"],
145
- "projections": ["catalog", "target", "section", "document"],
146
- "catalogKinds": ["blocks", "outline", "references", "referenceables"],
147
- "builtInTemplateIds": ["builtin:blank", "builtin:technical-report", "builtin:design-specification", "builtin:verification-report"]
148
- }
149
- ```
150
-
151
- The actual result also includes `semanticOperations` and numeric `limits`;
152
- query it instead of hard-coding the installed package's capabilities.
153
-
154
- ### `inspect`
155
-
156
- Without `--projection`, returns the existing inspector shape: the SHA-256
157
- revision of the exact source bytes, metadata, outline, references,
158
- referenceable nodes, targetable blocks, and an optional selected target. The
159
- revision includes a UTF-8 BOM when present and changes after
160
- representation-only edits. Existing no-projection calls retain this behavior.
96
+ JSON is the default and stable machine-readable output. `--json` states that
97
+ choice explicitly. `--human` provides concise interactive output and is not a
98
+ stable machine API; its wording and layout may change between releases. Never
99
+ parse human output in an Agent or script. Success is written to stdout;
100
+ structured errors are written to stderr.
101
+
102
+ Every JSON success and failure is one line with the top-level contract
103
+ `sdoc.cli.response/1`. The packaged schema is
104
+ `dist/schemas/sdoc.cli.response.schema.json`. Consumers must ignore unknown
105
+ fields: compatible updates may add fields, commands, operations, diagnostics,
106
+ and capability values, while existing fields retain their documented meaning.
107
+
108
+ ```json
109
+ {"contract":"sdoc.cli.response/1","ok":true,"command":"validate","revision":"sha256:..."}
110
+ ```
111
+
112
+ Failures always include `category` and a non-empty `diagnostics` array:
113
+
114
+ ```json
115
+ {"contract":"sdoc.cli.response/1","ok":false,"category":"argument","diagnostics":[{"code":"CLI_MISSING_DOCUMENT","message":"..."}]}
116
+ ```
117
+
118
+ ## Commands
119
+
120
+ ### `capabilities`
121
+
122
+ Reports the installed CLI version, supported contracts and commands, semantic
123
+ operation names, safety limits, read projections/catalog kinds, and built-in
124
+ template IDs. It does not accept a document path. JSON is the default:
125
+
126
+ ```powershell
127
+ sdoc capabilities
128
+ sdoc capabilities --json
129
+ sdoc capabilities --human
130
+ ```
131
+
132
+ ```json
133
+ {
134
+ "contract": "sdoc.cli.response/1",
135
+ "ok": true,
136
+ "command": "capabilities",
137
+ "cliVersion": "0.9.3",
138
+ "contracts": {
139
+ "document": "sdoc/1.0",
140
+ "operations": "sdoc.operations/1",
141
+ "read": "sdoc.read/1",
142
+ "response": "sdoc.cli.response/1"
143
+ },
144
+ "commands": ["capabilities", "inspect", "validate", "apply", "rename-heading", "set-document-title", "create"],
145
+ "projections": ["catalog", "target", "section", "document"],
146
+ "catalogKinds": ["blocks", "outline", "references", "referenceables"],
147
+ "builtInTemplateIds": ["builtin:blank", "builtin:technical-report", "builtin:design-specification", "builtin:verification-report"]
148
+ }
149
+ ```
150
+
151
+ The actual result also includes `semanticOperations` and numeric `limits`;
152
+ query it instead of hard-coding the installed package's capabilities.
153
+
154
+ ### `inspect`
155
+
156
+ Without `--projection`, returns the existing inspector shape: the SHA-256
157
+ revision of the exact source bytes, metadata, outline, references,
158
+ referenceable nodes, targetable blocks, and an optional selected target. The
159
+ revision includes a UTF-8 BOM when present and changes after
160
+ representation-only edits. Existing no-projection calls retain this behavior.
161
161
 
162
162
  ```powershell
163
163
  sdoc inspect document.sdoc --json
@@ -187,46 +187,46 @@ slash-delimited content path. For example, `/1/0` selects
187
187
  }
188
188
  ```
189
189
 
190
- Copy `target.operationTarget` directly instead of assembling a snapshot
191
- target. Every `blocks[]` entry also includes its canonical `operationTarget`.
192
- Referenceable nodes receive an ID target; other blocks receive a snapshot
193
- target. A provisional ID is valid only for that inspected revision; applying
194
- it persists the ID.
195
-
196
- An explicit `--projection` selects the additive bounded `sdoc.read/1`
197
- contract. Projected JSON still uses `contract: "sdoc.cli.response/1"` as its
198
- top-level response discriminator and exposes the core discriminator separately
199
- as `readContract: "sdoc.read/1"`. The core `projection`, `revision`, `data`,
200
- `page`, and `budget` fields remain top-level. Validate request objects against
201
- `dist/schemas/sdoc.read.schema.json` when another host calls the shared core
202
- directly.
203
-
204
- ```powershell
205
- sdoc inspect document.sdoc --projection catalog --json
206
- sdoc inspect document.sdoc --projection catalog --catalog outline --limit 100 --json
207
- sdoc inspect document.sdoc --projection target --target-id intro --max-bytes 262144 --max-nodes 1000 --json
208
- sdoc inspect document.sdoc --projection section --target-path /0 --max-nodes 500 --human
209
- sdoc inspect document.sdoc --projection document --max-bytes 262144 --max-nodes 1000 --json
210
- sdoc inspect document.sdoc --projection document --cursor $nextCursor --json
211
- ```
212
-
213
- Projection option rules are strict and are checked before the document is
214
- read:
215
-
216
- | Projection | Target | Allowed read options |
217
- |---|---|---|
218
- | `catalog` | none | `--catalog`, `--limit`, `--cursor`, `--max-bytes`, `--max-summary-length`, `--expected-revision` |
219
- | `target` | exactly one of ID/path | `--max-bytes`, `--max-nodes`, `--expected-revision` |
220
- | `section` | exactly one of ID/path | `--cursor`, `--max-bytes`, `--max-nodes`, `--expected-revision` |
221
- | `document` | none | `--cursor`, `--max-bytes`, `--max-nodes`, `--expected-revision` |
222
-
223
- The catalog defaults to `blocks`. `--limit`, `--max-bytes`, `--max-nodes`,
224
- and `--max-summary-length` accept canonical positive base-10 integers. Read
225
- options other than legacy `--target-id` and `--target-path` require an explicit
226
- projection. Catalog, section, and document results can return
227
- `page.nextCursor`; pass it back with the same projection/query until
228
- `page.complete` is true. Cursors bind the exact source bytes and query scope.
229
- They are opaque integrity tokens, not authentication credentials.
190
+ Copy `target.operationTarget` directly instead of assembling a snapshot
191
+ target. Every `blocks[]` entry also includes its canonical `operationTarget`.
192
+ Referenceable nodes receive an ID target; other blocks receive a snapshot
193
+ target. A provisional ID is valid only for that inspected revision; applying
194
+ it persists the ID.
195
+
196
+ An explicit `--projection` selects the additive bounded `sdoc.read/1`
197
+ contract. Projected JSON still uses `contract: "sdoc.cli.response/1"` as its
198
+ top-level response discriminator and exposes the core discriminator separately
199
+ as `readContract: "sdoc.read/1"`. The core `projection`, `revision`, `data`,
200
+ `page`, and `budget` fields remain top-level. Validate request objects against
201
+ `dist/schemas/sdoc.read.schema.json` when another host calls the shared core
202
+ directly.
203
+
204
+ ```powershell
205
+ sdoc inspect document.sdoc --projection catalog --json
206
+ sdoc inspect document.sdoc --projection catalog --catalog outline --limit 100 --json
207
+ sdoc inspect document.sdoc --projection target --target-id intro --max-bytes 262144 --max-nodes 1000 --json
208
+ sdoc inspect document.sdoc --projection section --target-path /0 --max-nodes 500 --human
209
+ sdoc inspect document.sdoc --projection document --max-bytes 262144 --max-nodes 1000 --json
210
+ sdoc inspect document.sdoc --projection document --cursor $nextCursor --json
211
+ ```
212
+
213
+ Projection option rules are strict and are checked before the document is
214
+ read:
215
+
216
+ | Projection | Target | Allowed read options |
217
+ |---|---|---|
218
+ | `catalog` | none | `--catalog`, `--limit`, `--cursor`, `--max-bytes`, `--max-summary-length`, `--expected-revision` |
219
+ | `target` | exactly one of ID/path | `--max-bytes`, `--max-nodes`, `--expected-revision` |
220
+ | `section` | exactly one of ID/path | `--cursor`, `--max-bytes`, `--max-nodes`, `--expected-revision` |
221
+ | `document` | none | `--cursor`, `--max-bytes`, `--max-nodes`, `--expected-revision` |
222
+
223
+ The catalog defaults to `blocks`. `--limit`, `--max-bytes`, `--max-nodes`,
224
+ and `--max-summary-length` accept canonical positive base-10 integers. Read
225
+ options other than legacy `--target-id` and `--target-path` require an explicit
226
+ projection. Catalog, section, and document results can return
227
+ `page.nextCursor`; pass it back with the same projection/query until
228
+ `page.complete` is true. Cursors bind the exact source bytes and query scope.
229
+ They are opaque integrity tokens, not authentication credentials.
230
230
 
231
231
  ### `validate`
232
232
 
@@ -239,10 +239,10 @@ sdoc validate legacy.tiptap.json --human
239
239
 
240
240
  ### `apply`
241
241
 
242
- Reads a complete `sdoc.operations/1` request from a UTF-8 JSON file or stdin.
243
- Malformed UTF-8 is rejected before JSON parsing, locking, or document writes.
244
- A UTF-8 BOM and non-ASCII JSON content are accepted. Preview is the default;
245
- only `--write` can modify the named document.
242
+ Reads a complete `sdoc.operations/1` request from a UTF-8 JSON file or stdin.
243
+ Malformed UTF-8 is rejected before JSON parsing, locking, or document writes.
244
+ A UTF-8 BOM and non-ASCII JSON content are accepted. Preview is the default;
245
+ only `--write` can modify the named document.
246
246
 
247
247
  ```powershell
248
248
  sdoc apply document.sdoc --operations operations.json --json
@@ -299,24 +299,24 @@ The preview and a later independent write can have different
299
299
 
300
300
  ### `set-document-title`
301
301
 
302
- Convenience command for one `setDocumentTitle` operation. `--title` and
303
- `--expected-revision` are required. Without `--id`, the command changes only
304
- `meta.title`. With the persistent or provisional ID of an H1, it changes
305
- `meta.title` and that explicit title heading atomically. The CLI never guesses
306
- a title heading and never renames the file.
302
+ Convenience command for one `setDocumentTitle` operation. `--title` and
303
+ `--expected-revision` are required. Without `--id`, the command changes only
304
+ `meta.title`. With the persistent or provisional ID of an H1, it changes
305
+ `meta.title` and that explicit title heading atomically. The CLI never guesses
306
+ a title heading and never renames the file.
307
307
 
308
308
  ```powershell
309
- $inspection = sdoc inspect document.sdoc --json | ConvertFrom-Json
310
- sdoc set-document-title document.sdoc --title "Metadata title" `
311
- --expected-revision $inspection.revision --write --json
312
- $inspection = sdoc inspect document.sdoc --json | ConvertFrom-Json
313
- sdoc set-document-title document.sdoc --title "Updated document" --id title-h1 `
314
- --expected-revision $inspection.revision --write --json
315
- ```
316
-
317
- Use `--discard-formatting` only when replacing marked or non-text content in
318
- the selected H1 is intentional. It requires `--id`; without an H1 target there
319
- is no formatting to discard.
309
+ $inspection = sdoc inspect document.sdoc --json | ConvertFrom-Json
310
+ sdoc set-document-title document.sdoc --title "Metadata title" `
311
+ --expected-revision $inspection.revision --write --json
312
+ $inspection = sdoc inspect document.sdoc --json | ConvertFrom-Json
313
+ sdoc set-document-title document.sdoc --title "Updated document" --id title-h1 `
314
+ --expected-revision $inspection.revision --write --json
315
+ ```
316
+
317
+ Use `--discard-formatting` only when replacing marked or non-text content in
318
+ the selected H1 is intentional. It requires `--id`; without an H1 target there
319
+ is no formatting to discard.
320
320
 
321
321
  ### `create`
322
322
 
@@ -331,25 +331,25 @@ sdoc create verification.sdoc --template builtin:verification-report --json
331
331
  sdoc create report.sdoc --template .\templates\company-report.sdoc --json
332
332
  ```
333
333
 
334
- An explicit file template must be a valid UTF-8 JSON `.sdoc`; malformed UTF-8
335
- is rejected before a destination is created. A UTF-8 BOM is accepted. Creation
336
- removes persisted document identity and template-only metadata while
337
- preserving supported settings, node IDs, and links.
338
-
339
- ## Public schemas and operation contract
340
-
341
- The package includes:
342
-
343
- - `dist/schemas/sdoc.operations.schema.json`: draft-07 request schema
344
- - `dist/schemas/sdoc.read.schema.json`: draft-07 `sdoc.read/1` request union
345
- - `dist/schemas/sdoc.cli.response.schema.json`: additive CLI JSON response schema
346
- - `dist/schemas/sdoc.schema.json`: persisted document schema and reusable
347
- `anyNode` fragment
348
- - `dist/examples/operations/*.json`: one request for each semantic operation
349
-
350
- Repository copies live at `sdoc.operations.schema.json`,
351
- `sdoc.read.schema.json`, `sdoc.schema.json`,
352
- `cli/schemas/sdoc.cli.response.schema.json`, and `examples/operations/`.
334
+ An explicit file template must be a valid UTF-8 JSON `.sdoc`; malformed UTF-8
335
+ is rejected before a destination is created. A UTF-8 BOM is accepted. Creation
336
+ removes persisted document identity and template-only metadata while
337
+ preserving supported settings, node IDs, and links.
338
+
339
+ ## Public schemas and operation contract
340
+
341
+ The package includes:
342
+
343
+ - `dist/schemas/sdoc.operations.schema.json`: draft-07 request schema
344
+ - `dist/schemas/sdoc.read.schema.json`: draft-07 `sdoc.read/1` request union
345
+ - `dist/schemas/sdoc.cli.response.schema.json`: additive CLI JSON response schema
346
+ - `dist/schemas/sdoc.schema.json`: persisted document schema and reusable
347
+ `anyNode` fragment
348
+ - `dist/examples/operations/*.json`: one request for each semantic operation
349
+
350
+ Repository copies live at `sdoc.operations.schema.json`,
351
+ `sdoc.read.schema.json`, `sdoc.schema.json`,
352
+ `cli/schemas/sdoc.cli.response.schema.json`, and `examples/operations/`.
353
353
 
354
354
  Every request has this envelope:
355
355
 
@@ -583,11 +583,11 @@ $result = $resultJson | ConvertFrom-Json
583
583
  | 4 | Stale revision or precondition conflict | `STALE_REVISION` |
584
584
  | 5 | File I/O error | `CLI_READ_FAILED` |
585
585
 
586
- On failure, inspect `diagnostics[].code` rather than matching human-readable
587
- messages. The machine-readable `category` is one of `argument`, `document`,
588
- `conflict`, `io`, or `internal`. Categories describe the failure source and do
589
- not replace exit codes; in particular, an `IoError` is categorized as `io`
590
- while retaining its existing exit code.
586
+ On failure, inspect `diagnostics[].code` rather than matching human-readable
587
+ messages. The machine-readable `category` is one of `argument`, `document`,
588
+ `conflict`, `io`, or `internal`. Categories describe the failure source and do
589
+ not replace exit codes; in particular, an `IoError` is categorized as `io`
590
+ while retaining its existing exit code.
591
591
 
592
592
  ## Diagnostic recovery
593
593
 
@@ -596,17 +596,17 @@ must branch on `diagnostics[].code` from explicit `--json` output.
596
596
 
597
597
  | Diagnostic code(s) | Likely cause | Recovery |
598
598
  |---|---|---|
599
- | `CLI_UNKNOWN_*`, `CLI_MISSING_*`, `CLI_CONFLICTING_OPTIONS`, `CLI_OPTION_REQUIRES_ID` | Misspelled command/flag, omitted value, or incompatible/dependent flags | Run the command-specific `--help`, correct the invocation, and retry |
600
- | `CLI_INVALID_TARGET_PATH` | `--target-path` is not a slash-delimited non-negative integer path | Copy the path from `inspect.blocks[].path` and format it like `/1/0` |
601
- | `CLI_INVALID_POSITIVE_INTEGER`, `CLI_INVALID_PROJECTION`, `CLI_INVALID_CATALOG` | A projected read option has a malformed number or unsupported selector | Use `sdoc inspect --help` and pass a documented projection/catalog and canonical positive integer |
602
- | `CLI_PROJECTION_REQUIRED`, `CLI_PROJECTION_REQUIRES_TARGET`, `CLI_PROJECTION_FORBIDS_TARGET`, `CLI_PROJECTION_OPTION_NOT_SUPPORTED` | Projected read flags are missing their projection, target, or valid projection-specific combination | Follow the projection option matrix above; legacy targets remain valid only when no read-only flags are supplied |
603
- | `CLI_INVALID_UTF8` | Operation file or stdin bytes are not valid UTF-8 | Re-encode the complete JSON request as UTF-8 and retry; the document and sibling lock are untouched |
604
- | `CLI_INVALID_JSON`, `INVALID_OPERATION_REQUEST`, `INVALID_OPERATION` | Malformed operations JSON or a request that does not match `sdoc.operations/1` | Validate against the packaged operation schema; inspect `operationIndex` when present |
599
+ | `CLI_UNKNOWN_*`, `CLI_MISSING_*`, `CLI_CONFLICTING_OPTIONS`, `CLI_OPTION_REQUIRES_ID` | Misspelled command/flag, omitted value, or incompatible/dependent flags | Run the command-specific `--help`, correct the invocation, and retry |
600
+ | `CLI_INVALID_TARGET_PATH` | `--target-path` is not a slash-delimited non-negative integer path | Copy the path from `inspect.blocks[].path` and format it like `/1/0` |
601
+ | `CLI_INVALID_POSITIVE_INTEGER`, `CLI_INVALID_PROJECTION`, `CLI_INVALID_CATALOG` | A projected read option has a malformed number or unsupported selector | Use `sdoc inspect --help` and pass a documented projection/catalog and canonical positive integer |
602
+ | `CLI_PROJECTION_REQUIRED`, `CLI_PROJECTION_REQUIRES_TARGET`, `CLI_PROJECTION_FORBIDS_TARGET`, `CLI_PROJECTION_OPTION_NOT_SUPPORTED` | Projected read flags are missing their projection, target, or valid projection-specific combination | Follow the projection option matrix above; legacy targets remain valid only when no read-only flags are supplied |
603
+ | `CLI_INVALID_UTF8` | Operation file or stdin bytes are not valid UTF-8 | Re-encode the complete JSON request as UTF-8 and retry; the document and sibling lock are untouched |
604
+ | `CLI_INVALID_JSON`, `INVALID_OPERATION_REQUEST`, `INVALID_OPERATION` | Malformed operations JSON or a request that does not match `sdoc.operations/1` | Validate against the packaged operation schema; inspect `operationIndex` when present |
605
605
  | `MALFORMED_JSON`, `DOCUMENT_SCHEMA_INVALID`, `UNSUPPORTED_VERSION` | The input is not valid UTF-8 JSON, violates the document schema, or uses an unsupported SDOC version | Repair or migrate the source; do not force a write |
606
606
  | `LEGACY_UPGRADE_REQUIRED` | A legacy `.tiptap.json` mutation omitted the explicit upgrade flag | Re-run with `--upgrade-legacy`, preview first, then add `--write` if intended |
607
- | `STALE_REVISION` | The document bytes changed after inspection | Re-inspect the current file and rebuild the whole request from that revision |
608
- | `INVALID_READ_CURSOR`, `STALE_READ_CURSOR`, `READ_CURSOR_SCOPE_MISMATCH` | A cursor is malformed, the exact source bytes changed, or it belongs to another projection/query | Restart the projection from its first page using the current document; never edit or reuse a cursor across queries |
609
- | `PROJECTION_ITEM_TOO_LARGE` | The next complete catalog entry or subtree cannot fit the requested byte/node budget | Increase the reported limiting budget; projection pages never split a complete item |
607
+ | `STALE_REVISION` | The document bytes changed after inspection | Re-inspect the current file and rebuild the whole request from that revision |
608
+ | `INVALID_READ_CURSOR`, `STALE_READ_CURSOR`, `READ_CURSOR_SCOPE_MISMATCH` | A cursor is malformed, the exact source bytes changed, or it belongs to another projection/query | Restart the projection from its first page using the current document; never edit or reuse a cursor across queries |
609
+ | `PROJECTION_ITEM_TOO_LARGE` | The next complete catalog entry or subtree cannot fit the requested byte/node budget | Increase the reported limiting budget; projection pages never split a complete item |
610
610
  | `TARGET_NOT_FOUND`, `TARGET_NOT_BLOCK`, `TARGET_TYPE_MISMATCH`, `TARGET_DIGEST_MISMATCH` | A selected path/ID is absent, is not a block, changed type, or no longer matches its snapshot | Re-inspect and use the returned `operationTarget`; do not weaken the precondition |
611
611
  | `SECTION_OPERATION_REQUIRED`, `HEADING_TARGET_REQUIRED`, `SECTION_TARGET_REQUIRED`, `TITLE_H1_TARGET_REQUIRED` | A block operation was used for a heading, or a title target was not H1 | Use the matching heading/section operation and an inspected heading target |
612
612
  | `INVALID_HEADING_LEVEL`, `SECTION_LEVEL_OUT_OF_RANGE` | A requested heading level is outside 1-6, or shifting the section would push a descendant outside that range | Choose a valid target level that keeps every descendant heading within 1-6 |
@@ -614,8 +614,8 @@ must branch on `diagnostics[].code` from explicit `--json` output.
614
614
  | `ATTRIBUTE_NOT_ALLOWED`, `NODE_TYPE_CHANGE` | An attr is not allowed for the node, or replacement changes its type | Consult the node catalog/schema and keep replacements type-compatible |
615
615
  | `ID_RENAME_NOT_SUPPORTED`, `ID_RENAME_REQUIRES_EXISTING_ID`, `INVALID_NEW_ID` | An ID rename targeted an unsupported or provisional node, or supplied an invalid new ID | Target an inspected heading/table with an existing persistent ID and choose a unique non-reserved ID |
616
616
  | `NEW_NONPORTABLE_ASSET`, `NEW_DANGLING_REFERENCE`, `NEW_UNSAFE_LINK` | The batch introduces an invalid asset path, missing internal target, or unsafe link | Use `./images/...` or `./drawio/*.drawio.svg`, create referenced IDs, and use a safe URL |
617
- | `DUPLICATE_ID` | The document contains conflicting persistent IDs | Assign unique IDs before retrying |
618
- | `CLI_TEMPLATE_INVALID` | An explicit template has malformed UTF-8, invalid JSON, or violates the template contract | Repair or re-encode the template as UTF-8; creation leaves the destination absent |
617
+ | `DUPLICATE_ID` | The document contains conflicting persistent IDs | Assign unique IDs before retrying |
618
+ | `CLI_TEMPLATE_INVALID` | An explicit template has malformed UTF-8, invalid JSON, or violates the template contract | Repair or re-encode the template as UTF-8; creation leaves the destination absent |
619
619
  | `CLI_TARGET_EXISTS` | `create` would overwrite an existing file | Choose a new path; the CLI never overwrites during creation |
620
620
  | `CLI_LOCK_UNAVAILABLE` | Another writer holds the sibling lock, or its owner cannot be reclaimed safely | Wait for a known writer to finish. Remove an abandoned lock manually only after confirming no writer is active, then re-inspect before retrying |
621
621
  | `CLI_READ_FAILED`, `CLI_ATOMIC_WRITE_FAILED` | Filesystem access or atomic replacement failed | Check path, permissions, free space, and filesystem support; verify the file before retrying |
package/dist/sdoc.js CHANGED
@@ -8325,7 +8325,7 @@ async function createDocumentPlan(documentPath, options = {}) {
8325
8325
  }
8326
8326
 
8327
8327
  // src/main.ts
8328
- var VERSION = true ? "0.9.2" : packageMetadata.version;
8328
+ var VERSION = true ? "0.9.3" : packageMetadata.version;
8329
8329
  var DEFAULT_DEPENDENCIES = {
8330
8330
  replaceDocument: atomicReplace,
8331
8331
  createDocument: atomicCreate
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sdoc-editor-cli",
3
- "version": "0.9.2",
3
+ "version": "0.9.3",
4
4
  "description": "Preview-first command line operations for Structured Doc Editor documents",
5
5
  "type": "module",
6
6
  "bin": {