mdat-plugin-cli-help 2.1.2 → 3.0.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.
package/dist/index.d.ts CHANGED
@@ -7,7 +7,7 @@ import { ILogBasic, ILogLayer } from "lognow";
7
7
  * Export this for library consumers to inject their own logger.
8
8
  * @param logger - Accepts either a LogLayer instance or a Console- or Stream-like log target
9
9
  */
10
- declare function setLogger(logger?: ILogBasic | ILogLayer): void;
10
+ declare function setLogger(logger?: ILogBasic | ILogLayer<unknown>): void;
11
11
  //#endregion
12
12
  //#region src/index.d.ts
13
13
  declare const _default: _$mdat.Config;
package/dist/index.js CHANGED
@@ -382,25 +382,25 @@ var CliHelpToObjectVisitor$2 = class extends parser$2.getBaseCstVisitorConstruct
382
382
  * Clean a Commander default value: strip `(default: ...)` wrapper, env info, and quotes.
383
383
  */
384
384
  cleanDefault(text) {
385
- if (text === void 0) return void 0;
385
+ if (text === void 0) return;
386
386
  let cleaned = text.replaceAll(/^\(default:\s*/g, "").replaceAll(/\)$/g, "").trim();
387
387
  cleaned = cleaned.replaceAll(/,\s*env:\s*\S+$/g, "").trim();
388
388
  cleaned = cleaned.replaceAll(/^["']|["']$/g, "");
389
389
  return cleaned || void 0;
390
390
  }
391
391
  getArray(context) {
392
- if (context === void 0) return void 0;
392
+ if (context === void 0) return;
393
393
  return context.map((entry) => entry.image);
394
394
  }
395
395
  getString(context) {
396
- if (context === void 0) return void 0;
396
+ if (context === void 0) return;
397
397
  return context.map((entry) => entry.image).join(" ");
398
398
  }
399
399
  /**
400
400
  * Trim leading/trailing whitespace from description text.
401
401
  */
402
402
  trimDescription(text) {
403
- if (text === void 0) return void 0;
403
+ if (text === void 0) return;
404
404
  return text.trim() || void 0;
405
405
  }
406
406
  };
@@ -647,11 +647,11 @@ var CliHelpToObjectVisitor$1 = class extends parser$1.getBaseCstVisitorConstruct
647
647
  return text.replaceAll(/^[\s[]*(default:)?\s*|[\s\]]*$/g, "");
648
648
  }
649
649
  getArray(context) {
650
- if (context === void 0) return void 0;
650
+ if (context === void 0) return;
651
651
  return context.map((entry) => entry.image);
652
652
  }
653
653
  getString(context, clean = false) {
654
- if (context === void 0) return void 0;
654
+ if (context === void 0) return;
655
655
  return context.map((entry) => clean ? this.clean(entry.image) : entry.image).join(" ");
656
656
  }
657
657
  };
@@ -950,11 +950,11 @@ var CliHelpToObjectVisitor = class extends parser.getBaseCstVisitorConstructor()
950
950
  return text.replaceAll(/^[\s[]*(default:)?\s*|[\s\]]*$/g, "");
951
951
  }
952
952
  getArray(context) {
953
- if (context === void 0) return void 0;
953
+ if (context === void 0) return;
954
954
  return context.map((entry) => entry.image);
955
955
  }
956
956
  getString(context, clean = false) {
957
- if (context === void 0) return void 0;
957
+ if (context === void 0) return;
958
958
  return context.map((entry) => clean ? this.clean(entry.image) : entry.image).join(" ");
959
959
  }
960
960
  positionalParentCommandToArguments(object) {
@@ -966,7 +966,7 @@ var CliHelpToObjectVisitor = class extends parser.getBaseCstVisitorConstructor()
966
966
  };
967
967
  }
968
968
  splitChoices(text) {
969
- if (text === void 0) return void 0;
969
+ if (text === void 0) return;
970
970
  return this.clean(text.replaceAll(/^\[choices:\s/g, "")).split(", ");
971
971
  }
972
972
  };
@@ -1073,12 +1073,15 @@ function helpStringToObject(helpString) {
1073
1073
  /**
1074
1074
  * Get help output from a CLI command and return it as markdown
1075
1075
  *
1076
- * @param cliCommand - The executable path (may contain spaces, e.g. on Windows)
1076
+ * @param command - The executable path (may contain spaces, e.g. on Windows)
1077
1077
  * @param helpFlag - The flag to pass to get help output
1078
1078
  * @param depth - Max recursion depth for subcommands
1079
+ * @param subcommands - Initial subcommand path to invoke before the help flag
1080
+ * (e.g. `['remote', 'add']` produces `command remote add --help`).
1081
+ * Discovered subcommands are appended to this path during recursion.
1079
1082
  */
1080
- async function getHelpMarkdown(cliCommand, helpFlag = "--help", depth) {
1081
- return getHelpMarkdownInternal(cliCommand, [], helpFlag, depth ?? Number.MAX_SAFE_INTEGER);
1083
+ async function getHelpMarkdown(command, helpFlag = "--help", depth, subcommands = []) {
1084
+ return getHelpMarkdownInternal(command, subcommands, helpFlag, depth ?? Number.MAX_SAFE_INTEGER);
1082
1085
  }
1083
1086
  async function getHelpMarkdownInternal(executable, subcommands, helpFlag, depth) {
1084
1087
  const rawHelpString = await getHelpString(executable, [...subcommands, helpFlag]);
@@ -1152,16 +1155,16 @@ async function isExecutable(filePath, strictExtensions = false) {
1152
1155
  //#region src/utilities/infer-command.ts
1153
1156
  /**
1154
1157
  * Accommodate missing or sloppy cli help command input
1155
- * @param cliCommand - Can be nothing, a command name on the path like `git`, or a path to an executable like `./bin/cli.js`
1158
+ * @param command - Can be nothing, a command name on the path like `git`, or a path to an executable like `./bin/cli.js`
1156
1159
  * @returns The path to a verified executable
1157
1160
  * @throws {Error} If nothing can be inferred or resolved
1158
1161
  */
1159
- async function inferCommand(cliCommand) {
1160
- cliCommand ??= await getFirstBinFromPackage();
1161
- return ensureExecutable(cliCommand);
1162
+ async function inferCommand(command) {
1163
+ command ??= await getFirstBinFromPackage();
1164
+ return ensureExecutable(command);
1162
1165
  }
1163
1166
  function firstOf(value) {
1164
- if (value === void 0) return void 0;
1167
+ if (value === void 0) return;
1165
1168
  return Array.isArray(value) ? value[0] : value;
1166
1169
  }
1167
1170
  async function getFirstBinFromPackage() {
@@ -1176,7 +1179,7 @@ async function getFirstBinFromPackage() {
1176
1179
  return binPath;
1177
1180
  }
1178
1181
  }
1179
- throw new Error(`Could not infer which command to run for the <!-- cli-help --> rule. Please pass a "cliCommand" option to the expansion comment, e.g. <!-- cli-help({cliCommand: './dist/bin.js'}) -->`);
1182
+ throw new Error(`Could not infer which command to run for the <!-- cli-help --> rule. Please pass a "command" option to the expansion comment, e.g. <!-- cli-help({command: './dist/bin.js'}) -->`);
1180
1183
  }
1181
1184
  function looksLikePath(maybePath) {
1182
1185
  const parsed = path.parse(maybePath);
@@ -1202,13 +1205,17 @@ async function getCommandPathFromPackage(commandName) {
1202
1205
  }
1203
1206
  //#endregion
1204
1207
  //#region src/index.ts
1208
+ const WHITESPACE_REGEX = /\s+/;
1205
1209
  const cliHelpRule = defineConfig({ cli: { async content(options, _context) {
1206
1210
  const validOptions = z.object({
1207
- cliCommand: z.string().optional(),
1211
+ command: z.string().optional(),
1208
1212
  depth: z.number().optional(),
1209
- helpFlag: z.string().optional()
1210
- }).optional().parse(options);
1211
- return getHelpMarkdown(await inferCommand(validOptions?.cliCommand), validOptions?.helpFlag, validOptions?.depth);
1213
+ helpFlag: z.string().optional(),
1214
+ subcommand: z.string().optional()
1215
+ }).strict().optional().parse(options);
1216
+ const resolvedCommand = await inferCommand(validOptions?.command);
1217
+ const subcommands = validOptions?.subcommand?.split(WHITESPACE_REGEX).filter(Boolean) ?? [];
1218
+ return getHelpMarkdown(resolvedCommand, validOptions?.helpFlag, validOptions?.depth, subcommands);
1212
1219
  } } });
1213
1220
  var src_default = defineConfig({
1214
1221
  cli: cliHelpRule.cli,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mdat-plugin-cli-help",
3
- "version": "2.1.2",
3
+ "version": "3.0.0",
4
4
  "description": "Mdat plugin to generate tabular help documentation for CLI tools in Markdown files.",
5
5
  "keywords": [
6
6
  "markdown",
@@ -39,21 +39,22 @@
39
39
  "chevrotain": "^12.0.0",
40
40
  "execa": "^9.6.1",
41
41
  "lognow": "^0.6.1",
42
- "type-fest": "^5.5.0",
42
+ "type-fest": "^5.6.0",
43
43
  "which": "^6.0.1",
44
44
  "zod": "^4.3.6"
45
45
  },
46
46
  "devDependencies": {
47
- "@kitschpatrol/shared-config": "^7.1.0",
47
+ "@kitschpatrol/shared-config": "^7.5.0",
48
48
  "@types/node": "~22.17.2",
49
49
  "@types/yargs": "^17.0.35",
50
50
  "bumpp": "^11.0.1",
51
51
  "commander": "^14.0.3",
52
- "mdat": "^2.2.1",
52
+ "mdat": "^2.3.0",
53
53
  "meow": "^14.1.0",
54
- "tsdown": "^0.21.7",
54
+ "shx": "^0.4.0",
55
+ "tsdown": "^0.21.10",
55
56
  "typescript": "~5.9.3",
56
- "vitest": "^4.1.3",
57
+ "vitest": "^4.1.5",
57
58
  "yargs": "^18.0.0"
58
59
  },
59
60
  "peerDependencies": {
@@ -72,10 +73,10 @@
72
73
  "bench": "vitest bench --run --no-file-parallelism --compare test/benchmarks/baseline.json",
73
74
  "bench:baseline": "vitest bench --run --no-file-parallelism --outputJson test/benchmarks/baseline.json",
74
75
  "build": "tsdown --no-fixed-extension --tsconfig tsconfig.build.json",
75
- "clean": "git rm -f pnpm-lock.yaml ; git clean -fdX",
76
+ "clean": "shx rm -f pnpm-lock.yaml && git clean -fdX -e !.claude/",
76
77
  "fix": "ksc fix",
77
78
  "lint": "ksc lint",
78
- "release": "bumpp --commit 'Release: %s' && pnpm run build && NPM_AUTH_TOKEN=$(op read 'op://Personal/npm/token') && pnpm publish",
79
+ "release": "bumpp --commit 'Release: %s' && pnpm build && NPM_AUTH_TOKEN=$(op read 'op://Personal/npm/token') && pnpm publish",
79
80
  "test": "vitest run --no-file-parallelism"
80
81
  }
81
82
  }
package/readme.md CHANGED
@@ -58,13 +58,13 @@ export default defineConfig({
58
58
  Assuming you have an executable with a `--help` flag on your path or in your project's scope:
59
59
 
60
60
  ```markdown
61
- <!-- cli-help({ cliCommand: "mdat", depth: 1 }) -->
61
+ <!-- cli-help({ command: "mdat", depth: 1 }) -->
62
62
  ```
63
63
 
64
64
  Then run the `mdat` CLI command on your Markdown file to expand the rule and embed the tabular help output:
65
65
 
66
66
  ````markdown
67
- <!-- cli-help({ cliCommand: "mdat", depth: 1 }) -->
67
+ <!-- cli-help({ command: "mdat", depth: 1 }) -->
68
68
 
69
69
  #### Command: `mdat`
70
70
 
@@ -105,12 +105,20 @@ mdat [command]
105
105
  <!-- /cli-help -->
106
106
  ````
107
107
 
108
+ To generate help for a specific subcommand, pass `subcommand`. Whitespace-separated for nested paths:
109
+
110
+ ```markdown
111
+ <!-- cli-help({ command: "mdat", subcommand: "readme", depth: 1 }) -->
112
+ ```
113
+
114
+ This invokes `mdat readme --help`. Discovered sub-subcommands are appended to this path during recursion.
115
+
108
116
  The command is also aliased under the `<!-- cli -->` keyword.
109
117
 
110
118
  This would have equivalent output to the above:
111
119
 
112
120
  ```markdown
113
- <!-- cli({ cliCommand: "mdat", depth: 1 }) -->
121
+ <!-- cli({ command: "mdat", depth: 1 }) -->
114
122
  ```
115
123
 
116
124
  If you embed the rule without any arguments, it will look for the binary file listed in the closest `package.json` file and run it with `--help`. This is what you want if you're documenting a package's CLI options in its readme.md file:
@@ -157,13 +165,17 @@ Currently, the parser implementation lives in this repository because I really o
157
165
 
158
166
  ## Maintainers
159
167
 
160
- [@kitschpatrol](https://github.com/kitschpatrol)
168
+ [kitschpatrol](https://github.com/kitschpatrol)
161
169
 
162
170
  <!-- contributing -->
163
171
 
164
172
  ## Contributing
165
173
 
166
- [Issues](https://github.com/kitschpatrol/mdat-plugin-cli-help/issues) and pull requests are welcome.
174
+ [Issues](https://github.com/kitschpatrol/mdat-plugin-cli-help/issues) are welcome and appreciated.
175
+
176
+ Please open an issue to discuss changes before submitting a pull request. Unsolicited PRs (especially AI-generated ones) are unlikely to be merged.
177
+
178
+ This repository uses [@kitschpatrol/shared-config](https://github.com/kitschpatrol/shared-config) (via its `ksc` CLI) for linting and formatting, plus [MDAT](https://github.com/kitschpatrol/mdat) for readme placeholder expansion.
167
179
 
168
180
  <!-- /contributing -->
169
181
 
@@ -171,6 +183,6 @@ Currently, the parser implementation lives in this repository because I really o
171
183
 
172
184
  ## License
173
185
 
174
- [MIT](license.txt) © Eric Mika
186
+ [MIT](license.txt) © [Eric Mika](https://ericmika.com)
175
187
 
176
188
  <!-- /license -->