@superdoc-dev/cli 0.5.0-next.15 → 0.5.0-next.16

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/dist/index.js CHANGED
@@ -141,6 +141,7 @@ function parseGlobalArgs(argv) {
141
141
  let prettyFlag = false;
142
142
  let timeoutMs;
143
143
  let sessionId;
144
+ let quiet = false;
144
145
  let help = false;
145
146
  let version2 = false;
146
147
  const rest = [];
@@ -162,6 +163,10 @@ function parseGlobalArgs(argv) {
162
163
  help = true;
163
164
  continue;
164
165
  }
166
+ if (token === "--quiet") {
167
+ quiet = true;
168
+ continue;
169
+ }
165
170
  if (token === "--version" || token === "-v") {
166
171
  version2 = true;
167
172
  continue;
@@ -221,6 +226,7 @@ function parseGlobalArgs(argv) {
221
226
  output,
222
227
  timeoutMs,
223
228
  sessionId,
229
+ quiet,
224
230
  help,
225
231
  version: version2
226
232
  },
@@ -42278,6 +42284,42 @@ var init_cli_only_operation_definitions = __esm(() => {
42278
42284
  required: ["contextId", "closed"]
42279
42285
  }
42280
42286
  },
42287
+ insertTab: {
42288
+ category: "core",
42289
+ description: "Insert a real Word tab node at a collapsed text insertion point. Accepts the same target/ref shortcuts as insert, but only for point inserts.",
42290
+ requiresDocumentContext: false,
42291
+ tokenOverride: ["insert", "tab"],
42292
+ sdkMetadata: { mutates: true, idempotency: "non-idempotent", supportsTrackedMode: false, supportsDryRun: false },
42293
+ outputSchema: {
42294
+ type: "object",
42295
+ properties: {
42296
+ document: { type: "object" },
42297
+ receipt: { type: "object" },
42298
+ inserted: { type: "object" },
42299
+ context: { type: "object" },
42300
+ output: { type: "object" }
42301
+ },
42302
+ required: ["receipt", "inserted"]
42303
+ }
42304
+ },
42305
+ insertLineBreak: {
42306
+ category: "core",
42307
+ description: "Insert a real Word line-break node at a collapsed text insertion point. Accepts the same target/ref shortcuts as insert, but only for point inserts.",
42308
+ requiresDocumentContext: false,
42309
+ tokenOverride: ["insert", "line-break"],
42310
+ sdkMetadata: { mutates: true, idempotency: "non-idempotent", supportsTrackedMode: false, supportsDryRun: false },
42311
+ outputSchema: {
42312
+ type: "object",
42313
+ properties: {
42314
+ document: { type: "object" },
42315
+ receipt: { type: "object" },
42316
+ inserted: { type: "object" },
42317
+ context: { type: "object" },
42318
+ output: { type: "object" }
42319
+ },
42320
+ required: ["receipt", "inserted"]
42321
+ }
42322
+ },
42281
42323
  status: {
42282
42324
  category: "session",
42283
42325
  description: "Show the current session status and document metadata.",
@@ -42482,6 +42524,8 @@ var init_types4 = __esm(() => {
42482
42524
  "open",
42483
42525
  "save",
42484
42526
  "close",
42527
+ "insertTab",
42528
+ "insertLineBreak",
42485
42529
  "status",
42486
42530
  "describe",
42487
42531
  "describeCommand",
@@ -172449,7 +172493,7 @@ var init_remark_gfm_CjV8kaUy_es = __esm(() => {
172449
172493
  init_remark_gfm_z_sDF4ss_es();
172450
172494
  });
172451
172495
 
172452
- // ../../packages/superdoc/dist/chunks/src-sOP3agXO.es.js
172496
+ // ../../packages/superdoc/dist/chunks/src-CeG3wOI4.es.js
172453
172497
  function deleteProps(obj, propOrProps) {
172454
172498
  const props = typeof propOrProps === "string" ? [propOrProps] : propOrProps;
172455
172499
  const removeNested = (target, pathParts, index2 = 0) => {
@@ -243359,11 +243403,16 @@ var Node$13 = class Node$14 {
243359
243403
  });
243360
243404
  return Object.fromEntries(markEntries);
243361
243405
  }
243362
- }, Commands, handleEnter = (editor) => {
243406
+ }, Commands, dispatchHistoryBoundary = (view) => {
243407
+ const tr = view?.state?.tr;
243408
+ if (!tr)
243409
+ return;
243410
+ view.dispatch?.(closeHistory(tr));
243411
+ }, handleEnter = (editor) => {
243363
243412
  const { view } = editor;
243364
- view?.dispatch?.(closeHistory(view?.state?.tr));
243413
+ dispatchHistoryBoundary(view);
243365
243414
  return editor.commands.first(({ commands: commands$1 }) => [
243366
- () => commands$1.splitRunToParagraph(),
243415
+ () => commands$1.splitRunToParagraph?.() ?? false,
243367
243416
  () => commands$1.newlineInCode(),
243368
243417
  () => commands$1.createParagraphNear(),
243369
243418
  () => commands$1.liftEmptyBlock(),
@@ -243371,7 +243420,7 @@ var Node$13 = class Node$14 {
243371
243420
  ]);
243372
243421
  }, handleBackspace = (editor) => {
243373
243422
  const { view } = editor;
243374
- view?.dispatch?.(closeHistory(view?.state?.tr));
243423
+ dispatchHistoryBoundary(view);
243375
243424
  return editor.commands.first(({ commands: commands$1, tr }) => [
243376
243425
  () => commands$1.undoInputRule(),
243377
243426
  () => {
@@ -243389,7 +243438,7 @@ var Node$13 = class Node$14 {
243389
243438
  ]);
243390
243439
  }, handleDelete2 = (editor) => {
243391
243440
  const { view } = editor;
243392
- view?.dispatch?.(closeHistory(view?.state?.tr));
243441
+ dispatchHistoryBoundary(view);
243393
243442
  return editor.commands.first(({ commands: commands$1 }) => [
243394
243443
  () => commands$1.deleteSkipEmptyRun(),
243395
243444
  () => commands$1.deleteNextToRun(),
@@ -253853,7 +253902,7 @@ var Node$13 = class Node$14 {
253853
253902
  return;
253854
253903
  console.log(...args$1);
253855
253904
  }, HEADER_FOOTER_INIT_BUDGET_MS = 200, MAX_ZOOM_WARNING_THRESHOLD = 10, MAX_SELECTION_RECTS_PER_USER = 100, SEMANTIC_RESIZE_DEBOUNCE_MS = 120, MIN_SEMANTIC_CONTENT_WIDTH_PX = 1, GLOBAL_PERFORMANCE, PresentationEditor, ICONS, TEXTS, tableActionsOptions;
253856
- var init_src_sOP3agXO_es = __esm(() => {
253905
+ var init_src_CeG3wOI4_es = __esm(() => {
253857
253906
  init_rolldown_runtime_B2q5OVn9_es();
253858
253907
  init_SuperConverter_CMIR0kxi_es();
253859
253908
  init_jszip_ChlR43oI_es();
@@ -287805,7 +287854,7 @@ var init_zipper_YmNpPIyc_es = __esm(() => {
287805
287854
 
287806
287855
  // ../../packages/superdoc/dist/super-editor.es.js
287807
287856
  var init_super_editor_es = __esm(() => {
287808
- init_src_sOP3agXO_es();
287857
+ init_src_CeG3wOI4_es();
287809
287858
  init_SuperConverter_CMIR0kxi_es();
287810
287859
  init_jszip_ChlR43oI_es();
287811
287860
  init_xml_js_40FWvL78_es();
@@ -336225,6 +336274,25 @@ async function getFileChecksum(path2) {
336225
336274
  }
336226
336275
  return createHash2("sha256").update(bytes).digest("hex");
336227
336276
  }
336277
+ async function exportOptionalSessionOutput(editor, io, outPath, force) {
336278
+ if (!outPath)
336279
+ return;
336280
+ try {
336281
+ return { output: await exportToPath(editor, outPath, force) };
336282
+ } catch (error4) {
336283
+ const code7 = error4 instanceof CliError ? error4.code : "FILE_WRITE_ERROR";
336284
+ const message = error4 instanceof Error ? error4.message : String(error4);
336285
+ io.warn?.(`[warn] optional export to ${outPath} failed: ${message}
336286
+ `);
336287
+ return {
336288
+ warning: {
336289
+ code: code7,
336290
+ path: outPath,
336291
+ message
336292
+ }
336293
+ };
336294
+ }
336295
+ }
336228
336296
  async function exportToPath(editor, outputPath, force = false) {
336229
336297
  const exists = await pathExists(outputPath);
336230
336298
  if (exists && !force) {
@@ -337892,18 +337960,6 @@ function buildPrettyOutput2(operationId, document2, result2, outputPath) {
337892
337960
  const verb = SUCCESS_VERB[operationId];
337893
337961
  return outputPath ? `Revision ${document2.revision}: ${verb} -> ${outputPath}` : `Revision ${document2.revision}: ${verb}`;
337894
337962
  }
337895
- async function exportOptionalSessionOutput(editor, outPath, force) {
337896
- if (!outPath)
337897
- return;
337898
- try {
337899
- return await exportToPath(editor, outPath, force);
337900
- } catch (error4) {
337901
- const message = error4 instanceof Error ? error4.message : String(error4);
337902
- process.stderr.write(`[warn] optional export to ${outPath} failed: ${message}
337903
- `);
337904
- return;
337905
- }
337906
- }
337907
337963
  async function executeMutationOperation(request) {
337908
337964
  const { operationId, input: input2, context } = request;
337909
337965
  const doc4 = readOptionalString(input2, "doc");
@@ -338014,7 +338070,7 @@ async function executeMutationOperation(request) {
338014
338070
  await writeContextMetadata(paths, updatedMetadata);
338015
338071
  byteLength3 = workingOutput.byteLength;
338016
338072
  }
338017
- const externalOutput = await exportOptionalSessionOutput(opened.editor, outPath, force);
338073
+ const externalOutput = await exportOptionalSessionOutput(opened.editor, context.io, outPath, force);
338018
338074
  const document2 = {
338019
338075
  path: updatedMetadata.sourcePath,
338020
338076
  source: updatedMetadata.source,
@@ -338027,9 +338083,16 @@ async function executeMutationOperation(request) {
338027
338083
  changeMode,
338028
338084
  dryRun: false,
338029
338085
  context: { dirty: updatedMetadata.dirty, revision: updatedMetadata.revision },
338030
- output: externalOutput
338086
+ output: externalOutput?.output ?? (externalOutput?.warning ? {
338087
+ path: externalOutput.warning.path,
338088
+ failed: true,
338089
+ error: {
338090
+ code: externalOutput.warning.code,
338091
+ message: externalOutput.warning.message
338092
+ }
338093
+ } : undefined)
338031
338094
  }),
338032
- pretty: buildPrettyOutput2(operationId, document2, result2, externalOutput?.path)
338095
+ pretty: buildPrettyOutput2(operationId, document2, result2, externalOutput?.output?.path)
338033
338096
  };
338034
338097
  } finally {
338035
338098
  opened.dispose();
@@ -338352,7 +338415,8 @@ var init_command_examples = __esm(() => {
338352
338415
  insert: [
338353
338416
  'superdoc insert --value "Hello, world!"',
338354
338417
  'superdoc insert --block-id abc123 --value "Appended text"',
338355
- 'superdoc insert --type markdown --value "## New Section"'
338418
+ 'superdoc insert --type markdown --value "## New Section"',
338419
+ 'superdoc insert --block-id abc123 --offset 5 --type html --value "<br/>"'
338356
338420
  ],
338357
338421
  replace: [
338358
338422
  'superdoc replace --block-id abc123 --start 0 --end 5 --text "Updated"',
@@ -338412,7 +338476,10 @@ var init_command_examples = __esm(() => {
338412
338476
  "lists.setType": [
338413
338477
  `superdoc lists set-type --target-json '{"kind":"block","nodeType":"listItem","nodeId":"abc123"}' --kind bullet`
338414
338478
  ],
338415
- "format.apply": [`superdoc format apply --block-id abc123 --start 0 --end 10 --inline-json '{"bold":true}'`],
338479
+ "format.apply": [
338480
+ `superdoc format apply --block-id abc123 --start 0 --end 10 --inline-json '{"bold":true}'`,
338481
+ `superdoc format apply --block-id abc123 --start 7 --end 14 --inline-json '{"fontSize":16,"fontFamily":"Times New Roman"}'`
338482
+ ],
338416
338483
  "comments.create": ['superdoc comments create --block-id abc123 --start 0 --end 5 --text "Review this section"'],
338417
338484
  "comments.list": ["superdoc comments list"],
338418
338485
  "comments.get": ["superdoc comments get --id comment-123"],
@@ -338425,7 +338492,8 @@ var init_command_examples = __esm(() => {
338425
338492
  "history.undo": ["superdoc history undo"],
338426
338493
  "history.redo": ["superdoc history redo"],
338427
338494
  "mutations.apply": [
338428
- `superdoc mutations apply --atomic true --change-mode direct --steps-json '[{"id":"s1","op":"text.rewrite","where":{"by":"select","select":{"type":"text","pattern":"old"},"require":"first"},"args":{"replacement":{"text":"new"}}}]'`
338495
+ `superdoc mutations apply --atomic true --change-mode direct --steps-json '[{"id":"s1","op":"text.rewrite","where":{"by":"select","select":{"type":"text","pattern":"old"},"require":"first"},"args":{"replacement":{"text":"new"}}}]'`,
338496
+ `superdoc mutations apply --atomic true --change-mode direct --steps-json '[{"id":"s1","op":"text.insert","where":{"by":"target","target":{"kind":"selection","start":{"kind":"text","blockId":"abc123","offset":0},"end":{"kind":"text","blockId":"abc123","offset":0}}},"args":{"position":"before","content":{"text":"ALPHA01 "}}},{"id":"s2","op":"format.apply","where":{"by":"target","target":{"kind":"selection","start":{"kind":"text","blockId":"abc123","offset":8},"end":{"kind":"text","blockId":"abc123","offset":15}}},"args":{"inline":{"fontSize":16,"fontFamily":"Times New Roman"}}}]'`
338429
338497
  ],
338430
338498
  "mutations.preview": [
338431
338499
  `superdoc mutations preview --atomic true --change-mode direct --steps-json '[{"id":"s1","op":"text.rewrite","where":{"by":"select","select":{"type":"text","pattern":"old"},"require":"first"},"args":{"replacement":{"text":"new"}}}]'`
@@ -338491,9 +338559,11 @@ function buildHelpText() {
338491
338559
  const lines = ["Usage: superdoc <command> [options]", ""];
338492
338560
  lines.push("Common tasks:");
338493
338561
  lines.push(" Find mutation target → query match");
338562
+ lines.push(" Seed a synthetic doc → open --content-override ...");
338494
338563
  lines.push(" Insert between list items → lists insert");
338495
338564
  lines.push(" Create a paragraph → create paragraph");
338496
338565
  lines.push(" Insert inline text → insert");
338566
+ lines.push(" Insert a real tab → insert tab");
338497
338567
  lines.push(" Batch formatting changes → mutations apply");
338498
338568
  lines.push("");
338499
338569
  const categories = new Map;
@@ -338540,9 +338610,30 @@ var init_commands = __esm(() => {
338540
338610
  init_command_examples();
338541
338611
  init_operation_set();
338542
338612
  CLI_ONLY_OVERRIDES = {
338543
- open: { mutates: true, examples: ["superdoc open my-doc.docx", "superdoc open my-doc.docx --session my-session"] },
338613
+ open: {
338614
+ mutates: true,
338615
+ examples: [
338616
+ "superdoc open my-doc.docx",
338617
+ 'superdoc open --content-override "# Title\\n\\nBody text" --override-type markdown',
338618
+ "superdoc open template.docx --content-override '<p>ALPHA01</p><p>BRAVO02</p>' --override-type html"
338619
+ ]
338620
+ },
338544
338621
  save: { mutates: true, examples: ["superdoc save", "superdoc save --out copy.docx"] },
338545
338622
  close: { mutates: true, examples: ["superdoc close"] },
338623
+ insertTab: {
338624
+ mutates: true,
338625
+ examples: [
338626
+ "superdoc insert tab --block-id abc123 --offset 5",
338627
+ `superdoc insert tab --target-json '{"kind":"selection","start":{"kind":"text","blockId":"abc123","offset":5},"end":{"kind":"text","blockId":"abc123","offset":5}}'`
338628
+ ]
338629
+ },
338630
+ insertLineBreak: {
338631
+ mutates: true,
338632
+ examples: [
338633
+ "superdoc insert line-break --block-id abc123 --offset 5",
338634
+ `superdoc insert line-break --target-json '{"kind":"selection","start":{"kind":"text","blockId":"abc123","offset":5},"end":{"kind":"text","blockId":"abc123","offset":5}}'`
338635
+ ]
338636
+ },
338546
338637
  status: { mutates: false, examples: ["superdoc status"] },
338547
338638
  describe: { mutates: false, examples: ["superdoc describe"] },
338548
338639
  describeCommand: { mutates: false, examples: ["superdoc describe command find"] },
@@ -338945,7 +339036,7 @@ function deriveOptionSpecs(operationId, params4) {
338945
339036
  }
338946
339037
  return specs;
338947
339038
  }
338948
- var DOC_PARAM, SESSION_PARAM, OUT_PARAM, FORCE_PARAM, DRY_RUN_PARAM, CHANGE_MODE_PARAM, EXPECTED_REVISION_PARAM, USER_NAME_PARAM, USER_EMAIL_PARAM, PASSWORD_PARAM, AGENT_HIDDEN_PARAM_NAMES, OPERATION_CONSTRAINTS, PARAM_FLAG_OVERRIDES, DOC_FIND_SELECT_SCHEMA, PARAM_SCHEMA_OVERRIDES, PARAM_EXCLUSIONS, TEXT_TARGET_FLAT_PARAMS, TEXT_TARGET_FLAT_PARAMS_AGENT_HIDDEN, LIST_TARGET_FLAT_PARAMS, FORMAT_OPERATION_IDS, EXTRA_CLI_PARAMS, CLI_ONLY_METADATA, CLI_OPERATION_METADATA, OPTION_FLAG_ALIASES, CLI_OPERATION_OPTION_SPECS;
339039
+ var DOC_PARAM, SESSION_PARAM, OUT_PARAM, FORCE_PARAM, DRY_RUN_PARAM, CHANGE_MODE_PARAM, EXPECTED_REVISION_PARAM, USER_NAME_PARAM, USER_EMAIL_PARAM, PASSWORD_PARAM, AGENT_HIDDEN_PARAM_NAMES, OPERATION_CONSTRAINTS, PARAM_FLAG_OVERRIDES, DOC_FIND_SELECT_SCHEMA, PARAM_SCHEMA_OVERRIDES, PARAM_EXCLUSIONS, TEXT_TARGET_FLAT_PARAMS, TEXT_TARGET_FLAT_PARAMS_AGENT_HIDDEN, SELECTION_TARGET_JSON_PARAM, INSERT_REF_PARAM, LIST_TARGET_FLAT_PARAMS, FORMAT_OPERATION_IDS, EXTRA_CLI_PARAMS, CLI_ONLY_METADATA, CLI_OPERATION_METADATA, OPTION_FLAG_ALIASES, CLI_OPERATION_OPTION_SPECS;
338949
339040
  var init_operation_params = __esm(() => {
338950
339041
  init_src();
338951
339042
  init_commands();
@@ -339091,6 +339182,19 @@ var init_operation_params = __esm(() => {
339091
339182
  ...p4,
339092
339183
  agentVisible: false
339093
339184
  }));
339185
+ SELECTION_TARGET_JSON_PARAM = {
339186
+ name: "target",
339187
+ kind: "jsonFlag",
339188
+ flag: "target-json",
339189
+ type: "json",
339190
+ description: "Collapsed text insertion point as SelectionTarget JSON."
339191
+ };
339192
+ INSERT_REF_PARAM = {
339193
+ name: "ref",
339194
+ kind: "flag",
339195
+ type: "string",
339196
+ description: "Mutation-ready ref returned by query.match or ranges.resolve."
339197
+ };
339094
339198
  LIST_TARGET_FLAT_PARAMS = [
339095
339199
  { name: "nodeId", kind: "flag", flag: "node-id", type: "string", description: "Node ID of the target list item." }
339096
339200
  ];
@@ -339594,6 +339698,54 @@ var init_operation_params = __esm(() => {
339594
339698
  params: [SESSION_PARAM, { name: "discard", kind: "flag", type: "boolean" }],
339595
339699
  constraints: null
339596
339700
  },
339701
+ "doc.insertTab": {
339702
+ command: "insert tab",
339703
+ positionalParams: ["doc"],
339704
+ docRequirement: "none",
339705
+ params: [
339706
+ DOC_PARAM,
339707
+ SESSION_PARAM,
339708
+ OUT_PARAM,
339709
+ FORCE_PARAM,
339710
+ EXPECTED_REVISION_PARAM,
339711
+ SELECTION_TARGET_JSON_PARAM,
339712
+ INSERT_REF_PARAM,
339713
+ ...TEXT_TARGET_FLAT_PARAMS,
339714
+ {
339715
+ name: "offset",
339716
+ kind: "flag",
339717
+ type: "number",
339718
+ description: "Character offset for insertion (alias for --start/--end with the same value)."
339719
+ }
339720
+ ],
339721
+ constraints: {
339722
+ mutuallyExclusive: [["target", "ref"]]
339723
+ }
339724
+ },
339725
+ "doc.insertLineBreak": {
339726
+ command: "insert line-break",
339727
+ positionalParams: ["doc"],
339728
+ docRequirement: "none",
339729
+ params: [
339730
+ DOC_PARAM,
339731
+ SESSION_PARAM,
339732
+ OUT_PARAM,
339733
+ FORCE_PARAM,
339734
+ EXPECTED_REVISION_PARAM,
339735
+ SELECTION_TARGET_JSON_PARAM,
339736
+ INSERT_REF_PARAM,
339737
+ ...TEXT_TARGET_FLAT_PARAMS,
339738
+ {
339739
+ name: "offset",
339740
+ kind: "flag",
339741
+ type: "number",
339742
+ description: "Character offset for insertion (alias for --start/--end with the same value)."
339743
+ }
339744
+ ],
339745
+ constraints: {
339746
+ mutuallyExclusive: [["target", "ref"]]
339747
+ }
339748
+ },
339597
339749
  "doc.status": {
339598
339750
  command: "status",
339599
339751
  positionalParams: [],
@@ -340900,6 +341052,261 @@ var init_close = __esm(() => {
340900
341052
  init_context();
340901
341053
  });
340902
341054
 
341055
+ // src/commands/insert-inline-special.ts
341056
+ function isRecord7(value2) {
341057
+ return typeof value2 === "object" && value2 != null && !Array.isArray(value2);
341058
+ }
341059
+ function isSelectionTarget3(value2) {
341060
+ return isRecord7(value2) && value2.kind === "selection" && isRecord7(value2.start) && isRecord7(value2.end);
341061
+ }
341062
+ function isCollapsedTextSelectionTarget(target2) {
341063
+ return target2.start.kind === "text" && target2.end.kind === "text" && target2.start.blockId === target2.end.blockId && target2.start.offset === target2.end.offset;
341064
+ }
341065
+ function buildPrettyOutput3(kind2, revision, outputPath) {
341066
+ const label2 = COMMAND_BY_KIND[kind2].label;
341067
+ return outputPath ? `Revision ${revision}: inserted ${label2} -> ${outputPath}` : `Revision ${revision}: inserted ${label2}`;
341068
+ }
341069
+ async function resolveInsertionPoint(editor, input2, kind2) {
341070
+ const apiInput = extractInvokeInput("insert", input2);
341071
+ if (!isRecord7(apiInput)) {
341072
+ throw new CliError("INVALID_ARGUMENT", `insert ${COMMAND_BY_KIND[kind2].label}: invalid target input.`);
341073
+ }
341074
+ const ref4 = typeof apiInput.ref === "string" ? apiInput.ref : undefined;
341075
+ const rawTarget = apiInput.target;
341076
+ if (ref4) {
341077
+ const resolved = editor.doc.invoke({
341078
+ operationId: "ranges.resolve",
341079
+ input: {
341080
+ start: { kind: "ref", ref: ref4, boundary: "start" },
341081
+ end: { kind: "ref", ref: ref4, boundary: "start" }
341082
+ }
341083
+ });
341084
+ if (!isSelectionTarget3(resolved?.target) || !isCollapsedTextSelectionTarget(resolved.target)) {
341085
+ throw new CliError("INVALID_TARGET", `insert ${COMMAND_BY_KIND[kind2].label}: ref must resolve to a collapsed text insertion point.`);
341086
+ }
341087
+ const collapsedTarget = {
341088
+ kind: "text",
341089
+ blockId: resolved.target.start.blockId,
341090
+ range: { start: resolved.target.start.offset, end: resolved.target.start.offset }
341091
+ };
341092
+ const resolvedRange = resolveSelectionTarget(editor, resolved.target);
341093
+ return {
341094
+ target: collapsedTarget,
341095
+ range: { from: resolvedRange.absFrom, to: resolvedRange.absTo }
341096
+ };
341097
+ }
341098
+ if (rawTarget !== undefined) {
341099
+ if (!isSelectionTarget3(rawTarget)) {
341100
+ throw new CliError("INVALID_TARGET", `insert ${COMMAND_BY_KIND[kind2].label}: target must be a collapsed text selection.`);
341101
+ }
341102
+ const selectionTarget = rawTarget;
341103
+ if (!isCollapsedTextSelectionTarget(selectionTarget)) {
341104
+ throw new CliError("INVALID_TARGET", `insert ${COMMAND_BY_KIND[kind2].label}: target must be a collapsed text selection.`);
341105
+ }
341106
+ const resolvedRange = resolveSelectionTarget(editor, selectionTarget);
341107
+ return {
341108
+ target: {
341109
+ kind: "text",
341110
+ blockId: selectionTarget.start.blockId,
341111
+ range: { start: selectionTarget.start.offset, end: selectionTarget.start.offset }
341112
+ },
341113
+ range: { from: resolvedRange.absFrom, to: resolvedRange.absTo }
341114
+ };
341115
+ }
341116
+ const fallback = resolveDefaultInsertTarget(editor);
341117
+ if (!fallback) {
341118
+ throw new CliError("TARGET_NOT_FOUND", `insert ${COMMAND_BY_KIND[kind2].label}: no writable text block is available. Pass an explicit collapsed text target.`);
341119
+ }
341120
+ if (fallback.kind === "structural-end") {
341121
+ return {
341122
+ kind: "structural-end",
341123
+ target: { kind: "text", blockId: "", range: { start: 0, end: 0 } },
341124
+ insertPos: fallback.insertPos
341125
+ };
341126
+ }
341127
+ return {
341128
+ kind: "text-block",
341129
+ target: fallback.target,
341130
+ range: fallback.range
341131
+ };
341132
+ }
341133
+ function executeInlineSpecialInsert(editor, kind2, insertionPoint) {
341134
+ const commandName = kind2 === "tab" ? "insertTabNode" : "insertLineBreak";
341135
+ const commands2 = editor.commands;
341136
+ const command2 = commands2?.[commandName];
341137
+ if (typeof command2 !== "function") {
341138
+ throw new CliError("CAPABILITY_UNAVAILABLE", `insert ${COMMAND_BY_KIND[kind2].label}: ${commandName} is unavailable.`);
341139
+ }
341140
+ let chain = editor.chain();
341141
+ if (insertionPoint.kind === "structural-end") {
341142
+ if (typeof commands2?.insertParagraphAt !== "function") {
341143
+ throw new CliError("CAPABILITY_UNAVAILABLE", `insert ${COMMAND_BY_KIND[kind2].label}: insertParagraphAt is unavailable.`);
341144
+ }
341145
+ chain = chain.insertParagraphAt({ pos: insertionPoint.insertPos, tracked: false }).setTextSelection({ from: insertionPoint.insertPos + 1, to: insertionPoint.insertPos + 1 });
341146
+ } else {
341147
+ const { from: from5, to } = insertionPoint.range;
341148
+ if (from5 !== to) {
341149
+ throw new CliError("INVALID_TARGET", `insert ${COMMAND_BY_KIND[kind2].label}: target must be collapsed to a single insertion point.`);
341150
+ }
341151
+ chain = chain.setMeta("inputType", "programmatic").setMeta("skipTrackChanges", true).setTextSelection({ from: from5, to });
341152
+ }
341153
+ chain = kind2 === "tab" ? chain.insertTabNode() : chain.insertLineBreak();
341154
+ if (chain.run() !== true) {
341155
+ throw new CliError("COMMAND_FAILED", `insert ${COMMAND_BY_KIND[kind2].label}: editor command returned false.`);
341156
+ }
341157
+ }
341158
+ function buildSuccessData(kind2, document2, target2, revision, output) {
341159
+ return {
341160
+ document: document2,
341161
+ receipt: {
341162
+ success: true,
341163
+ resolution: {
341164
+ target: target2
341165
+ }
341166
+ },
341167
+ inserted: { kind: kind2 },
341168
+ context: { dirty: true, revision },
341169
+ output: output?.output ?? (output?.warning ? {
341170
+ path: output.warning.path,
341171
+ failed: true,
341172
+ error: {
341173
+ code: output.warning.code,
341174
+ message: output.warning.message
341175
+ }
341176
+ } : undefined)
341177
+ };
341178
+ }
341179
+ async function runInsertInlineSpecial(kind2, tokens, context) {
341180
+ const commandSpec = COMMAND_BY_KIND[kind2];
341181
+ const { parsed, help } = parseOperationArgs(commandSpec.operationId, tokens, {
341182
+ commandName: `insert ${kind2 === "tab" ? "tab" : "line-break"}`
341183
+ });
341184
+ if (help || getBooleanOption(parsed, "help")) {
341185
+ return {
341186
+ command: kind2 === "tab" ? "insert tab" : "insert line-break",
341187
+ data: {
341188
+ usage: [
341189
+ `superdoc insert ${kind2 === "tab" ? "tab" : "line-break"} [doc] [--target-json '{...}'|--block-id <id> --offset <n>]`,
341190
+ `superdoc insert ${kind2 === "tab" ? "tab" : "line-break"} [doc] [--ref <ref>] [--out <path>]`
341191
+ ]
341192
+ },
341193
+ pretty: [
341194
+ "Usage:",
341195
+ ` superdoc insert ${kind2 === "tab" ? "tab" : "line-break"} [doc] [--target-json '{...}'|--block-id <id> --offset <n>]`,
341196
+ ` superdoc insert ${kind2 === "tab" ? "tab" : "line-break"} [doc] [--ref <ref>] [--out <path>]`
341197
+ ].join(`
341198
+ `)
341199
+ };
341200
+ }
341201
+ const { doc: doc4 } = resolveDocArg(parsed, `insert ${COMMAND_BY_KIND[kind2].label}`);
341202
+ const outPath = getStringOption(parsed, "out");
341203
+ const force = getBooleanOption(parsed, "force");
341204
+ const expectedRevisionRaw = parsed.options.expectedRevision;
341205
+ const expectedRevision = typeof expectedRevisionRaw === "number" ? expectedRevisionRaw : undefined;
341206
+ const commandName = kind2 === "tab" ? "insert tab" : "insert line-break";
341207
+ const input2 = parsed.options;
341208
+ if (doc4 && expectedRevision != null) {
341209
+ throw new CliError("INVALID_ARGUMENT", `${commandName}: --expected-revision is only supported with an active open context.`);
341210
+ }
341211
+ if (doc4) {
341212
+ if (!outPath) {
341213
+ throw new CliError("MISSING_REQUIRED", `${commandName}: missing required --out.`);
341214
+ }
341215
+ const source = doc4 === "-" ? "stdin" : "path";
341216
+ const opened = await openDocument(doc4, context.io);
341217
+ try {
341218
+ const resolved = await resolveInsertionPoint(opened.editor, input2, kind2);
341219
+ executeInlineSpecialInsert(opened.editor, kind2, resolved);
341220
+ const output = await exportToPath(opened.editor, outPath, force);
341221
+ const document2 = {
341222
+ path: source === "path" ? doc4 : undefined,
341223
+ source,
341224
+ byteLength: opened.meta.byteLength,
341225
+ revision: 0
341226
+ };
341227
+ return {
341228
+ command: commandName,
341229
+ data: buildSuccessData(kind2, document2, resolved.target, 0, { output }),
341230
+ pretty: buildPrettyOutput3(kind2, 0, output.path)
341231
+ };
341232
+ } finally {
341233
+ opened.dispose();
341234
+ }
341235
+ }
341236
+ return withActiveContext(context.io, commandName, async ({ metadata, paths }) => {
341237
+ assertExpectedRevision(metadata, expectedRevision);
341238
+ const isHostMode = context.executionMode === "host" && context.sessionPool != null;
341239
+ const opened = await openSessionDocument(paths.workingDocPath, context.io, metadata, {
341240
+ sessionId: context.sessionId ?? metadata.contextId,
341241
+ executionMode: context.executionMode,
341242
+ sessionPool: context.sessionPool
341243
+ });
341244
+ try {
341245
+ const resolved = await resolveInsertionPoint(opened.editor, input2, kind2);
341246
+ executeInlineSpecialInsert(opened.editor, kind2, resolved);
341247
+ let updatedMetadata;
341248
+ let byteLength3;
341249
+ if (isHostMode) {
341250
+ context.sessionPool.markDirty(metadata.contextId);
341251
+ updatedMetadata = markContextUpdated(context.io, metadata, {
341252
+ dirty: true,
341253
+ revision: metadata.revision + 1
341254
+ });
341255
+ await writeContextMetadata(paths, updatedMetadata);
341256
+ context.sessionPool.updateMetadataRevision(metadata.contextId, updatedMetadata.revision);
341257
+ byteLength3 = opened.meta.byteLength;
341258
+ } else if (metadata.sessionType === "collab") {
341259
+ const synced = await syncCollaborativeSessionSnapshot(context.io, metadata, paths, opened.editor);
341260
+ updatedMetadata = synced.updatedMetadata;
341261
+ byteLength3 = synced.output.byteLength;
341262
+ } else {
341263
+ const workingOutput = await exportToPath(opened.editor, paths.workingDocPath, true);
341264
+ updatedMetadata = markContextUpdated(context.io, metadata, {
341265
+ dirty: true,
341266
+ revision: metadata.revision + 1
341267
+ });
341268
+ await writeContextMetadata(paths, updatedMetadata);
341269
+ byteLength3 = workingOutput.byteLength;
341270
+ }
341271
+ const externalOutput = await exportOptionalSessionOutput(opened.editor, context.io, outPath, force);
341272
+ const document2 = {
341273
+ path: updatedMetadata.sourcePath,
341274
+ source: updatedMetadata.source,
341275
+ byteLength: byteLength3,
341276
+ revision: updatedMetadata.revision
341277
+ };
341278
+ return {
341279
+ command: commandName,
341280
+ data: buildSuccessData(kind2, document2, resolved.target, updatedMetadata.revision, externalOutput),
341281
+ pretty: buildPrettyOutput3(kind2, updatedMetadata.revision, externalOutput?.output?.path)
341282
+ };
341283
+ } finally {
341284
+ opened.dispose();
341285
+ }
341286
+ }, context.sessionId, context.executionMode);
341287
+ }
341288
+ function runInsertTab(tokens, context) {
341289
+ return runInsertInlineSpecial("tab", tokens, context);
341290
+ }
341291
+ function runInsertLineBreak(tokens, context) {
341292
+ return runInsertInlineSpecial("lineBreak", tokens, context);
341293
+ }
341294
+ var COMMAND_BY_KIND;
341295
+ var init_insert_inline_special = __esm(() => {
341296
+ init_super_editor_es();
341297
+ init_args();
341298
+ init_context();
341299
+ init_document();
341300
+ init_errors();
341301
+ init_invoke_input();
341302
+ init_operation_args();
341303
+ init_session_collab();
341304
+ COMMAND_BY_KIND = {
341305
+ tab: { operationId: "doc.insertTab", label: "tab" },
341306
+ lineBreak: { operationId: "doc.insertLineBreak", label: "line break" }
341307
+ };
341308
+ });
341309
+
340903
341310
  // src/lib/open-password.ts
340904
341311
  function resolvePassword(explicit, allowEnvFallback = true) {
340905
341312
  if (explicit != null)
@@ -341429,6 +341836,7 @@ function getLegacyRunner(operationId) {
341429
341836
  var LEGACY_RUNNERS;
341430
341837
  var init_legacy_operation_dispatch = __esm(() => {
341431
341838
  init_close();
341839
+ init_insert_inline_special();
341432
341840
  init_open();
341433
341841
  init_save();
341434
341842
  init_session_close();
@@ -341439,6 +341847,8 @@ var init_legacy_operation_dispatch = __esm(() => {
341439
341847
  "doc.open": runOpen,
341440
341848
  "doc.save": runSave,
341441
341849
  "doc.close": runClose,
341850
+ "doc.insertTab": runInsertTab,
341851
+ "doc.insertLineBreak": runInsertLineBreak,
341442
341852
  "doc.session.list": runSessionList,
341443
341853
  "doc.session.save": runSessionSave,
341444
341854
  "doc.session.close": runSessionClose,
@@ -341454,6 +341864,8 @@ var init_manual_command_allowlist = __esm(() => {
341454
341864
  "open",
341455
341865
  "save",
341456
341866
  "close",
341867
+ "insert tab",
341868
+ "insert line-break",
341457
341869
  "session list",
341458
341870
  "session save",
341459
341871
  "session close",
@@ -341464,6 +341876,8 @@ var init_manual_command_allowlist = __esm(() => {
341464
341876
  "doc.open",
341465
341877
  "doc.save",
341466
341878
  "doc.close",
341879
+ "doc.insertTab",
341880
+ "doc.insertLineBreak",
341467
341881
  "doc.session.list",
341468
341882
  "doc.session.save",
341469
341883
  "doc.session.close",
@@ -347595,35 +348009,61 @@ var init_uninstall = __esm(() => {
347595
348009
  import { readFileSync } from "node:fs";
347596
348010
  import { dirname as dirname3, resolve as resolve3 } from "node:path";
347597
348011
  import { fileURLToPath as fileURLToPath2 } from "node:url";
347598
- function resolveCliPackagePath() {
347599
- const __filename3 = fileURLToPath2(import.meta.url);
347600
- const __dirname3 = dirname3(__filename3);
347601
- return resolve3(__dirname3, "../../package.json");
348012
+ function parsePackageJson(rawPackageJson) {
348013
+ try {
348014
+ return JSON.parse(rawPackageJson);
348015
+ } catch {
348016
+ return null;
348017
+ }
348018
+ }
348019
+ function isSupportedCliPackageName(name2) {
348020
+ return typeof name2 === "string" && (name2 === CLI_PACKAGE_NAME || name2.startsWith(`${CLI_PACKAGE_NAME}-`));
348021
+ }
348022
+ function resolveCliPackagePath(moduleUrl) {
348023
+ let currentDir = dirname3(fileURLToPath2(moduleUrl));
348024
+ while (true) {
348025
+ const packageJsonPath = resolve3(currentDir, "package.json");
348026
+ try {
348027
+ const rawPackageJson = readFileSync(packageJsonPath, "utf8");
348028
+ const parsed = parsePackageJson(rawPackageJson);
348029
+ if (isSupportedCliPackageName(parsed?.name)) {
348030
+ return packageJsonPath;
348031
+ }
348032
+ } catch {}
348033
+ const parentDir = dirname3(currentDir);
348034
+ if (parentDir === currentDir) {
348035
+ return null;
348036
+ }
348037
+ currentDir = parentDir;
348038
+ }
347602
348039
  }
347603
348040
  function parsePackageVersion(rawPackageJson) {
348041
+ const parsed = parsePackageJson(rawPackageJson);
348042
+ if (typeof parsed?.version === "string" && parsed.version.length > 0) {
348043
+ return parsed.version;
348044
+ }
348045
+ return null;
348046
+ }
348047
+ function resolveCliPackageVersionFromModuleUrl(moduleUrl) {
347604
348048
  try {
347605
- const parsed = JSON.parse(rawPackageJson);
347606
- if (typeof parsed.version === "string" && parsed.version.length > 0) {
347607
- return parsed.version;
348049
+ const packageJsonPath = resolveCliPackagePath(moduleUrl);
348050
+ if (!packageJsonPath) {
348051
+ return FALLBACK_CLI_PACKAGE_VERSION;
347608
348052
  }
347609
- } catch {}
347610
- return null;
348053
+ const packageJson = readFileSync(packageJsonPath, "utf8");
348054
+ return parsePackageVersion(packageJson) ?? FALLBACK_CLI_PACKAGE_VERSION;
348055
+ } catch {
348056
+ return FALLBACK_CLI_PACKAGE_VERSION;
348057
+ }
347611
348058
  }
347612
348059
  function resolveCliPackageVersion() {
347613
348060
  if (cachedCliPackageVersion) {
347614
348061
  return cachedCliPackageVersion;
347615
348062
  }
347616
- try {
347617
- const packageJson = readFileSync(resolveCliPackagePath(), "utf8");
347618
- const version4 = parsePackageVersion(packageJson);
347619
- cachedCliPackageVersion = version4 ?? FALLBACK_CLI_PACKAGE_VERSION;
347620
- return cachedCliPackageVersion;
347621
- } catch {
347622
- cachedCliPackageVersion = FALLBACK_CLI_PACKAGE_VERSION;
347623
- return cachedCliPackageVersion;
347624
- }
348063
+ cachedCliPackageVersion = resolveCliPackageVersionFromModuleUrl(import.meta.url);
348064
+ return cachedCliPackageVersion;
347625
348065
  }
347626
- var FALLBACK_CLI_PACKAGE_VERSION = "0.0.0", cachedCliPackageVersion = null;
348066
+ var CLI_PACKAGE_NAME = "@superdoc-dev/cli", FALLBACK_CLI_PACKAGE_VERSION = "0.0.0", cachedCliPackageVersion = null;
347627
348067
  var init_version2 = () => {};
347628
348068
 
347629
348069
  // src/host/session-pool.ts
@@ -348212,6 +348652,9 @@ function defaultIo() {
348212
348652
  stderr(message) {
348213
348653
  process.stderr.write(message);
348214
348654
  },
348655
+ warn(message) {
348656
+ process.stderr.write(message);
348657
+ },
348215
348658
  readStdinBytes() {
348216
348659
  if (stdinCache)
348217
348660
  return stdinCache;
@@ -348245,10 +348688,20 @@ function mergeIo(overrides) {
348245
348688
  return {
348246
348689
  stdout: overrides.stdout ?? base5.stdout,
348247
348690
  stderr: overrides.stderr ?? base5.stderr,
348691
+ warn: overrides.warn ?? base5.warn,
348248
348692
  readStdinBytes: overrides.readStdinBytes ?? base5.readStdinBytes,
348249
348693
  now: overrides.now ?? base5.now
348250
348694
  };
348251
348695
  }
348696
+ function applyDiagnosticPolicy(io, globals) {
348697
+ if (globals.output === "pretty" && !globals.quiet) {
348698
+ return io;
348699
+ }
348700
+ return {
348701
+ ...io,
348702
+ warn() {}
348703
+ };
348704
+ }
348252
348705
  function parseCommand(rest) {
348253
348706
  if (rest.length === 0) {
348254
348707
  throw new CliError("MISSING_REQUIRED", "Missing command.");
@@ -348355,7 +348808,8 @@ async function invokeCommand(argv, options2 = {}) {
348355
348808
  const startedAt = io.now();
348356
348809
  const { parsed, output } = await withStateDirOverride(options2.stateDir, async () => {
348357
348810
  const parsedInvocation = parseInvocation(argv);
348358
- const commandOutput = await executeParsedInvocation(parsedInvocation, io, options2.executionMode ?? "oneshot", options2.sessionPool);
348811
+ const runtimeIo = applyDiagnosticPolicy(io, parsedInvocation.globals);
348812
+ const commandOutput = await executeParsedInvocation(parsedInvocation, runtimeIo, options2.executionMode ?? "oneshot", options2.sessionPool);
348359
348813
  return { parsed: parsedInvocation, output: commandOutput };
348360
348814
  });
348361
348815
  return {
@@ -348378,6 +348832,7 @@ async function run2(argv, ioOverrides, options2 = {}) {
348378
348832
  try {
348379
348833
  const parsed = parseInvocation(argv);
348380
348834
  outputMode = parsed.globals.output;
348835
+ const runtimeIo = applyDiagnosticPolicy(io, parsed.globals);
348381
348836
  if (parsed.globals.version && !parsed.globals.help) {
348382
348837
  io.stdout(`${resolveCliPackageVersion()}
348383
348838
  `);
@@ -348404,7 +348859,7 @@ async function run2(argv, ioOverrides, options2 = {}) {
348404
348859
  return legacyCompat.exitCode;
348405
348860
  }
348406
348861
  }
348407
- const output = await executeParsedInvocation(parsed, io, "oneshot");
348862
+ const output = await executeParsedInvocation(parsed, runtimeIo, "oneshot");
348408
348863
  if (output.helpText) {
348409
348864
  io.stdout(output.helpText);
348410
348865
  return 0;
@@ -348436,6 +348891,7 @@ var init_src2 = __esm(async () => {
348436
348891
  init_input_readers();
348437
348892
  init_call();
348438
348893
  init_close();
348894
+ init_insert_inline_special();
348439
348895
  init_open();
348440
348896
  init_session_close();
348441
348897
  init_session_list();
@@ -348468,6 +348924,7 @@ var init_src2 = __esm(async () => {
348468
348924
  " --pretty",
348469
348925
  " --session <id>",
348470
348926
  " --timeout-ms <n>",
348927
+ " --quiet",
348471
348928
  " --help, -h",
348472
348929
  " --version, -v"
348473
348930
  ].join(`
@@ -348475,6 +348932,8 @@ var init_src2 = __esm(async () => {
348475
348932
  MANUAL_COMMANDS = {
348476
348933
  call: runCall,
348477
348934
  close: runClose,
348935
+ "insert line-break": runInsertLineBreak,
348936
+ "insert tab": runInsertTab,
348478
348937
  open: runOpen,
348479
348938
  save: runSave,
348480
348939
  "session list": runSessionList,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@superdoc-dev/cli",
3
- "version": "0.5.0-next.15",
3
+ "version": "0.5.0-next.16",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "superdoc": "./dist/index.js"
@@ -25,20 +25,20 @@
25
25
  "@types/ws": "^8.5.13",
26
26
  "typescript": "^5.9.2",
27
27
  "@superdoc/document-api": "0.0.1",
28
- "@superdoc/pm-adapter": "0.0.0",
28
+ "superdoc": "1.23.0",
29
29
  "@superdoc/super-editor": "0.0.1",
30
- "superdoc": "1.23.0"
30
+ "@superdoc/pm-adapter": "0.0.0"
31
31
  },
32
32
  "module": "src/index.ts",
33
33
  "publishConfig": {
34
34
  "access": "public"
35
35
  },
36
36
  "optionalDependencies": {
37
- "@superdoc-dev/cli-darwin-arm64": "0.5.0-next.15",
38
- "@superdoc-dev/cli-darwin-x64": "0.5.0-next.15",
39
- "@superdoc-dev/cli-windows-x64": "0.5.0-next.15",
40
- "@superdoc-dev/cli-linux-arm64": "0.5.0-next.15",
41
- "@superdoc-dev/cli-linux-x64": "0.5.0-next.15"
37
+ "@superdoc-dev/cli-darwin-arm64": "0.5.0-next.16",
38
+ "@superdoc-dev/cli-darwin-x64": "0.5.0-next.16",
39
+ "@superdoc-dev/cli-linux-x64": "0.5.0-next.16",
40
+ "@superdoc-dev/cli-linux-arm64": "0.5.0-next.16",
41
+ "@superdoc-dev/cli-windows-x64": "0.5.0-next.16"
42
42
  },
43
43
  "scripts": {
44
44
  "predev": "node scripts/ensure-superdoc-build.js",
package/skill/SKILL.md CHANGED
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: editing-docx
2
+ name: superdoc-edit-docx
3
3
  description: Edit, query, and transform Word documents with the SuperDoc CLI v1 operation surface. Use when the user asks to read, search, modify, comment, or review changes in .docx files.
4
4
  ---
5
5
 
@@ -24,7 +24,7 @@ Use `describe command` for per-command args and constraints.
24
24
 
25
25
  ## Preferred Workflows
26
26
 
27
- ### 1) Stateful multi-step edits (recommended)
27
+ ### 1) Edit an existing document (recommended for targeted changes)
28
28
 
29
29
  ```bash
30
30
  superdoc open ./contract.docx
@@ -34,12 +34,51 @@ superdoc save --in-place
34
34
  superdoc close
35
35
  ```
36
36
 
37
- - Always use `query match` (not `find`) to discover mutation targets it returns exact addresses with cardinality guarantees.
37
+ - Use `query match` when you are modifying existing content and need an exact mutation target.
38
38
  - After `open`, commands run against the active/default session when `<doc>` is omitted.
39
39
  - Use `superdoc session list|set-default|save|close` for explicit session control.
40
40
  - `close` on dirty state requires `--discard` or a prior `save`.
41
41
 
42
- ### 2) Stateless one-off reads
42
+ ### 2) Generate or seed a document body (recommended for synthetic/probe docs)
43
+
44
+ Use `open --content-override` when you want to create a new body from Markdown, HTML, or plain text in one step.
45
+
46
+ ```bash
47
+ superdoc open --content-override "# Probe Title\n\nALPHA01" --override-type markdown
48
+ superdoc save --out ./probe.docx
49
+ superdoc close
50
+ ```
51
+
52
+ ```bash
53
+ superdoc open template.docx \
54
+ --content-override '<p>ALPHA01 <strong>BRAVO02</strong><br/>CHARLIE03</p>' \
55
+ --override-type html
56
+ superdoc save --out ./probe.docx
57
+ superdoc close
58
+ ```
59
+
60
+ - `--content-override` is the fastest way to seed paragraphs, headings, lists, and `<br/>` line breaks.
61
+ - Use `--override-type markdown|html|text` explicitly. `open` rejects `--content-override` without it.
62
+ - For generation, do not start with `query match` unless you are modifying content that already exists.
63
+
64
+ ### 3) Generate incrementally, then reuse the insert receipt target
65
+
66
+ When you need deterministic inline formatting after seeding text, insert first, then reuse the returned target block/range.
67
+
68
+ ```bash
69
+ superdoc open
70
+ superdoc insert --value "ALPHA01 BRAVO02 CHARLIE03"
71
+ superdoc format apply --block-id <from-insert-receipt> --start 8 --end 15 --inline-json '{"fontSize":16,"fontFamily":"Times New Roman"}'
72
+ superdoc format apply --block-id <from-insert-receipt> --start 16 --end 25 --inline-json '{"fontSize":10,"fontFamily":"Arial"}'
73
+ superdoc save --out ./probe.docx
74
+ superdoc close
75
+ ```
76
+
77
+ - The insert receipt contains the resolved target under `receipt.resolution.target`.
78
+ - For a simple one-paragraph synthetic doc, direct `--block-id --start --end` formatting is usually shorter than re-querying.
79
+ - Use `query match` again only if later steps need to rediscover content by meaning, not by the range you just created.
80
+
81
+ ### 4) Stateless one-off reads
43
82
 
44
83
  ```bash
45
84
  superdoc get-text ./proposal.docx
@@ -47,7 +86,7 @@ superdoc get-markdown ./proposal.docx
47
86
  superdoc info ./proposal.docx
48
87
  ```
49
88
 
50
- ### 3) Stateless one-off mutations
89
+ ### 5) Stateless one-off mutations
51
90
 
52
91
  ```bash
53
92
  superdoc replace ./proposal.docx \
@@ -58,6 +97,20 @@ superdoc replace ./proposal.docx \
58
97
 
59
98
  - In stateless mode (`<doc>` provided), mutating commands require `--out` unless using `--dry-run`.
60
99
 
100
+ ### 6) Inline special nodes: tabs vs line breaks
101
+
102
+ - `insert line-break` inserts a real Word line break node inside the current paragraph.
103
+ - `insert tab` inserts a real Word tab node inside the current paragraph.
104
+ - Paragraph tab stops are different. Tab stops control layout positions; tab nodes are inline content characters that advance to the next tab stop.
105
+
106
+ ```bash
107
+ superdoc insert line-break --block-id p1 --offset 12
108
+ superdoc insert tab --block-id p1 --offset 12
109
+ ```
110
+
111
+ - Use `format paragraph set-tab-stop` / related paragraph formatting commands when you need the tab stop definitions themselves.
112
+ - Use the inline insert commands when you need actual `w:br` or `w:tab` content in exported DOCX.
113
+
61
114
  ### Safety: preview before apply
62
115
 
63
116
  - Use `--dry-run` to preview any mutation without applying it.
@@ -76,6 +129,7 @@ superdoc replace ./proposal.docx \
76
129
 
77
130
  - Replace text: `replace --target-json '{...}' --text "..."`
78
131
  - Insert inline text: `insert --block-id <id> --offset <n> --value "..."`
132
+ - Insert inline tab/line break nodes: `insert tab`, `insert line-break`
79
133
  - Delete text/node: `delete --target-json '{...}'`
80
134
  - Delete blocks: `blocks delete`, `blocks delete-range`
81
135
  - Batch mutations: `mutations apply --steps-json '[...]' --atomic true --change-mode direct`
@@ -131,8 +185,10 @@ Always supported alongside their `-json` counterpart (use one, not both):
131
185
  ## Output and Global Flags
132
186
 
133
187
  - Default output is JSON envelope.
188
+ - In JSON mode, command results are returned as a JSON envelope.
134
189
  - Use `--pretty` for human-readable output (not supported by `call`).
135
- - Global flags: `--output <json|pretty>`, `--session <id>`, `--timeout-ms <n>`.
190
+ - Use `--quiet` to suppress non-essential warnings in pretty mode.
191
+ - Global flags: `--output <json|pretty>`, `--session <id>`, `--timeout-ms <n>`, `--quiet`.
136
192
  - `<doc>` can be `-` to read DOCX bytes from stdin.
137
193
 
138
194
  ## Legacy Compatibility (Use Sparingly)