politty 0.3.2 → 0.4.0

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.
@@ -1,53 +1,84 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
- //#region \0rolldown/runtime.js
3
- var __create = Object.create;
4
- var __defProp = Object.defineProperty;
5
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
- var __getOwnPropNames = Object.getOwnPropertyNames;
7
- var __getProtoOf = Object.getPrototypeOf;
8
- var __hasOwnProp = Object.prototype.hasOwnProperty;
9
- var __exportAll = (all, no_symbols) => {
10
- let target = {};
11
- for (var name in all) {
12
- __defProp(target, name, {
13
- get: all[name],
14
- enumerable: true
15
- });
16
- }
17
- if (!no_symbols) {
18
- __defProp(target, Symbol.toStringTag, { value: "Module" });
19
- }
20
- return target;
21
- };
22
- var __copyProps = (to, from, except, desc) => {
23
- if (from && typeof from === "object" || typeof from === "function") {
24
- for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
25
- key = keys[i];
26
- if (!__hasOwnProp.call(to, key) && key !== except) {
27
- __defProp(to, key, {
28
- get: ((k) => from[k]).bind(null, key),
29
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
30
- });
31
- }
32
- }
33
- }
34
- return to;
35
- };
36
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
37
- value: mod,
38
- enumerable: true
39
- }) : target, mod));
40
-
41
- //#endregion
42
- const require_schema_extractor = require('../schema-extractor-BU705qpC.cjs');
43
- const require_subcommand_router = require('../subcommand-router-Vf-0w9P4.cjs');
2
+ const require_subcommand_router = require('../subcommand-router-4d1Xbp8B.cjs');
3
+ const require_schema_extractor = require('../schema-extractor-Cv7ipqLS.cjs');
44
4
  let zod = require("zod");
45
5
  let node_util = require("node:util");
46
6
  let node_fs = require("node:fs");
47
- node_fs = __toESM(node_fs);
7
+ node_fs = require_subcommand_router.__toESM(node_fs);
48
8
  let node_path = require("node:path");
49
- node_path = __toESM(node_path);
9
+ node_path = require_subcommand_router.__toESM(node_path);
10
+
11
+ //#region src/docs/types.ts
12
+ /**
13
+ * Environment variable name for update mode
14
+ */
15
+ const UPDATE_GOLDEN_ENV = "POLITTY_DOCS_UPDATE";
16
+ /**
17
+ * All section types in rendering order
18
+ */
19
+ const SECTION_TYPES = [
20
+ "heading",
21
+ "description",
22
+ "usage",
23
+ "arguments",
24
+ "options",
25
+ "subcommands",
26
+ "examples",
27
+ "notes"
28
+ ];
29
+ /**
30
+ * Marker prefix for command section markers in generated documentation
31
+ * Format: <!-- politty:command:<scope>:<type>:start --> ... <!-- politty:command:<scope>:<type>:end -->
32
+ */
33
+ const SECTION_MARKER_PREFIX = "politty:command";
34
+ /**
35
+ * Generate start marker for a command section
36
+ */
37
+ function sectionStartMarker(type, scope) {
38
+ return `<!-- ${SECTION_MARKER_PREFIX}:${scope}:${type}:start -->`;
39
+ }
40
+ /**
41
+ * Generate end marker for a command section
42
+ */
43
+ function sectionEndMarker(type, scope) {
44
+ return `<!-- ${SECTION_MARKER_PREFIX}:${scope}:${type}:end -->`;
45
+ }
46
+ /**
47
+ * Marker prefix for global options sections in generated documentation
48
+ * Format: <!-- politty:global-options:start --> ... <!-- politty:global-options:end -->
49
+ */
50
+ const GLOBAL_OPTIONS_MARKER_PREFIX = "politty:global-options";
51
+ /**
52
+ * Generate start marker for a global options section
53
+ */
54
+ function globalOptionsStartMarker() {
55
+ return `<!-- ${GLOBAL_OPTIONS_MARKER_PREFIX}:start -->`;
56
+ }
57
+ /**
58
+ * Generate end marker for a global options section
59
+ */
60
+ function globalOptionsEndMarker() {
61
+ return `<!-- ${GLOBAL_OPTIONS_MARKER_PREFIX}:end -->`;
62
+ }
63
+ /**
64
+ * Marker prefix for index sections in generated documentation
65
+ * Format: <!-- politty:index:<scope>:start --> ... <!-- politty:index:<scope>:end -->
66
+ */
67
+ const INDEX_MARKER_PREFIX = "politty:index";
68
+ /**
69
+ * Generate start marker for an index section
70
+ */
71
+ function indexStartMarker(scope) {
72
+ return `<!-- ${INDEX_MARKER_PREFIX}:${scope}:start -->`;
73
+ }
74
+ /**
75
+ * Generate end marker for an index section
76
+ */
77
+ function indexEndMarker(scope) {
78
+ return `<!-- ${INDEX_MARKER_PREFIX}:${scope}:end -->`;
79
+ }
50
80
 
81
+ //#endregion
51
82
  //#region src/docs/default-renderers.ts
52
83
  /**
53
84
  * Escape markdown special characters in table cells
@@ -109,15 +140,34 @@ function formatEnvInfo(env) {
109
140
  return ` [env: ${(Array.isArray(env) ? env : [env]).join(", ")}]`;
110
141
  }
111
142
  /**
112
- * Format option flags (uses kebab-case cliName)
143
+ * Resolve placeholder for an option (uses kebab-case cliName)
144
+ */
145
+ function resolvePlaceholder(opt) {
146
+ return opt.placeholder ?? opt.cliName.toUpperCase().replace(/-/g, "_");
147
+ }
148
+ /**
149
+ * Format option name for table display (e.g., `--dry-run` or `--port <PORT>`)
150
+ */
151
+ function formatOptionName(opt) {
152
+ const placeholder = resolvePlaceholder(opt);
153
+ return opt.type === "boolean" ? `\`--${opt.cliName}\`` : `\`--${opt.cliName} <${placeholder}>\``;
154
+ }
155
+ /**
156
+ * Format option flags for list display (uses kebab-case cliName)
113
157
  */
114
158
  function formatOptionFlags(opt) {
115
- const parts = [];
116
- const placeholder = opt.placeholder ?? opt.cliName.toUpperCase().replace(/-/g, "_");
159
+ const placeholder = resolvePlaceholder(opt);
117
160
  const longFlag = opt.type === "boolean" ? `--${opt.cliName}` : `--${opt.cliName} <${placeholder}>`;
118
- if (opt.alias) parts.push(`\`-${opt.alias}\`, \`${longFlag}\``);
119
- else parts.push(`\`${longFlag}\``);
120
- return parts.join("");
161
+ if (opt.alias) return `\`-${opt.alias}\`, \`${longFlag}\``;
162
+ return `\`${longFlag}\``;
163
+ }
164
+ /**
165
+ * Format env variable names for table display
166
+ */
167
+ function formatEnvNames(env) {
168
+ if (!env) return "-";
169
+ if (Array.isArray(env)) return env.map((e) => `\`${e}\``).join(", ");
170
+ return `\`${env}\``;
121
171
  }
122
172
  /**
123
173
  * Render options as markdown table
@@ -145,14 +195,13 @@ function renderOptionsTable(info) {
145
195
  lines.push("|--------|-------|-------------|----------|---------|");
146
196
  }
147
197
  for (const opt of info.options) {
148
- const placeholder = opt.placeholder ?? opt.cliName.toUpperCase().replace(/-/g, "_");
149
- const optionName = opt.type === "boolean" ? `\`--${opt.cliName}\`` : `\`--${opt.cliName} <${placeholder}>\``;
198
+ const optionName = formatOptionName(opt);
150
199
  const alias = opt.alias ? `\`-${opt.alias}\`` : "-";
151
200
  const desc = escapeTableCell$2(opt.description ?? "");
152
201
  const required = opt.required ? "Yes" : "No";
153
202
  const defaultVal = formatDefaultValue$1(opt.defaultValue);
154
203
  if (hasEnv) {
155
- const envNames = opt.env ? Array.isArray(opt.env) ? opt.env.map((e) => `\`${e}\``).join(", ") : `\`${opt.env}\`` : "-";
204
+ const envNames = formatEnvNames(opt.env);
156
205
  lines.push(`| ${optionName} | ${alias} | ${desc} | ${required} | ${defaultVal} | ${envNames} |`);
157
206
  } else lines.push(`| ${optionName} | ${alias} | ${desc} | ${required} | ${defaultVal} |`);
158
207
  }
@@ -239,14 +288,13 @@ function renderOptionsTableFromArray(options) {
239
288
  lines.push("|--------|-------|-------------|----------|---------|");
240
289
  }
241
290
  for (const opt of options) {
242
- const placeholder = opt.placeholder ?? opt.cliName.toUpperCase().replace(/-/g, "_");
243
- const optionName = opt.type === "boolean" ? `\`--${opt.cliName}\`` : `\`--${opt.cliName} <${placeholder}>\``;
291
+ const optionName = formatOptionName(opt);
244
292
  const alias = opt.alias ? `\`-${opt.alias}\`` : "-";
245
293
  const desc = escapeTableCell$2(opt.description ?? "");
246
294
  const required = opt.required ? "Yes" : "No";
247
295
  const defaultVal = formatDefaultValue$1(opt.defaultValue);
248
296
  if (hasEnv) {
249
- const envNames = opt.env ? Array.isArray(opt.env) ? opt.env.map((e) => `\`${e}\``).join(", ") : `\`${opt.env}\`` : "-";
297
+ const envNames = formatEnvNames(opt.env);
250
298
  lines.push(`| ${optionName} | ${alias} | ${desc} | ${required} | ${defaultVal} | ${envNames} |`);
251
299
  } else lines.push(`| ${optionName} | ${alias} | ${desc} | ${required} | ${defaultVal} |`);
252
300
  }
@@ -362,17 +410,23 @@ function renderExamplesDefault(examples, results, opts) {
362
410
  return lines.join("\n");
363
411
  }
364
412
  /**
413
+ * Wrap content with section markers
414
+ */
415
+ function wrapWithMarker(type, scope, content) {
416
+ return `${sectionStartMarker(type, scope)}\n${content}\n${sectionEndMarker(type, scope)}`;
417
+ }
418
+ /**
365
419
  * Create command renderer with options
366
420
  */
367
421
  function createCommandRenderer(options = {}) {
368
422
  const { headingLevel = 1, optionStyle = "table", generateAnchors = true, includeSubcommandDetails = true, renderDescription: customRenderDescription, renderUsage: customRenderUsage, renderArguments: customRenderArguments, renderOptions: customRenderOptions, renderSubcommands: customRenderSubcommands, renderNotes: customRenderNotes, renderFooter: customRenderFooter, renderExamples: customRenderExamples } = options;
369
423
  return (info) => {
370
- const lines = [];
424
+ const sections = [];
425
+ const scope = info.commandPath;
371
426
  const effectiveLevel = Math.min(headingLevel + (info.depth - 1), 6);
372
427
  const h = "#".repeat(effectiveLevel);
373
428
  const title = info.commandPath || info.name;
374
- lines.push(`${h} ${title}`);
375
- lines.push("");
429
+ sections.push(wrapWithMarker("heading", scope, `${h} ${title}`));
376
430
  if (info.description) {
377
431
  const context = {
378
432
  content: info.description,
@@ -380,10 +434,7 @@ function createCommandRenderer(options = {}) {
380
434
  info
381
435
  };
382
436
  const content = customRenderDescription ? customRenderDescription(context) : context.content;
383
- if (content) {
384
- lines.push(content);
385
- lines.push("");
386
- }
437
+ if (content) sections.push(wrapWithMarker("description", scope, content));
387
438
  }
388
439
  {
389
440
  const context = {
@@ -392,10 +443,7 @@ function createCommandRenderer(options = {}) {
392
443
  info
393
444
  };
394
445
  const content = customRenderUsage ? customRenderUsage(context) : context.content;
395
- if (content) {
396
- lines.push(content);
397
- lines.push("");
398
- }
446
+ if (content) sections.push(wrapWithMarker("usage", scope, content));
399
447
  }
400
448
  if (info.positionalArgs.length > 0) {
401
449
  const renderArgs = (args, opts) => {
@@ -411,10 +459,7 @@ function createCommandRenderer(options = {}) {
411
459
  info
412
460
  };
413
461
  const content = customRenderArguments ? customRenderArguments(context) : renderArgs(context.args);
414
- if (content) {
415
- lines.push(content);
416
- lines.push("");
417
- }
462
+ if (content) sections.push(wrapWithMarker("arguments", scope, content));
418
463
  }
419
464
  if (info.options.length > 0) {
420
465
  const renderOpts = (opts, renderOpts) => {
@@ -430,10 +475,7 @@ function createCommandRenderer(options = {}) {
430
475
  info
431
476
  };
432
477
  const content = customRenderOptions ? customRenderOptions(context) : renderOpts(context.options);
433
- if (content) {
434
- lines.push(content);
435
- lines.push("");
436
- }
478
+ if (content) sections.push(wrapWithMarker("options", scope, content));
437
479
  }
438
480
  if (info.subCommands.length > 0) {
439
481
  const effectiveAnchors = generateAnchors && includeSubcommandDetails;
@@ -450,10 +492,7 @@ function createCommandRenderer(options = {}) {
450
492
  info
451
493
  };
452
494
  const content = customRenderSubcommands ? customRenderSubcommands(context) : renderSubs(context.subcommands);
453
- if (content) {
454
- lines.push(content);
455
- lines.push("");
456
- }
495
+ if (content) sections.push(wrapWithMarker("subcommands", scope, content));
457
496
  }
458
497
  if (info.examples && info.examples.length > 0) {
459
498
  const renderEx = (examples, results, opts) => {
@@ -472,10 +511,7 @@ function createCommandRenderer(options = {}) {
472
511
  info
473
512
  };
474
513
  const content = customRenderExamples ? customRenderExamples(context) : renderEx(context.examples, context.results);
475
- if (content) {
476
- lines.push(content);
477
- lines.push("");
478
- }
514
+ if (content) sections.push(wrapWithMarker("examples", scope, content));
479
515
  }
480
516
  if (info.notes) {
481
517
  const context = {
@@ -484,10 +520,7 @@ function createCommandRenderer(options = {}) {
484
520
  info
485
521
  };
486
522
  const content = customRenderNotes ? customRenderNotes(context) : context.content;
487
- if (content) {
488
- lines.push(content);
489
- lines.push("");
490
- }
523
+ if (content) sections.push(wrapWithMarker("notes", scope, content));
491
524
  }
492
525
  {
493
526
  const context = {
@@ -496,14 +529,9 @@ function createCommandRenderer(options = {}) {
496
529
  info
497
530
  };
498
531
  const content = customRenderFooter ? customRenderFooter(context) : context.content;
499
- if (content) {
500
- lines.push(content);
501
- lines.push("");
502
- }
532
+ if (content) sections.push(content);
503
533
  }
504
- while (lines.length > 0 && lines[lines.length - 1] === "") lines.pop();
505
- lines.push("");
506
- return lines.join("\n");
534
+ return sections.join("\n\n") + "\n";
507
535
  };
508
536
  }
509
537
  /**
@@ -695,7 +723,7 @@ async function executeSingleExample(example, rootCommand, commandPath) {
695
723
  collector.start();
696
724
  let success = true;
697
725
  try {
698
- const { runCommand } = await Promise.resolve().then(() => require("../runner-BFKk3Arg.cjs")).then((n) => n.runner_exports);
726
+ const { runCommand } = await Promise.resolve().then(() => require("../runner-9dLE13Dv.cjs")).then((n) => n.runner_exports);
699
727
  const result = await runCommand(rootCommand, argv);
700
728
  success = result.success;
701
729
  if (!result.success && result.error) console.error(result.error.message);
@@ -976,64 +1004,6 @@ async function renderCommandIndex(command, categories, options) {
976
1004
  return sections.join("\n\n");
977
1005
  }
978
1006
 
979
- //#endregion
980
- //#region src/docs/types.ts
981
- /**
982
- * Environment variable name for update mode
983
- */
984
- const UPDATE_GOLDEN_ENV = "POLITTY_DOCS_UPDATE";
985
- /**
986
- * Marker prefix for command sections in generated documentation
987
- * Format: <!-- politty:command:<path>:start --> ... <!-- politty:command:<path>:end -->
988
- */
989
- const COMMAND_MARKER_PREFIX = "politty:command";
990
- /**
991
- * Generate start marker for a command section
992
- */
993
- function commandStartMarker(commandPath) {
994
- return `<!-- ${COMMAND_MARKER_PREFIX}:${commandPath}:start -->`;
995
- }
996
- /**
997
- * Generate end marker for a command section
998
- */
999
- function commandEndMarker(commandPath) {
1000
- return `<!-- ${COMMAND_MARKER_PREFIX}:${commandPath}:end -->`;
1001
- }
1002
- /**
1003
- * Marker prefix for global options sections in generated documentation
1004
- * Format: <!-- politty:global-options:start --> ... <!-- politty:global-options:end -->
1005
- */
1006
- const GLOBAL_OPTIONS_MARKER_PREFIX = "politty:global-options";
1007
- /**
1008
- * Generate start marker for a global options section
1009
- */
1010
- function globalOptionsStartMarker() {
1011
- return `<!-- ${GLOBAL_OPTIONS_MARKER_PREFIX}:start -->`;
1012
- }
1013
- /**
1014
- * Generate end marker for a global options section
1015
- */
1016
- function globalOptionsEndMarker() {
1017
- return `<!-- ${GLOBAL_OPTIONS_MARKER_PREFIX}:end -->`;
1018
- }
1019
- /**
1020
- * Marker prefix for index sections in generated documentation
1021
- * Format: <!-- politty:index:start --> ... <!-- politty:index:end -->
1022
- */
1023
- const INDEX_MARKER_PREFIX = "politty:index";
1024
- /**
1025
- * Generate start marker for an index section
1026
- */
1027
- function indexStartMarker() {
1028
- return `<!-- ${INDEX_MARKER_PREFIX}:start -->`;
1029
- }
1030
- /**
1031
- * Generate end marker for an index section
1032
- */
1033
- function indexEndMarker() {
1034
- return `<!-- ${INDEX_MARKER_PREFIX}:end -->`;
1035
- }
1036
-
1037
1007
  //#endregion
1038
1008
  //#region src/docs/golden-test.ts
1039
1009
  /**
@@ -1124,16 +1094,8 @@ function matchesIgnorePattern(path, ignorePattern) {
1124
1094
  */
1125
1095
  function expandCommandPaths(commandPaths, allCommands) {
1126
1096
  const expanded = /* @__PURE__ */ new Set();
1127
- for (const cmdPath of commandPaths) if (containsWildcard(cmdPath)) {
1128
- const matches = expandWildcardPattern(cmdPath, allCommands);
1129
- for (const match of matches) {
1130
- expanded.add(match);
1131
- for (const path of allCommands.keys()) if (isSubcommandOf(path, match)) expanded.add(path);
1132
- }
1133
- } else {
1134
- if (allCommands.has(cmdPath)) expanded.add(cmdPath);
1135
- for (const path of allCommands.keys()) if (isSubcommandOf(path, cmdPath)) expanded.add(path);
1136
- }
1097
+ const resolved = commandPaths.flatMap((cmdPath) => containsWildcard(cmdPath) ? expandWildcardPattern(cmdPath, allCommands) : [cmdPath]);
1098
+ for (const cmdPath of resolved) for (const existingPath of allCommands.keys()) if (isSubcommandOf(existingPath, cmdPath)) expanded.add(existingPath);
1137
1099
  return Array.from(expanded);
1138
1100
  }
1139
1101
  /**
@@ -1276,55 +1238,52 @@ function processFileHeader(existingContent, fileConfig, updateMode) {
1276
1238
  wasUpdated: true
1277
1239
  };
1278
1240
  }
1241
+ function formatCommandPath(commandPath) {
1242
+ return commandPath === "" ? "<root>" : commandPath;
1243
+ }
1279
1244
  /**
1280
- * Extract a command section from content using markers
1281
- * Returns the content between start and end markers (including markers)
1245
+ * Extract a section marker's content from document content.
1246
+ * Returns the content between start and end markers (including markers).
1282
1247
  */
1283
- function extractCommandSection(content, commandPath) {
1284
- const startMarker = commandStartMarker(commandPath);
1285
- const endMarker = commandEndMarker(commandPath);
1286
- const startIndex = content.indexOf(startMarker);
1287
- if (startIndex === -1) return null;
1288
- const endIndex = content.indexOf(endMarker, startIndex);
1289
- if (endIndex === -1) return null;
1290
- return content.slice(startIndex, endIndex + endMarker.length);
1248
+ function extractSectionMarker(content, type, scope) {
1249
+ return extractMarkerSection(content, sectionStartMarker(type, scope), sectionEndMarker(type, scope));
1291
1250
  }
1292
1251
  /**
1293
- * Collect command paths from command start markers in content.
1252
+ * Replace a section marker's content in document content.
1253
+ * Returns updated content, or null if marker not found.
1294
1254
  */
1295
- function collectCommandMarkerPaths(content) {
1296
- const markerPattern = /<!--\s*politty:command:(.*?):start\s*-->/g;
1297
- const paths = [];
1298
- for (const match of content.matchAll(markerPattern)) paths.push(match[1] ?? "");
1299
- return paths;
1255
+ function replaceSectionMarker(content, type, scope, newContent) {
1256
+ return replaceMarkerSection(content, sectionStartMarker(type, scope), sectionEndMarker(type, scope), newContent);
1300
1257
  }
1301
- function formatCommandPath(commandPath) {
1302
- return commandPath === "" ? "<root>" : commandPath;
1258
+ /**
1259
+ * Collect all section types that have markers for a given command path.
1260
+ */
1261
+ function collectSectionMarkers(content, commandPath) {
1262
+ const found = [];
1263
+ for (const type of SECTION_TYPES) if (extractSectionMarker(content, type, commandPath) !== null) found.push(type);
1264
+ return found;
1303
1265
  }
1304
1266
  /**
1305
- * Replace a command section in content using markers
1306
- * Returns the updated content with the new section
1267
+ * Collect all command paths that have any section markers in the content.
1307
1268
  */
1308
- function replaceCommandSection(content, commandPath, newSection) {
1309
- const startMarker = commandStartMarker(commandPath);
1310
- const endMarker = commandEndMarker(commandPath);
1311
- const startIndex = content.indexOf(startMarker);
1312
- if (startIndex === -1) return null;
1313
- const endIndex = content.indexOf(endMarker, startIndex);
1314
- if (endIndex === -1) return null;
1315
- return content.slice(0, startIndex) + newSection + content.slice(endIndex + endMarker.length);
1269
+ function collectSectionMarkerPaths(content) {
1270
+ const sectionTypes = SECTION_TYPES.join("|");
1271
+ const markerPattern = new RegExp(`<!--\\s*politty:command:(.*?):(?:${sectionTypes}):start\\s*-->`, "g");
1272
+ const paths = /* @__PURE__ */ new Set();
1273
+ for (const match of content.matchAll(markerPattern)) paths.add(match[1] ?? "");
1274
+ return Array.from(paths);
1316
1275
  }
1317
1276
  /**
1318
- * Insert a command section at the correct position based on specified order
1319
- * Returns the updated content with the section inserted at the right position
1277
+ * Insert command section markers at the correct position based on specified order.
1278
+ * Uses the heading marker of adjacent commands as reference points.
1320
1279
  */
1321
- function insertCommandSection(content, commandPath, newSection, specifiedOrder) {
1280
+ function insertCommandSections(content, commandPath, newSection, specifiedOrder) {
1322
1281
  const targetIndex = specifiedOrder.indexOf(commandPath);
1323
1282
  if (targetIndex === -1) return content.trimEnd() + "\n\n" + newSection + "\n";
1324
1283
  for (let i = targetIndex + 1; i < specifiedOrder.length; i++) {
1325
1284
  const nextCmd = specifiedOrder[i];
1326
1285
  if (nextCmd === void 0) continue;
1327
- const nextMarker = commandStartMarker(nextCmd);
1286
+ const nextMarker = sectionStartMarker("heading", nextCmd);
1328
1287
  const nextIndex = content.indexOf(nextMarker);
1329
1288
  if (nextIndex !== -1) {
1330
1289
  let insertPos = nextIndex;
@@ -1336,11 +1295,15 @@ function insertCommandSection(content, commandPath, newSection, specifiedOrder)
1336
1295
  for (let i = targetIndex - 1; i >= 0; i--) {
1337
1296
  const prevCmd = specifiedOrder[i];
1338
1297
  if (prevCmd === void 0) continue;
1339
- const prevEndMarker = commandEndMarker(prevCmd);
1340
- const prevEndIndex = content.indexOf(prevEndMarker);
1341
- if (prevEndIndex !== -1) {
1342
- const insertPos = prevEndIndex + prevEndMarker.length;
1343
- return content.slice(0, insertPos) + "\n" + newSection + content.slice(insertPos);
1298
+ const prevMarkers = collectSectionMarkers(content, prevCmd);
1299
+ if (prevMarkers.length > 0) {
1300
+ const lastType = prevMarkers[prevMarkers.length - 1];
1301
+ const prevEndMarker = sectionEndMarker(lastType, prevCmd);
1302
+ const prevEndIndex = content.indexOf(prevEndMarker);
1303
+ if (prevEndIndex !== -1) {
1304
+ const insertPos = prevEndIndex + prevEndMarker.length;
1305
+ return content.slice(0, insertPos) + "\n" + newSection + content.slice(insertPos);
1306
+ }
1344
1307
  }
1345
1308
  }
1346
1309
  return content.trimEnd() + "\n" + newSection + "\n";
@@ -1491,9 +1454,9 @@ function generateGlobalOptionsSection(config) {
1491
1454
  /**
1492
1455
  * Generate index section content with markers
1493
1456
  */
1494
- async function generateIndexSection(categories, command, options) {
1495
- const startMarker = indexStartMarker();
1496
- const endMarker = indexEndMarker();
1457
+ async function generateIndexSection(categories, command, scope, options) {
1458
+ const startMarker = indexStartMarker(scope);
1459
+ const endMarker = indexEndMarker(scope);
1497
1460
  return [
1498
1461
  startMarker,
1499
1462
  await renderCommandIndex(command, categories, options),
@@ -1554,13 +1517,13 @@ async function processGlobalOptionsMarker(existingContent, globalOptionsConfig,
1554
1517
  * Returns result with updated content and any diffs.
1555
1518
  * If the marker is not present in the file, the section is silently skipped.
1556
1519
  */
1557
- async function processIndexMarker(existingContent, categories, command, updateMode, formatter, indexOptions) {
1520
+ async function processIndexMarker(existingContent, categories, command, scope, updateMode, formatter, indexOptions) {
1558
1521
  let content = existingContent;
1559
1522
  const diffs = [];
1560
1523
  let hasError = false;
1561
1524
  let wasUpdated = false;
1562
- const startMarker = indexStartMarker();
1563
- const endMarker = indexEndMarker();
1525
+ const startMarker = indexStartMarker(scope);
1526
+ const endMarker = indexEndMarker(scope);
1564
1527
  const hasStartMarker = content.includes(startMarker);
1565
1528
  const hasEndMarker = content.includes(endMarker);
1566
1529
  if (!hasStartMarker && !hasEndMarker) return {
@@ -1590,7 +1553,7 @@ async function processIndexMarker(existingContent, categories, command, updateMo
1590
1553
  wasUpdated
1591
1554
  };
1592
1555
  }
1593
- const generatedSection = await applyFormatter(await generateIndexSection(categories, command, indexOptions), formatter);
1556
+ const generatedSection = await applyFormatter(await generateIndexSection(categories, command, scope, indexOptions), formatter);
1594
1557
  if (existingSection !== generatedSection) if (updateMode) {
1595
1558
  const updated = replaceMarkerSection(content, startMarker, endMarker, generatedSection);
1596
1559
  if (updated) {
@@ -1638,21 +1601,16 @@ function findTargetCommandsInFile(targetCommands, filePath, files, allCommands,
1638
1601
  return Array.from(expandedTargets);
1639
1602
  }
1640
1603
  /**
1641
- * Generate a single command section with markers
1604
+ * Generate a single command section (already contains section markers from renderer)
1642
1605
  */
1643
1606
  function generateCommandSection(cmdPath, allCommands, render, filePath, fileMap) {
1644
1607
  const info = allCommands.get(cmdPath);
1645
1608
  if (!info) return null;
1646
- const renderedSection = render({
1609
+ return render({
1647
1610
  ...info,
1648
1611
  filePath,
1649
1612
  fileMap
1650
1613
  });
1651
- return [
1652
- commandStartMarker(cmdPath),
1653
- renderedSection,
1654
- commandEndMarker(cmdPath)
1655
- ].join("\n");
1656
1614
  }
1657
1615
  /**
1658
1616
  * Generate markdown for a file containing multiple commands
@@ -1741,12 +1699,13 @@ async function generateDoc(config) {
1741
1699
  for (const targetCommand of fileTargetCommands) {
1742
1700
  const rawSection = generateCommandSection(targetCommand, allCommands, render, filePath, fileMap);
1743
1701
  if (!rawSection) throw new Error(`Target command "${targetCommand}" not found in commands`);
1744
- const header = targetCommand === "" && fileConfig ? generateFileHeader(fileConfig) : null;
1745
- const generatedSection = await applyFormatter(header ? `${header}\n${rawSection}` : rawSection, formatter);
1702
+ const generatedSection = await applyFormatter(rawSection, formatter);
1746
1703
  if (!existingContent) {
1747
1704
  if (updateMode) {
1748
- writeFile(filePath, generatedSection);
1749
- existingContent = generatedSection;
1705
+ const header = targetCommand === "" && fileConfig ? generateFileHeader(fileConfig) : null;
1706
+ const fullContent = header ? `${header}\n${generatedSection}` : generatedSection;
1707
+ writeFile(filePath, fullContent);
1708
+ existingContent = fullContent;
1750
1709
  fileStatus = "created";
1751
1710
  } else {
1752
1711
  hasError = true;
@@ -1755,32 +1714,35 @@ async function generateDoc(config) {
1755
1714
  }
1756
1715
  continue;
1757
1716
  }
1758
- const existingSection = extractCommandSection(existingContent, targetCommand);
1759
- const generatedSectionOnly = extractCommandSection(generatedSection, targetCommand);
1760
- if (!generatedSectionOnly) throw new Error(`Generated content does not contain section for command "${targetCommand}"`);
1761
- if (!existingSection) {
1717
+ const existingMarkers = collectSectionMarkers(existingContent, targetCommand);
1718
+ if (existingMarkers.length === 0) {
1762
1719
  if (updateMode) {
1763
- existingContent = insertCommandSection(existingContent, targetCommand, generatedSectionOnly, specifiedCommands);
1720
+ existingContent = insertCommandSections(existingContent, targetCommand, generatedSection, specifiedCommands);
1764
1721
  writeFile(filePath, existingContent);
1765
1722
  if (fileStatus !== "created") fileStatus = "updated";
1766
1723
  } else {
1767
1724
  hasError = true;
1768
1725
  fileStatus = "diff";
1769
- diffs.push(`Existing file does not contain section for command "${targetCommand}"`);
1726
+ diffs.push(`Existing file does not contain section markers for command "${targetCommand}"`);
1770
1727
  }
1771
1728
  continue;
1772
1729
  }
1773
- if (existingSection !== generatedSectionOnly) if (updateMode) {
1774
- const updatedContent = replaceCommandSection(existingContent, targetCommand, generatedSectionOnly);
1775
- if (updatedContent) {
1776
- existingContent = updatedContent;
1777
- writeFile(filePath, existingContent);
1778
- if (fileStatus !== "created") fileStatus = "updated";
1779
- } else throw new Error(`Failed to replace section for command "${targetCommand}"`);
1780
- } else {
1781
- hasError = true;
1782
- fileStatus = "diff";
1783
- diffs.push(formatDiff(existingSection, generatedSectionOnly));
1730
+ for (const sectionType of existingMarkers) {
1731
+ const existingSection = extractSectionMarker(existingContent, sectionType, targetCommand);
1732
+ const generatedSectionPart = extractSectionMarker(generatedSection, sectionType, targetCommand);
1733
+ if (!existingSection || !generatedSectionPart) continue;
1734
+ if (existingSection !== generatedSectionPart) if (updateMode) {
1735
+ const updated = replaceSectionMarker(existingContent, sectionType, targetCommand, generatedSectionPart);
1736
+ if (updated) {
1737
+ existingContent = updated;
1738
+ writeFile(filePath, existingContent);
1739
+ if (fileStatus !== "created") fileStatus = "updated";
1740
+ } else throw new Error(`Failed to replace ${sectionType} section for command "${targetCommand}"`);
1741
+ } else {
1742
+ hasError = true;
1743
+ fileStatus = "diff";
1744
+ diffs.push(formatDiff(existingSection, generatedSectionPart));
1745
+ }
1784
1746
  }
1785
1747
  }
1786
1748
  } else {
@@ -1822,10 +1784,10 @@ async function generateDoc(config) {
1822
1784
  if (headerResult.diff) rootDocDiffs.push(headerResult.diff);
1823
1785
  if (headerResult.hasError) hasError = true;
1824
1786
  if (headerResult.wasUpdated) markerUpdated = true;
1825
- const unexpectedCommandMarkers = Array.from(new Set(collectCommandMarkerPaths(content)));
1826
- if (unexpectedCommandMarkers.length > 0) {
1787
+ const unexpectedSectionPaths = Array.from(new Set(collectSectionMarkerPaths(content)));
1788
+ if (unexpectedSectionPaths.length > 0) {
1827
1789
  hasError = true;
1828
- rootDocDiffs.push(`Found unexpected command marker sections in rootDoc: ${unexpectedCommandMarkers.map((commandPath) => `"${formatCommandPath(commandPath)}"`).join(", ")}.`);
1790
+ rootDocDiffs.push(`Found unexpected section markers in rootDoc: ${unexpectedSectionPaths.map((commandPath) => `"${formatCommandPath(commandPath)}"`).join(", ")}.`);
1829
1791
  }
1830
1792
  const normalizedGlobalOptions = normalizeGlobalOptions(rootDoc.globalOptions);
1831
1793
  if (normalizedGlobalOptions) {
@@ -1836,7 +1798,8 @@ async function generateDoc(config) {
1836
1798
  if (globalOptionsResult.wasUpdated) markerUpdated = true;
1837
1799
  }
1838
1800
  const derivedCategories = deriveIndexFromFiles(files, rootDocFilePath, allCommands, ignores);
1839
- const indexResult = await processIndexMarker(content, derivedCategories, command, updateMode, formatter, rootDoc.index);
1801
+ const indexScope = node_path.relative(process.cwd(), rootDocFilePath);
1802
+ const indexResult = await processIndexMarker(content, derivedCategories, command, indexScope, updateMode, formatter, rootDoc.index);
1840
1803
  content = indexResult.content;
1841
1804
  rootDocDiffs.push(...indexResult.diffs);
1842
1805
  if (indexResult.hasError) hasError = true;
@@ -1888,17 +1851,14 @@ function initDocFile(config, fileSystem) {
1888
1851
  }
1889
1852
 
1890
1853
  //#endregion
1891
- exports.COMMAND_MARKER_PREFIX = COMMAND_MARKER_PREFIX;
1892
1854
  exports.GLOBAL_OPTIONS_MARKER_PREFIX = GLOBAL_OPTIONS_MARKER_PREFIX;
1893
1855
  exports.INDEX_MARKER_PREFIX = INDEX_MARKER_PREFIX;
1856
+ exports.SECTION_MARKER_PREFIX = SECTION_MARKER_PREFIX;
1857
+ exports.SECTION_TYPES = SECTION_TYPES;
1894
1858
  exports.UPDATE_GOLDEN_ENV = UPDATE_GOLDEN_ENV;
1895
- exports.__exportAll = __exportAll;
1896
- exports.__toESM = __toESM;
1897
1859
  exports.assertDocMatch = assertDocMatch;
1898
1860
  exports.buildCommandInfo = buildCommandInfo;
1899
1861
  exports.collectAllCommands = collectAllCommands;
1900
- exports.commandEndMarker = commandEndMarker;
1901
- exports.commandStartMarker = commandStartMarker;
1902
1862
  exports.compareWithExisting = compareWithExisting;
1903
1863
  exports.createCommandRenderer = createCommandRenderer;
1904
1864
  exports.defaultRenderers = defaultRenderers;
@@ -1925,5 +1885,7 @@ exports.renderSubcommandsTable = renderSubcommandsTable;
1925
1885
  exports.renderSubcommandsTableFromArray = renderSubcommandsTableFromArray;
1926
1886
  exports.renderUsage = renderUsage;
1927
1887
  exports.resolveLazyCommand = require_subcommand_router.resolveLazyCommand;
1888
+ exports.sectionEndMarker = sectionEndMarker;
1889
+ exports.sectionStartMarker = sectionStartMarker;
1928
1890
  exports.writeFile = writeFile;
1929
1891
  //# sourceMappingURL=index.cjs.map