@superdoc/cli 0.23.0-next.1

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/README.md ADDED
@@ -0,0 +1,396 @@
1
+ # @superdoc-dev/cli
2
+
3
+ LLM-first CLI for deterministic DOCX operations through SuperDoc's Document API.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install -g @superdoc-dev/cli
9
+ ```
10
+
11
+ The package automatically installs a native binary for your platform via optionalDependencies. Supported platforms:
12
+
13
+ | Platform | Package |
14
+ |----------|---------|
15
+ | macOS (Apple Silicon) | `@superdoc-dev/cli-darwin-arm64` |
16
+ | macOS (Intel) | `@superdoc-dev/cli-darwin-x64` |
17
+ | Linux (x64) | `@superdoc-dev/cli-linux-x64` |
18
+ | Linux (ARM64) | `@superdoc-dev/cli-linux-arm64` |
19
+ | Windows (x64) | `@superdoc-dev/cli-windows-x64` |
20
+
21
+ ## Usage
22
+
23
+ ```bash
24
+ superdoc <command> [options]
25
+ ```
26
+
27
+ ## Getting Started
28
+
29
+ Stateful editing flow (recommended for multi-step edits):
30
+
31
+ ```bash
32
+ superdoc open ./contract.docx
33
+
34
+ # Use query match to find a mutation-grade target
35
+ superdoc query match --select-json '{"type":"text","pattern":"termination"}' --require exactlyOne
36
+
37
+ # Mutate using the returned target
38
+ superdoc replace --target-json '{"kind":"text","blockId":"p1","range":{"start":0,"end":11}}' --text "expiration"
39
+
40
+ superdoc save --in-place
41
+ superdoc close
42
+ ```
43
+
44
+ ## Encrypted Documents
45
+
46
+ Open password-protected `.docx` files with `--password` or the `SUPERDOC_DOC_PASSWORD` env var:
47
+
48
+ ```bash
49
+ # Explicit flag
50
+ superdoc open ./secret.docx --password 'mypassword'
51
+
52
+ # Env var (preferred — avoids password in process listings)
53
+ SUPERDOC_DOC_PASSWORD='mypassword' superdoc open ./secret.docx
54
+
55
+ # Via call
56
+ superdoc call doc.open --input-json '{"doc":"./secret.docx","password":"mypassword"}'
57
+ ```
58
+
59
+ If the password is missing or incorrect, the CLI returns a structured error with one of these codes:
60
+ - `DOCX_PASSWORD_REQUIRED` — encrypted file, no password supplied
61
+ - `DOCX_PASSWORD_INVALID` — wrong password
62
+ - `DOCX_ENCRYPTION_UNSUPPORTED` — recognized but unsupported encryption method
63
+ - `DOCX_DECRYPTION_FAILED` — crypto failure or corrupt data
64
+
65
+ ## Choosing the Right Command
66
+
67
+ ### Which command should I use?
68
+
69
+ | I want to... | Use this command |
70
+ |--------------|------------------|
71
+ | Find a mutation target (block ID, text range) | `query match` |
72
+ | Search/browse document content | `find` |
73
+ | Insert inline text within a block | `insert` |
74
+ | Create a new standalone paragraph | `create paragraph` |
75
+ | Create a new heading | `create heading` |
76
+ | Insert a list item before/after another list item | `lists insert` |
77
+ | Apply formatting to a text range | `format apply` or format helpers (`format bold`, etc.) |
78
+ | Apply multiple changes in one operation | `mutations apply` |
79
+
80
+ ### Mutation targeting workflow
81
+
82
+ Always use `query match` to discover targets before mutating:
83
+
84
+ ```bash
85
+ # Step 1: Find the target
86
+ superdoc query match --select-json '{"type":"text","pattern":"Introduction"}' --require exactlyOne
87
+
88
+ # Step 2: Use the returned address in a mutation
89
+ superdoc replace --block-id <returned-blockId> --start <start> --end <end> --text "Overview"
90
+ ```
91
+
92
+ `find` is for content discovery and inspection. `query match` is for mutation targeting — it returns exact addresses with cardinality guarantees.
93
+
94
+ ### Block-oriented editing workflow
95
+
96
+ Use `blocks list` for ordered inspection, then `blocks delete-range` for contiguous removal:
97
+
98
+ ```bash
99
+ superdoc open ./contract.docx
100
+
101
+ # 1. Inspect block order, IDs, and text previews
102
+ superdoc blocks list --limit 30
103
+
104
+ # 2. Preview the deletion (no mutation, shows what would be removed)
105
+ superdoc blocks delete-range \
106
+ --start-json '{"kind":"block","nodeType":"paragraph","nodeId":"abc123"}' \
107
+ --end-json '{"kind":"block","nodeType":"paragraph","nodeId":"def456"}' \
108
+ --dry-run
109
+
110
+ # 3. Apply the deletion
111
+ superdoc blocks delete-range \
112
+ --start-json '{"kind":"block","nodeType":"paragraph","nodeId":"abc123"}' \
113
+ --end-json '{"kind":"block","nodeType":"paragraph","nodeId":"def456"}'
114
+
115
+ superdoc save --in-place
116
+ ```
117
+
118
+ This replaces the pattern of calling `blocks delete` once per block. A 17-block removal becomes one command.
119
+
120
+ ### Preview-before-apply workflow
121
+
122
+ Use `--dry-run` and `--expected-revision` for safe, auditable mutations:
123
+
124
+ ```bash
125
+ superdoc open ./contract.docx
126
+
127
+ # 1. Check session state
128
+ superdoc status
129
+
130
+ # 2. Find the mutation target
131
+ superdoc query match --select-json '{"type":"text","pattern":"termination"}' --require exactlyOne
132
+
133
+ # 3. Preview the change (validates input, shows what would change, no mutation)
134
+ superdoc replace --block-id p1 --start 0 --end 11 --text "expiration" --dry-run
135
+
136
+ # 4. Apply with revision guard (fails if document changed since preview)
137
+ superdoc replace --block-id p1 --start 0 --end 11 --text "expiration" --expected-revision 1
138
+
139
+ superdoc save --in-place
140
+ ```
141
+
142
+ ### Common mistakes
143
+
144
+ 1. **Do not use `find` output to construct mutation targets.** `find` returns discovery-grade data, not mutation-grade addresses. Use `query match` instead.
145
+ 2. **Do not use `insert --block-id` for sibling block insertion.** `insert` inserts inline text *within* a block. To create a new block adjacent to another, use `create paragraph`, `create heading`, or `lists insert`.
146
+ 3. **Do not use `create paragraph` to continue a list.** If you want to add a list item adjacent to existing list items, use `lists insert`. `create paragraph` creates a standalone (non-list) paragraph.
147
+
148
+ ## Command Index
149
+
150
+ | Category | Commands |
151
+ |----------|----------|
152
+ | query | `find`, `query match`, `get-node`, `get-node-by-id`, `get-text`, `info` |
153
+ | mutation | `insert`, `replace`, `delete`, `blocks delete`, `blocks delete-range`, `blocks list`, `mutations apply`, `mutations preview` |
154
+ | format | `format apply`, `format bold`, `format italic`, `format underline`, `format strikethrough` |
155
+ | create | `create paragraph`, `create heading`, `create table-of-contents` |
156
+ | lists | `lists list`, `lists get`, `lists insert`, `lists create`, `lists attach`, `lists detach`, `lists join`, `lists separate`, `lists set-level`, `lists indent`, `lists outdent`, `lists set-value`, `lists set-type`, `lists convert-to-text` |
157
+ | comments | `comments add`, `comments reply`, `comments delete`, `comments get`, `comments list` |
158
+ | trackChanges | `track-changes list`, `track-changes get`, `track-changes accept`, `track-changes reject`, `track-changes accept-all`, `track-changes reject-all` |
159
+ | history | `history get`, `history undo`, `history redo` |
160
+ | lifecycle | `open`, `save`, `close` |
161
+ | session | `session list`, `session save`, `session close`, `session set-default`, `session use` |
162
+ | introspection | `status`, `describe`, `describe command` |
163
+ | low-level | `call <operationId>` |
164
+ | legacy compat | `search`, `replace-legacy <find> <to> <files...>`, `read` |
165
+
166
+ For full command help and examples, run:
167
+
168
+ ```bash
169
+ superdoc --help
170
+ superdoc describe command <command-name>
171
+ ```
172
+
173
+ ## v1 Breaking Changes
174
+
175
+ This CLI replaces the previous `@superdoc-dev/cli` package surface with the v1 contract-driven command set.
176
+
177
+ | Legacy command | v1 status | Migration |
178
+ |---------------|-----------|-----------|
179
+ | `superdoc replace <find> <to> <files...>` | Renamed to `replace-legacy` | Use `replace-legacy`, or use `query match` + `replace --target-json` for the v1 workflow. |
180
+
181
+ Legacy compatibility is retained for `search`, `read`, and `replace-legacy`.
182
+
183
+ ## Normative Policy
184
+
185
+ - Canonical contract/version metadata comes from `@superdoc/document-api` (`CONTRACT_VERSION`, operation metadata, and schemas).
186
+ - This README is usage guidance for CLI consumers.
187
+ - If guidance here conflicts with `superdoc describe`/`describe command` output or document-api contract exports, those are authoritative.
188
+
189
+ ## Host mode (stdio JSON-RPC)
190
+
191
+ ```bash
192
+ superdoc host --stdio
193
+ ```
194
+
195
+ - Starts a persistent JSON-RPC 2.0 host over newline-delimited stdio frames.
196
+ - Intended for SDK/runtime integrations that need long-lived command execution in a single process.
197
+ - Supported methods:
198
+ - `host.ping`
199
+ - `host.capabilities`
200
+ - `host.describe`
201
+ - `host.describe.command` (requires `params.operationId`)
202
+ - `host.shutdown`
203
+ - `cli.invoke` (executes canonical CLI command semantics)
204
+
205
+ ## API introspection commands
206
+
207
+ ```bash
208
+ superdoc describe
209
+ superdoc describe command doc.find
210
+ superdoc status
211
+ ```
212
+
213
+ - `describe` returns contract + protocol metadata and the operation catalog.
214
+ - `describe command <operationId>` returns one operation definition (inputs, response schema, errors, examples).
215
+ - `status` shows current session status and document metadata.
216
+
217
+ ## Stateful session commands
218
+
219
+ ```bash
220
+ superdoc open ./contract.docx
221
+ superdoc status
222
+ superdoc query match --select-json '{"type":"text","pattern":"termination"}' --require exactlyOne
223
+ superdoc replace --target-json '{...}' --text "Updated clause"
224
+ superdoc save --in-place
225
+ superdoc close
226
+ ```
227
+
228
+ - `open` creates a new session id automatically unless `--session <id>` is provided.
229
+ - If `<doc>` is omitted, commands run against the active default session.
230
+ - Explicit `<doc>` (or `--doc`) always runs in stateless mode and does not use session state.
231
+
232
+ ## Session management
233
+
234
+ ```bash
235
+ superdoc session list
236
+ superdoc session save <sessionId> [--in-place] [--out <path>] [--force]
237
+ superdoc session set-default <sessionId>
238
+ superdoc session use <sessionId>
239
+ superdoc session close <sessionId> [--discard]
240
+ ```
241
+
242
+ ## Read / locate commands
243
+
244
+ ```bash
245
+ superdoc info [<doc>]
246
+ superdoc find [<doc>] --type text --pattern "termination" --limit 5
247
+ superdoc query match [<doc>] --select-json '{"type":"text","pattern":"termination"}' --require exactlyOne
248
+ superdoc get-node [<doc>] --address-json '{"kind":"block","nodeType":"paragraph","nodeId":"p1"}'
249
+ superdoc get-node-by-id [<doc>] --id p1 --node-type paragraph
250
+ ```
251
+
252
+ - `find` returns discovery-grade results for content search and browsing.
253
+ - `query match` returns mutation-grade addresses and text ranges — use this before any mutation.
254
+ - For text queries, use the returned `blocks[].range` as targets for `replace`, `comments add`, and formatting commands.
255
+
256
+ ## Mutating commands
257
+
258
+ ```bash
259
+ superdoc replace [<doc>] --target-json '{...}' --text "Updated text" [--out ./updated.docx]
260
+ superdoc insert [<doc>] --value "New text" [--out ./inserted.docx]
261
+ superdoc blocks delete [<doc>] --node-type paragraph --node-id abc123
262
+ superdoc blocks delete-range --start-json '{"kind":"block",...}' --end-json '{"kind":"block",...}'
263
+ superdoc create paragraph [<doc>] --text "New paragraph" [--at-json '{"kind":"after","target":{"kind":"block","nodeType":"paragraph","nodeId":"p1"}}']
264
+ superdoc lists insert [<doc>] --node-id li1 --position after --text "New item"
265
+ superdoc format bold [<doc>] --target-json '{...}' [--out ./bolded.docx]
266
+ superdoc comments add [<doc>] --block-id p1 --start 0 --end 10 --text "Please revise" [--out ./with-comment.docx]
267
+ ```
268
+
269
+ - In stateless mode (`<doc>` provided), mutating commands require `--out`.
270
+ - In stateful mode (after `open`), mutating commands update the active working document and `--out` is optional.
271
+ - Use `--dry-run` to preview any mutation without applying it.
272
+ - Use `--expected-revision <n>` with stateful mutating commands for optimistic concurrency checks.
273
+
274
+ ## Block inspection
275
+
276
+ ```bash
277
+ superdoc blocks list
278
+ superdoc blocks list --limit 20 --offset 10
279
+ superdoc blocks list --node-types-json '["paragraph","heading"]'
280
+ ```
281
+
282
+ - Returns ordered block metadata: ordinal, nodeId, nodeType, textPreview, isEmpty.
283
+ - Use the returned nodeIds as targets for `blocks delete`, `blocks delete-range`, or other block-oriented commands.
284
+
285
+ ## Low-level invocation
286
+
287
+ ```bash
288
+ superdoc call <operationId> --input-json '{...}'
289
+ ```
290
+
291
+ - Invokes any document-api operation directly with a JSON payload.
292
+
293
+ ## Save command modes
294
+
295
+ ```bash
296
+ superdoc save --in-place
297
+ superdoc save --out ./final.docx
298
+ ```
299
+
300
+ - `save` persists the active session but keeps it open for more edits.
301
+ - If no source path exists (for example stdin-opened docs), `save` requires `--out <path>`.
302
+ - `save --in-place` checks for source-file drift and refuses overwrite unless `--force` is passed.
303
+
304
+ ## Close command modes
305
+
306
+ ```bash
307
+ superdoc close
308
+ superdoc close --discard
309
+ ```
310
+
311
+ - Dirty contexts require explicit `--discard` (or run `save` first, then `close`).
312
+
313
+ ## Output modes
314
+
315
+ - Default: `--output json` (machine-oriented envelope)
316
+ - Human mode: `--output pretty` (or `--pretty`)
317
+
318
+ ```bash
319
+ superdoc info ./contract.docx --output json
320
+ superdoc info ./contract.docx --pretty
321
+ ```
322
+
323
+ ## Global flags
324
+
325
+ - `--output <json|pretty>`
326
+ - `--json`
327
+ - `--pretty`
328
+ - `--session <id>`
329
+ - `--timeout-ms <n>`
330
+ - `--help`
331
+ - `--version`, `-v`
332
+
333
+ ## Input payload flags
334
+
335
+ - `--query-json`, `--query-file` (`find`, `lists list`)
336
+ - `--address-json`, `--address-file` (`get-node`, `lists get`)
337
+ - `--target-json` (mutation commands — no `--target-file` counterpart; use flat flags `--block-id`/`--start`/`--end` as alternative)
338
+ - `--input-json`, `--input-file` (`call`, `create paragraph`)
339
+ - `--at-json`, `--at-file` (`create paragraph`)
340
+
341
+ ## Stdin support
342
+
343
+ Use `-` as `<doc>` to read DOCX bytes from stdin:
344
+
345
+ ```bash
346
+ cat ./contract.docx | superdoc open -
347
+ cat ./contract.docx | superdoc info -
348
+ ```
349
+
350
+ ## JSON envelope contract
351
+
352
+ Normative operation/version metadata comes from `@superdoc/document-api`; use `superdoc describe` for the runtime contract surface.
353
+
354
+ Success:
355
+
356
+ ```json
357
+ {
358
+ "ok": true,
359
+ "command": "find",
360
+ "data": {},
361
+ "meta": {
362
+ "version": "1.0.0",
363
+ "elapsedMs": 42
364
+ }
365
+ }
366
+ ```
367
+
368
+ Error:
369
+
370
+ ```json
371
+ {
372
+ "ok": false,
373
+ "error": {
374
+ "code": "INVALID_TARGET",
375
+ "message": "Expected paragraph:abc123 but found listItem:abc123.",
376
+ "details": {
377
+ "requestedNodeType": "paragraph",
378
+ "actualNodeType": "listItem",
379
+ "nodeId": "abc123",
380
+ "remediation": "Use lists.insert to add an item to a list sequence."
381
+ }
382
+ },
383
+ "meta": {
384
+ "version": "1.0.0",
385
+ "elapsedMs": 8
386
+ }
387
+ }
388
+ ```
389
+
390
+ ## Part of SuperDoc
391
+
392
+ This CLI is part of [SuperDoc](https://github.com/superdoc/docx-editor) — open-source DOCX editing and tooling. Renders, edits, and automates .docx in the browser and on the server.
393
+
394
+ ## License
395
+
396
+ AGPL-3.0 · [Enterprise license available](https://superdoc.dev)
Binary file