politty 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/dist/{arg-registry-D4NsqcNZ.d.ts → arg-registry-i6SA4l-E.d.cts} +1 -2
  2. package/dist/arg-registry-i6SA4l-E.d.cts.map +1 -0
  3. package/dist/{arg-registry-ClI2WGgH.d.cts → arg-registry-w5mMKJkZ.d.ts} +1 -2
  4. package/dist/arg-registry-w5mMKJkZ.d.ts.map +1 -0
  5. package/dist/augment.d.cts +1 -2
  6. package/dist/augment.d.cts.map +1 -1
  7. package/dist/augment.d.ts +1 -2
  8. package/dist/augment.d.ts.map +1 -1
  9. package/dist/{command-CvKyk4ag.js → command-DCpFEZFM.js} +1 -1
  10. package/dist/{command-CvKyk4ag.js.map → command-DCpFEZFM.js.map} +1 -1
  11. package/dist/completion/index.cjs.map +1 -1
  12. package/dist/completion/index.d.cts +1 -3
  13. package/dist/completion/index.d.cts.map +1 -1
  14. package/dist/completion/index.d.ts +1 -3
  15. package/dist/completion/index.d.ts.map +1 -1
  16. package/dist/completion/index.js +2 -2
  17. package/dist/completion/index.js.map +1 -1
  18. package/dist/docs/index.cjs +247 -25
  19. package/dist/docs/index.cjs.map +1 -1
  20. package/dist/docs/index.d.cts +93 -13
  21. package/dist/docs/index.d.cts.map +1 -1
  22. package/dist/docs/index.d.ts +93 -13
  23. package/dist/docs/index.d.ts.map +1 -1
  24. package/dist/docs/index.js +264 -44
  25. package/dist/docs/index.js.map +1 -1
  26. package/dist/index.cjs +2 -1
  27. package/dist/index.d.cts +42 -3
  28. package/dist/index.d.cts.map +1 -1
  29. package/dist/index.d.ts +42 -3
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +4 -4
  32. package/dist/runner-BkhekqT9.cjs +4 -0
  33. package/dist/{runner-C8rhhx6L.js → runner-CyxuNkT1.js} +19 -19
  34. package/dist/runner-CyxuNkT1.js.map +1 -0
  35. package/dist/runner-DzzbIwEy.js +4 -0
  36. package/dist/{runner-CmjYWlam.cjs → runner-ttyvfYGi.cjs} +22 -16
  37. package/dist/runner-ttyvfYGi.cjs.map +1 -0
  38. package/dist/schema-extractor-B9D3Rf22.cjs.map +1 -1
  39. package/dist/{schema-extractor-kkajLb9E.d.ts → schema-extractor-CXeUTW_Z.d.cts} +1 -2
  40. package/dist/schema-extractor-CXeUTW_Z.d.cts.map +1 -0
  41. package/dist/{schema-extractor-D-Eo7I77.d.cts → schema-extractor-Cl_D04BX.d.ts} +1 -2
  42. package/dist/schema-extractor-Cl_D04BX.d.ts.map +1 -0
  43. package/dist/{schema-extractor-Dk5Z0Iei.js → schema-extractor-D0q5Fj2R.js} +1 -1
  44. package/dist/schema-extractor-D0q5Fj2R.js.map +1 -0
  45. package/dist/{subcommand-router-BiSvDXHg.js → subcommand-router-D9QSLX56.js} +1 -1
  46. package/dist/subcommand-router-D9QSLX56.js.map +1 -0
  47. package/dist/subcommand-router-Vf-0w9P4.cjs.map +1 -1
  48. package/package.json +12 -12
  49. package/dist/arg-registry-ClI2WGgH.d.cts.map +0 -1
  50. package/dist/arg-registry-D4NsqcNZ.d.ts.map +0 -1
  51. package/dist/runner-C8rhhx6L.js.map +0 -1
  52. package/dist/runner-C_m6ve-j.js +0 -4
  53. package/dist/runner-CmjYWlam.cjs.map +0 -1
  54. package/dist/runner-pmoTWUXY.cjs +0 -4
  55. package/dist/schema-extractor-D-Eo7I77.d.cts.map +0 -1
  56. package/dist/schema-extractor-Dk5Z0Iei.js.map +0 -1
  57. package/dist/schema-extractor-kkajLb9E.d.ts.map +0 -1
  58. package/dist/subcommand-router-BiSvDXHg.js.map +0 -1
@@ -27,6 +27,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
27
27
  //#endregion
28
28
  const require_schema_extractor = require('../schema-extractor-B9D3Rf22.cjs');
29
29
  const require_subcommand_router = require('../subcommand-router-Vf-0w9P4.cjs');
30
+ let zod = require("zod");
30
31
  let node_fs = require("node:fs");
31
32
  node_fs = __toESM(node_fs);
32
33
  let node_path = require("node:path");
@@ -36,13 +37,13 @@ node_path = __toESM(node_path);
36
37
  /**
37
38
  * Escape markdown special characters in table cells
38
39
  */
39
- function escapeTableCell(str) {
40
+ function escapeTableCell$2(str) {
40
41
  return str.replace(/\|/g, "\\|").replace(/\n/g, " ");
41
42
  }
42
43
  /**
43
44
  * Format default value for display
44
45
  */
45
- function formatDefaultValue(value) {
46
+ function formatDefaultValue$1(value) {
46
47
  if (value === void 0) return "-";
47
48
  return `\`${JSON.stringify(value)}\``;
48
49
  }
@@ -66,7 +67,7 @@ function renderArgumentsTable(info) {
66
67
  lines.push("| Argument | Description | Required |");
67
68
  lines.push("|----------|-------------|----------|");
68
69
  for (const arg of info.positionalArgs) {
69
- const desc = escapeTableCell(arg.description ?? "");
70
+ const desc = escapeTableCell$2(arg.description ?? "");
70
71
  const required = arg.required ? "Yes" : "No";
71
72
  lines.push(`| \`${arg.name}\` | ${desc} | ${required} |`);
72
73
  }
@@ -132,8 +133,8 @@ function renderOptionsTable(info) {
132
133
  const placeholder = opt.placeholder ?? opt.cliName.toUpperCase().replace(/-/g, "_");
133
134
  const optionName = opt.type === "boolean" ? `\`--${opt.cliName}\`` : `\`--${opt.cliName} <${placeholder}>\``;
134
135
  const alias = opt.alias ? `\`-${opt.alias}\`` : "-";
135
- const desc = escapeTableCell(opt.description ?? "");
136
- const defaultVal = formatDefaultValue(opt.defaultValue);
136
+ const desc = escapeTableCell$2(opt.description ?? "");
137
+ const defaultVal = formatDefaultValue$1(opt.defaultValue);
137
138
  if (hasEnv) {
138
139
  const envNames = opt.env ? Array.isArray(opt.env) ? opt.env.map((e) => `\`${e}\``).join(", ") : `\`${opt.env}\`` : "-";
139
140
  lines.push(`| ${optionName} | ${alias} | ${desc} | ${defaultVal} | ${envNames} |`);
@@ -167,7 +168,7 @@ function renderOptionsList(info) {
167
168
  /**
168
169
  * Generate anchor from command path
169
170
  */
170
- function generateAnchor(commandPath) {
171
+ function generateAnchor$1(commandPath) {
171
172
  return commandPath.join("-").toLowerCase();
172
173
  }
173
174
  /**
@@ -193,10 +194,10 @@ function renderSubcommandsTable(info, generateAnchors = true) {
193
194
  const fileMap = info.fileMap;
194
195
  for (const sub of info.subCommands) {
195
196
  const fullName = sub.fullPath.join(" ");
196
- const desc = escapeTableCell(sub.description ?? "");
197
+ const desc = escapeTableCell$2(sub.description ?? "");
197
198
  const subCommandPath = sub.fullPath.join(" ");
198
199
  if (generateAnchors) {
199
- const anchor = generateAnchor(sub.fullPath);
200
+ const anchor = generateAnchor$1(sub.fullPath);
200
201
  const subFile = fileMap?.[subCommandPath];
201
202
  if (currentFile && subFile && currentFile !== subFile) {
202
203
  const relativePath = getRelativePath(currentFile, subFile);
@@ -224,8 +225,8 @@ function renderOptionsTableFromArray(options) {
224
225
  const placeholder = opt.placeholder ?? opt.cliName.toUpperCase().replace(/-/g, "_");
225
226
  const optionName = opt.type === "boolean" ? `\`--${opt.cliName}\`` : `\`--${opt.cliName} <${placeholder}>\``;
226
227
  const alias = opt.alias ? `\`-${opt.alias}\`` : "-";
227
- const desc = escapeTableCell(opt.description ?? "");
228
- const defaultVal = formatDefaultValue(opt.defaultValue);
228
+ const desc = escapeTableCell$2(opt.description ?? "");
229
+ const defaultVal = formatDefaultValue$1(opt.defaultValue);
229
230
  if (hasEnv) {
230
231
  const envNames = opt.env ? Array.isArray(opt.env) ? opt.env.map((e) => `\`${e}\``).join(", ") : `\`${opt.env}\`` : "-";
231
232
  lines.push(`| ${optionName} | ${alias} | ${desc} | ${defaultVal} | ${envNames} |`);
@@ -257,7 +258,7 @@ function renderArgumentsTableFromArray(args) {
257
258
  lines.push("| Argument | Description | Required |");
258
259
  lines.push("|----------|-------------|----------|");
259
260
  for (const arg of args) {
260
- const desc = escapeTableCell(arg.description ?? "");
261
+ const desc = escapeTableCell$2(arg.description ?? "");
261
262
  const required = arg.required ? "Yes" : "No";
262
263
  lines.push(`| \`${arg.name}\` | ${desc} | ${required} |`);
263
264
  }
@@ -288,10 +289,10 @@ function renderSubcommandsTableFromArray(subcommands, info, generateAnchors = tr
288
289
  const fileMap = info.fileMap;
289
290
  for (const sub of subcommands) {
290
291
  const fullName = sub.fullPath.join(" ");
291
- const desc = escapeTableCell(sub.description ?? "");
292
+ const desc = escapeTableCell$2(sub.description ?? "");
292
293
  const subCommandPath = sub.fullPath.join(" ");
293
294
  if (generateAnchors) {
294
- const anchor = generateAnchor(sub.fullPath);
295
+ const anchor = generateAnchor$1(sub.fullPath);
295
296
  const subFile = fileMap?.[subCommandPath];
296
297
  if (currentFile && subFile && currentFile !== subFile) {
297
298
  const relativePath = getRelativePath(currentFile, subFile);
@@ -380,8 +381,8 @@ function createCommandRenderer(options = {}) {
380
381
  const renderArgs = (args, opts) => {
381
382
  const style = opts?.style ?? optionStyle;
382
383
  const withHeading = opts?.withHeading ?? true;
383
- const content$1 = style === "table" ? renderArgumentsTableFromArray(args) : renderArgumentsListFromArray(args);
384
- return withHeading ? `**Arguments**\n\n${content$1}` : content$1;
384
+ const content = style === "table" ? renderArgumentsTableFromArray(args) : renderArgumentsListFromArray(args);
385
+ return withHeading ? `**Arguments**\n\n${content}` : content;
385
386
  };
386
387
  const context = {
387
388
  args: info.positionalArgs,
@@ -396,11 +397,11 @@ function createCommandRenderer(options = {}) {
396
397
  }
397
398
  }
398
399
  if (info.options.length > 0) {
399
- const renderOpts = (opts, renderOpts$1) => {
400
- const style = renderOpts$1?.style ?? optionStyle;
401
- const withHeading = renderOpts$1?.withHeading ?? true;
402
- const content$1 = style === "table" ? renderOptionsTableFromArray(opts) : renderOptionsListFromArray(opts);
403
- return withHeading ? `**Options**\n\n${content$1}` : content$1;
400
+ const renderOpts = (opts, renderOpts) => {
401
+ const style = renderOpts?.style ?? optionStyle;
402
+ const withHeading = renderOpts?.withHeading ?? true;
403
+ const content = style === "table" ? renderOptionsTableFromArray(opts) : renderOptionsListFromArray(opts);
404
+ return withHeading ? `**Options**\n\n${content}` : content;
404
405
  };
405
406
  const context = {
406
407
  options: info.options,
@@ -419,8 +420,8 @@ function createCommandRenderer(options = {}) {
419
420
  const renderSubs = (subs, opts) => {
420
421
  const anchors = opts?.generateAnchors ?? effectiveAnchors;
421
422
  const withHeading = opts?.withHeading ?? true;
422
- const content$1 = renderSubcommandsTableFromArray(subs, info, anchors);
423
- return withHeading ? `**Commands**\n\n${content$1}` : content$1;
423
+ const content = renderSubcommandsTableFromArray(subs, info, anchors);
424
+ return withHeading ? `**Commands**\n\n${content}` : content;
424
425
  };
425
426
  const context = {
426
427
  subcommands: info.subCommands,
@@ -437,8 +438,8 @@ function createCommandRenderer(options = {}) {
437
438
  if (info.examples && info.examples.length > 0) {
438
439
  const renderEx = (examples, results, opts) => {
439
440
  const withHeading = opts?.withHeading ?? true;
440
- const content$1 = renderExamplesDefault(examples, results, opts);
441
- return withHeading ? `**Examples**\n\n${content$1}` : content$1;
441
+ const content = renderExamplesDefault(examples, results, opts);
442
+ return withHeading ? `**Examples**\n\n${content}` : content;
442
443
  };
443
444
  const context = {
444
445
  examples: info.examples,
@@ -671,7 +672,7 @@ async function executeSingleExample(example, rootCommand, commandPath) {
671
672
  collector.start();
672
673
  let success = true;
673
674
  try {
674
- const { runCommand } = await Promise.resolve().then(() => require("../runner-pmoTWUXY.cjs"));
675
+ const { runCommand } = await Promise.resolve().then(() => require("../runner-BkhekqT9.cjs"));
675
676
  const result = await runCommand(rootCommand, argv);
676
677
  success = result.success;
677
678
  if (!result.success && result.error) console.error(result.error.message);
@@ -1206,6 +1207,225 @@ function initDocFile(config, fileSystem) {
1206
1207
  else for (const filePath of Object.keys(config.files)) deleteFile(filePath, fileSystem);
1207
1208
  }
1208
1209
 
1210
+ //#endregion
1211
+ //#region src/docs/render-args.ts
1212
+ /**
1213
+ * Extract ResolvedFieldMeta array from ArgsShape
1214
+ *
1215
+ * This converts a raw args shape (like `commonArgs`) into the
1216
+ * ResolvedFieldMeta format used by politty's rendering functions.
1217
+ */
1218
+ function extractArgsFields(args) {
1219
+ return require_schema_extractor.extractFields(zod.z.object(args)).fields;
1220
+ }
1221
+ /**
1222
+ * Render args definition as a markdown options table
1223
+ *
1224
+ * This function takes raw args definitions (like `commonArgs`) and
1225
+ * renders them as a markdown table suitable for documentation.
1226
+ *
1227
+ * @example
1228
+ * import { renderArgsTable } from "politty/docs";
1229
+ * import { commonArgs, workspaceArgs } from "./args";
1230
+ *
1231
+ * const table = renderArgsTable({
1232
+ * ...commonArgs,
1233
+ * ...workspaceArgs,
1234
+ * });
1235
+ * // | Option | Alias | Description | Default |
1236
+ * // |--------|-------|-------------|---------|
1237
+ * // | `--env-file <ENV_FILE>` | `-e` | Path to environment file | - |
1238
+ * // ...
1239
+ *
1240
+ * @param args - Args shape (Record of string keys to Zod schemas with arg() metadata)
1241
+ * @param options - Rendering options
1242
+ * @returns Rendered markdown table string
1243
+ */
1244
+ function renderArgsTable(args, options) {
1245
+ const optionFields = extractArgsFields(args).filter((f) => !f.positional);
1246
+ if (optionFields.length === 0) return "";
1247
+ if (options?.columns) return renderFilteredTable(optionFields, options.columns);
1248
+ return renderOptionsTableFromArray(optionFields);
1249
+ }
1250
+ /**
1251
+ * Escape markdown special characters in table cells
1252
+ */
1253
+ function escapeTableCell$1(str) {
1254
+ return str.replace(/\|/g, "\\|").replace(/\n/g, " ");
1255
+ }
1256
+ /**
1257
+ * Format default value for display
1258
+ */
1259
+ function formatDefaultValue(value) {
1260
+ if (value === void 0) return "-";
1261
+ return `\`${JSON.stringify(value)}\``;
1262
+ }
1263
+ /**
1264
+ * Render table with filtered columns
1265
+ */
1266
+ function renderFilteredTable(options, columns) {
1267
+ const lines = [];
1268
+ const headerCells = [];
1269
+ const separatorCells = [];
1270
+ for (const col of columns) switch (col) {
1271
+ case "option":
1272
+ headerCells.push("Option");
1273
+ separatorCells.push("------");
1274
+ break;
1275
+ case "alias":
1276
+ headerCells.push("Alias");
1277
+ separatorCells.push("-----");
1278
+ break;
1279
+ case "description":
1280
+ headerCells.push("Description");
1281
+ separatorCells.push("-----------");
1282
+ break;
1283
+ case "default":
1284
+ headerCells.push("Default");
1285
+ separatorCells.push("-------");
1286
+ break;
1287
+ case "env":
1288
+ headerCells.push("Env");
1289
+ separatorCells.push("---");
1290
+ break;
1291
+ }
1292
+ lines.push(`| ${headerCells.join(" | ")} |`);
1293
+ lines.push(`| ${separatorCells.join(" | ")} |`);
1294
+ for (const opt of options) {
1295
+ const cells = [];
1296
+ for (const col of columns) switch (col) {
1297
+ case "option": {
1298
+ const placeholder = opt.placeholder ?? opt.cliName.toUpperCase().replace(/-/g, "_");
1299
+ const optionName = opt.type === "boolean" ? `\`--${opt.cliName}\`` : `\`--${opt.cliName} <${placeholder}>\``;
1300
+ cells.push(optionName);
1301
+ break;
1302
+ }
1303
+ case "alias":
1304
+ cells.push(opt.alias ? `\`-${opt.alias}\`` : "-");
1305
+ break;
1306
+ case "description":
1307
+ cells.push(escapeTableCell$1(opt.description ?? ""));
1308
+ break;
1309
+ case "default":
1310
+ cells.push(formatDefaultValue(opt.defaultValue));
1311
+ break;
1312
+ case "env": {
1313
+ const envNames = opt.env ? Array.isArray(opt.env) ? opt.env.map((e) => `\`${e}\``).join(", ") : `\`${opt.env}\`` : "-";
1314
+ cells.push(envNames);
1315
+ break;
1316
+ }
1317
+ }
1318
+ lines.push(`| ${cells.join(" | ")} |`);
1319
+ }
1320
+ return lines.join("\n");
1321
+ }
1322
+
1323
+ //#endregion
1324
+ //#region src/docs/render-index.ts
1325
+ /**
1326
+ * Escape markdown special characters in table cells
1327
+ */
1328
+ function escapeTableCell(str) {
1329
+ return str.replace(/\|/g, "\\|").replace(/\n/g, " ");
1330
+ }
1331
+ /**
1332
+ * Generate anchor from command path
1333
+ */
1334
+ function generateAnchor(commandPath) {
1335
+ return commandPath.replace(/\s+/g, "-").toLowerCase();
1336
+ }
1337
+ /**
1338
+ * Check if a command is a leaf (has no subcommands)
1339
+ */
1340
+ function isLeafCommand(info) {
1341
+ return info.subCommands.length === 0;
1342
+ }
1343
+ /**
1344
+ * Expand commands to include their subcommands
1345
+ * If a command has subcommands, recursively find all commands under it
1346
+ *
1347
+ * @param commandPaths - Command paths to expand
1348
+ * @param allCommands - Map of all available commands
1349
+ * @param leafOnly - If true, only include leaf commands; if false, include all commands
1350
+ */
1351
+ function expandCommands(commandPaths, allCommands, leafOnly) {
1352
+ const result = [];
1353
+ for (const cmdPath of commandPaths) {
1354
+ const info = allCommands.get(cmdPath);
1355
+ if (!info) continue;
1356
+ if (isLeafCommand(info)) result.push(cmdPath);
1357
+ else for (const [path, pathInfo] of allCommands) if (cmdPath === "" ? path.length > 0 : path.startsWith(cmdPath + " ") || path === cmdPath) {
1358
+ if (isLeafCommand(pathInfo) || !leafOnly) result.push(path);
1359
+ }
1360
+ }
1361
+ return result;
1362
+ }
1363
+ /**
1364
+ * Render a single category section
1365
+ */
1366
+ function renderCategory(category, allCommands, headingLevel, leafOnly) {
1367
+ const h = "#".repeat(headingLevel);
1368
+ const lines = [];
1369
+ lines.push(`${h} [${category.title}](${category.docPath})`);
1370
+ lines.push("");
1371
+ lines.push(category.description);
1372
+ lines.push("");
1373
+ const commandPaths = expandCommands(category.commands, allCommands, leafOnly);
1374
+ lines.push("| Command | Description |");
1375
+ lines.push("|---------|-------------|");
1376
+ for (const cmdPath of commandPaths) {
1377
+ const info = allCommands.get(cmdPath);
1378
+ if (!info) continue;
1379
+ if (leafOnly && !isLeafCommand(info)) continue;
1380
+ const displayName = cmdPath || info.name;
1381
+ const anchor = generateAnchor(displayName);
1382
+ const desc = escapeTableCell(info.description ?? "");
1383
+ lines.push(`| [${displayName}](${category.docPath}#${anchor}) | ${desc} |`);
1384
+ }
1385
+ return lines.join("\n");
1386
+ }
1387
+ /**
1388
+ * Render command index from categories
1389
+ *
1390
+ * Generates a category-based index of commands with links to documentation.
1391
+ *
1392
+ * @example
1393
+ * const categories: CommandCategory[] = [
1394
+ * {
1395
+ * title: "Application Commands",
1396
+ * description: "Commands for managing applications.",
1397
+ * commands: ["init", "generate", "apply"],
1398
+ * docPath: "./cli/application.md",
1399
+ * },
1400
+ * ];
1401
+ *
1402
+ * const index = await renderCommandIndex(mainCommand, categories);
1403
+ * // ### [Application Commands](./cli/application.md)
1404
+ * //
1405
+ * // Commands for managing applications.
1406
+ * //
1407
+ * // | Command | Description |
1408
+ * // |---------|-------------|
1409
+ * // | [init](./cli/application.md#init) | Initialize a project |
1410
+ * // ...
1411
+ *
1412
+ * @param command - Root command to extract command information from
1413
+ * @param categories - Category definitions for grouping commands
1414
+ * @param options - Rendering options
1415
+ * @returns Rendered markdown string
1416
+ */
1417
+ async function renderCommandIndex(command, categories, options) {
1418
+ const headingLevel = options?.headingLevel ?? 3;
1419
+ const leafOnly = options?.leafOnly ?? true;
1420
+ const allCommands = await collectAllCommands(command);
1421
+ const sections = [];
1422
+ for (const category of categories) {
1423
+ const section = renderCategory(category, allCommands, headingLevel, leafOnly);
1424
+ sections.push(section);
1425
+ }
1426
+ return sections.join("\n\n");
1427
+ }
1428
+
1209
1429
  //#endregion
1210
1430
  exports.COMMAND_MARKER_PREFIX = COMMAND_MARKER_PREFIX;
1211
1431
  exports.UPDATE_GOLDEN_ENV = UPDATE_GOLDEN_ENV;
@@ -1222,10 +1442,12 @@ exports.executeExamples = executeExamples;
1222
1442
  exports.formatDiff = formatDiff;
1223
1443
  exports.generateDoc = generateDoc;
1224
1444
  exports.initDocFile = initDocFile;
1445
+ exports.renderArgsTable = renderArgsTable;
1225
1446
  exports.renderArgumentsList = renderArgumentsList;
1226
1447
  exports.renderArgumentsListFromArray = renderArgumentsListFromArray;
1227
1448
  exports.renderArgumentsTable = renderArgumentsTable;
1228
1449
  exports.renderArgumentsTableFromArray = renderArgumentsTableFromArray;
1450
+ exports.renderCommandIndex = renderCommandIndex;
1229
1451
  exports.renderExamplesDefault = renderExamplesDefault;
1230
1452
  exports.renderOptionsList = renderOptionsList;
1231
1453
  exports.renderOptionsListFromArray = renderOptionsListFromArray;