@hydranium/cli 1.0.0-next.212 → 1.0.0-next.213

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 (42) hide show
  1. package/README.md +8 -0
  2. package/lib/commands/ast-ground-truth-args.d.ts +3 -2
  3. package/lib/commands/ast-ground-truth-args.d.ts.map +1 -1
  4. package/lib/commands/ast-ground-truth-args.js +9 -7
  5. package/lib/commands/ast-ground-truth-args.js.map +1 -1
  6. package/lib/commands/harness-args.d.ts +18 -7
  7. package/lib/commands/harness-args.d.ts.map +1 -1
  8. package/lib/commands/harness-args.js +31 -13
  9. package/lib/commands/harness-args.js.map +1 -1
  10. package/lib/commands/headless-harness.d.ts +5 -2
  11. package/lib/commands/headless-harness.d.ts.map +1 -1
  12. package/lib/commands/headless-harness.js +50 -7
  13. package/lib/commands/headless-harness.js.map +1 -1
  14. package/lib/commands/lint-grammar-args.d.ts +3 -2
  15. package/lib/commands/lint-grammar-args.d.ts.map +1 -1
  16. package/lib/commands/lint-grammar-args.js +10 -7
  17. package/lib/commands/lint-grammar-args.js.map +1 -1
  18. package/lib/commands/measure-memory-args.d.ts +3 -2
  19. package/lib/commands/measure-memory-args.d.ts.map +1 -1
  20. package/lib/commands/measure-memory-args.js +10 -7
  21. package/lib/commands/measure-memory-args.js.map +1 -1
  22. package/lib/commands/model-docs-args.d.ts +4 -3
  23. package/lib/commands/model-docs-args.d.ts.map +1 -1
  24. package/lib/commands/model-docs-args.js +10 -8
  25. package/lib/commands/model-docs-args.js.map +1 -1
  26. package/lib/commands/reflect-args.d.ts +3 -2
  27. package/lib/commands/reflect-args.d.ts.map +1 -1
  28. package/lib/commands/reflect-args.js +10 -7
  29. package/lib/commands/reflect-args.js.map +1 -1
  30. package/lib/commands/validate-args.d.ts +3 -2
  31. package/lib/commands/validate-args.d.ts.map +1 -1
  32. package/lib/commands/validate-args.js +10 -7
  33. package/lib/commands/validate-args.js.map +1 -1
  34. package/package.json +9 -9
  35. package/src/commands/ast-ground-truth-args.ts +10 -7
  36. package/src/commands/harness-args.ts +36 -14
  37. package/src/commands/headless-harness.ts +54 -7
  38. package/src/commands/lint-grammar-args.ts +11 -7
  39. package/src/commands/measure-memory-args.ts +11 -7
  40. package/src/commands/model-docs-args.ts +11 -8
  41. package/src/commands/reflect-args.ts +11 -7
  42. package/src/commands/validate-args.ts +11 -7
@@ -1 +1 @@
1
- {"version":3,"file":"measure-memory-args.js","sourceRoot":"","sources":["../../src/commands/measure-memory-args.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"measure-memory-args.js","sourceRoot":"","sources":["../../src/commands/measure-memory-args.ts"],"names":[],"mappings":"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"}
@@ -9,9 +9,10 @@
9
9
  import { type UsageError } from './harness-args.js';
10
10
  import { type ModelDocsCommandOptions } from './model-docs.js';
11
11
  /**
12
- * Every flag `model-docs` accepts, derived from the sets the parser is handed so
13
- * the list cannot claim a flag the parser would reject. `--services` is consumed
14
- * by the shared harness parser itself, so it is in neither set.
12
+ * Every flag `model-docs` accepts, derived from the sets the parser is handed
13
+ * so the list cannot claim a flag the parser would reject.
14
+ * {@link HARNESS_VALUE_FLAGS} are consumed by the shared harness parser itself,
15
+ * so they are in neither set.
15
16
  */
16
17
  export declare const MODEL_DOCS_FLAGS: readonly string[];
17
18
  /** The subset that takes a value, so `--help` in a value position reads as data. */
@@ -1 +1 @@
1
- {"version":3,"file":"model-docs-args.d.ts","sourceRoot":"","sources":["../../src/commands/model-docs-args.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EASJ,KAAK,UAAU,EACjB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAgB,KAAK,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAI7E;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,EAAE,SAAS,MAAM,EAAoC,CAAC;AAEnF,oFAAoF;AACpF,eAAO,MAAM,sBAAsB,EAAE,SAAS,MAAM,EAAqB,CAAC;AAE1E,8EAA8E;AAC9E,eAAO,MAAM,eAAe,EAAE,SAAS,MAAM,EAgB5C,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,GAAE,UAA0B,GAAG,uBAAuB,CAM/G;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAMjE"}
1
+ {"version":3,"file":"model-docs-args.d.ts","sourceRoot":"","sources":["../../src/commands/model-docs-args.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAUJ,KAAK,UAAU,EACjB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAgB,KAAK,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAI7E;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,EAAE,SAAS,MAAM,EAA6C,CAAC;AAE5F,oFAAoF;AACpF,eAAO,MAAM,sBAAsB,EAAE,SAAS,MAAM,EAAqB,CAAC;AAE1E,8EAA8E;AAC9E,eAAO,MAAM,eAAe,EAAE,SAAS,MAAM,EAiB5C,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,GAAE,UAA0B,GAAG,uBAAuB,CAM/G;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAMjE"}
@@ -6,21 +6,22 @@
6
6
  *
7
7
  * SPDX-License-Identifier: MIT
8
8
  ********************************************************************************/
9
- import { exitWithUsage, helpRequested, LOG_VALUE_FLAGS, logHelpLines, logOptions, parseHarnessArgs, printHelp, SERVICES_FLAG } from './harness-args.js';
9
+ import { exitWithUsage, HARNESS_VALUE_FLAGS, helpRequested, importHelpLines, LOG_VALUE_FLAGS, logHelpLines, logOptions, parseHarnessArgs, printHelp } from './harness-args.js';
10
10
  import { OUT_FILE_FLAG } from './headless-harness.js';
11
11
  import { runModelDocs } from './model-docs.js';
12
12
  const VALUE_FLAGS = [OUT_FILE_FLAG, ...LOG_VALUE_FLAGS];
13
13
  /**
14
- * Every flag `model-docs` accepts, derived from the sets the parser is handed so
15
- * the list cannot claim a flag the parser would reject. `--services` is consumed
16
- * by the shared harness parser itself, so it is in neither set.
14
+ * Every flag `model-docs` accepts, derived from the sets the parser is handed
15
+ * so the list cannot claim a flag the parser would reject.
16
+ * {@link HARNESS_VALUE_FLAGS} are consumed by the shared harness parser itself,
17
+ * so they are in neither set.
17
18
  */
18
- export const MODEL_DOCS_FLAGS = [SERVICES_FLAG, ...VALUE_FLAGS];
19
+ export const MODEL_DOCS_FLAGS = [...HARNESS_VALUE_FLAGS, ...VALUE_FLAGS];
19
20
  /** The subset that takes a value, so `--help` in a value position reads as data. */
20
21
  export const MODEL_DOCS_VALUE_FLAGS = MODEL_DOCS_FLAGS;
21
22
  /** The `--help` text, as data, held to {@link MODEL_DOCS_FLAGS} by a test. */
22
23
  export const MODEL_DOCS_HELP = [
23
- 'Usage: hydranium-cli model-docs --services <module> [--out-file <file>] [--log-level <lvl>] [--log-file <file>] [--log-file-level <lvl>]',
24
+ 'Usage: hydranium-cli model-docs --services <module> [--import <specifier>]... [--out-file <file>] [--log-level <lvl>] [--log-file <file>] [--log-file-level <lvl>]',
24
25
  '',
25
26
  'Generate a navigable Markdown reference of every AST node type — a type index,',
26
27
  'cross-linked super/sub types, a reverse "referenced by" index, and a per-language',
@@ -31,17 +32,18 @@ export const MODEL_DOCS_HELP = [
31
32
  '',
32
33
  'Options:',
33
34
  ' --services <module> ESM module exporting `createServices(): { shared }` (required).',
35
+ ...importHelpLines(22),
34
36
  ' --out-file <file> Write the Markdown to this file instead of stdout. Written',
35
37
  ' only once the report exists, unlike a shell redirection,',
36
38
  ' which truncates the file before the head is even booted.',
37
39
  ...logHelpLines(22)
38
40
  ];
39
41
  export function parseModelDocsArgs(args, onError = exitWithUsage) {
40
- const { servicesModule, options } = parseHarnessArgs(args, 'model-docs', VALUE_FLAGS, [], {
42
+ const { servicesModule, imports, options } = parseHarnessArgs(args, 'model-docs', VALUE_FLAGS, [], {
41
43
  requireWorkspace: false,
42
44
  onError
43
45
  });
44
- return { servicesModule, outFile: options[OUT_FILE_FLAG], ...logOptions(options) };
46
+ return { servicesModule, imports, outFile: options[OUT_FILE_FLAG], ...logOptions(options) };
45
47
  }
46
48
  export function runModelDocsCommand(args) {
47
49
  if (helpRequested(args, MODEL_DOCS_VALUE_FLAGS)) {
@@ -1 +1 @@
1
- {"version":3,"file":"model-docs-args.js","sourceRoot":"","sources":["../../src/commands/model-docs-args.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EACJ,aAAa,EACb,aAAa,EACb,eAAe,EACf,YAAY,EACZ,UAAU,EACV,gBAAgB,EAChB,SAAS,EACT,aAAa,EAEf,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAgC,MAAM,iBAAiB,CAAC;AAE7E,MAAM,WAAW,GAAG,CAAC,aAAa,EAAE,GAAG,eAAe,CAAU,CAAC;AAEjE;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAsB,CAAC,aAAa,EAAE,GAAG,WAAW,CAAC,CAAC;AAEnF,oFAAoF;AACpF,MAAM,CAAC,MAAM,sBAAsB,GAAsB,gBAAgB,CAAC;AAE1E,8EAA8E;AAC9E,MAAM,CAAC,MAAM,eAAe,GAAsB;IAC/C,0IAA0I;IAC1I,EAAE;IACF,gFAAgF;IAChF,mFAAmF;IACnF,gFAAgF;IAChF,kFAAkF;IAClF,4EAA4E;IAC5E,uEAAuE;IACvE,EAAE;IACF,UAAU;IACV,yFAAyF;IACzF,oFAAoF;IACpF,kFAAkF;IAClF,kFAAkF;IAClF,GAAG,YAAY,CAAC,EAAE,CAAC;CACrB,CAAC;AAEF,MAAM,UAAU,kBAAkB,CAAC,IAAc,EAAE,OAAO,GAAe,aAAa;IACnF,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,GAAG,gBAAgB,CAAC,IAAI,EAAE,YAAY,EAAE,WAAW,EAAE,EAAE,EAAE;QACvF,gBAAgB,EAAE,KAAK;QACvB,OAAO;KACT,CAAC,CAAC;IACH,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,EAAE,GAAG,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;AACtF,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,IAAc;IAC/C,IAAI,aAAa,CAAC,IAAI,EAAE,sBAAsB,CAAC,EAAE,CAAC;QAC/C,SAAS,CAAC,eAAe,CAAC,CAAC;QAC3B,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC5B,CAAC;IACD,OAAO,YAAY,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC;AACjD,CAAC"}
1
+ {"version":3,"file":"model-docs-args.js","sourceRoot":"","sources":["../../src/commands/model-docs-args.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EACJ,aAAa,EACb,mBAAmB,EACnB,aAAa,EACb,eAAe,EACf,eAAe,EACf,YAAY,EACZ,UAAU,EACV,gBAAgB,EAChB,SAAS,EAEX,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAgC,MAAM,iBAAiB,CAAC;AAE7E,MAAM,WAAW,GAAG,CAAC,aAAa,EAAE,GAAG,eAAe,CAAU,CAAC;AAEjE;;;;;GAKG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAsB,CAAC,GAAG,mBAAmB,EAAE,GAAG,WAAW,CAAC,CAAC;AAE5F,oFAAoF;AACpF,MAAM,CAAC,MAAM,sBAAsB,GAAsB,gBAAgB,CAAC;AAE1E,8EAA8E;AAC9E,MAAM,CAAC,MAAM,eAAe,GAAsB;IAC/C,oKAAoK;IACpK,EAAE;IACF,gFAAgF;IAChF,mFAAmF;IACnF,gFAAgF;IAChF,kFAAkF;IAClF,4EAA4E;IAC5E,uEAAuE;IACvE,EAAE;IACF,UAAU;IACV,yFAAyF;IACzF,GAAG,eAAe,CAAC,EAAE,CAAC;IACtB,oFAAoF;IACpF,kFAAkF;IAClF,kFAAkF;IAClF,GAAG,YAAY,CAAC,EAAE,CAAC;CACrB,CAAC;AAEF,MAAM,UAAU,kBAAkB,CAAC,IAAc,EAAE,OAAO,GAAe,aAAa;IACnF,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,gBAAgB,CAAC,IAAI,EAAE,YAAY,EAAE,WAAW,EAAE,EAAE,EAAE;QAChG,gBAAgB,EAAE,KAAK;QACvB,OAAO;KACT,CAAC,CAAC;IACH,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,EAAE,GAAG,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;AAC/F,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,IAAc;IAC/C,IAAI,aAAa,CAAC,IAAI,EAAE,sBAAsB,CAAC,EAAE,CAAC;QAC/C,SAAS,CAAC,eAAe,CAAC,CAAC;QAC3B,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC5B,CAAC;IACD,OAAO,YAAY,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC;AACjD,CAAC"}
@@ -10,8 +10,9 @@ import { type UsageError } from './harness-args.js';
10
10
  import { type ReflectCommandOptions } from './reflect.js';
11
11
  /**
12
12
  * Every flag `reflect` accepts, derived from the sets the parser is handed so
13
- * the list cannot claim a flag the parser would reject. `--services` is consumed
14
- * by the shared harness parser itself, so it is in neither set.
13
+ * the list cannot claim a flag the parser would reject.
14
+ * {@link HARNESS_VALUE_FLAGS} are consumed by the shared harness parser itself,
15
+ * so they are in neither set.
15
16
  */
16
17
  export declare const REFLECT_FLAGS: readonly string[];
17
18
  /** The subset that takes a value, so `--help` in a value position reads as data. */
@@ -1 +1 @@
1
- {"version":3,"file":"reflect-args.d.ts","sourceRoot":"","sources":["../../src/commands/reflect-args.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EASJ,KAAK,UAAU,EACjB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAc,KAAK,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAKtE;;;;GAIG;AACH,eAAO,MAAM,aAAa,EAAE,SAAS,MAAM,EAAmD,CAAC;AAE/F,oFAAoF;AACpF,eAAO,MAAM,mBAAmB,EAAE,SAAS,MAAM,EAAoC,CAAC;AAEtF,2EAA2E;AAC3E,eAAO,MAAM,YAAY,EAAE,SAAS,MAAM,EAgBzC,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,GAAE,UAA0B,GAAG,qBAAqB,CAW3G;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAM/D"}
1
+ {"version":3,"file":"reflect-args.d.ts","sourceRoot":"","sources":["../../src/commands/reflect-args.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAUJ,KAAK,UAAU,EACjB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAc,KAAK,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAKtE;;;;;GAKG;AACH,eAAO,MAAM,aAAa,EAAE,SAAS,MAAM,EAA4D,CAAC;AAExG,oFAAoF;AACpF,eAAO,MAAM,mBAAmB,EAAE,SAAS,MAAM,EAA6C,CAAC;AAE/F,2EAA2E;AAC3E,eAAO,MAAM,YAAY,EAAE,SAAS,MAAM,EAiBzC,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,GAAE,UAA0B,GAAG,qBAAqB,CAY3G;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAM/D"}
@@ -6,22 +6,23 @@
6
6
  *
7
7
  * SPDX-License-Identifier: MIT
8
8
  ********************************************************************************/
9
- import { exitWithUsage, helpRequested, LOG_VALUE_FLAGS, logHelpLines, logOptions, parseHarnessArgs, printHelp, SERVICES_FLAG } from './harness-args.js';
9
+ import { exitWithUsage, HARNESS_VALUE_FLAGS, helpRequested, importHelpLines, LOG_VALUE_FLAGS, logHelpLines, logOptions, parseHarnessArgs, printHelp } from './harness-args.js';
10
10
  import { OUT_FILE_FLAG } from './headless-harness.js';
11
11
  import { runReflect } from './reflect.js';
12
12
  const VALUE_FLAGS = [OUT_FILE_FLAG, ...LOG_VALUE_FLAGS];
13
13
  const BOOL_FLAGS = ['--json'];
14
14
  /**
15
15
  * Every flag `reflect` accepts, derived from the sets the parser is handed so
16
- * the list cannot claim a flag the parser would reject. `--services` is consumed
17
- * by the shared harness parser itself, so it is in neither set.
16
+ * the list cannot claim a flag the parser would reject.
17
+ * {@link HARNESS_VALUE_FLAGS} are consumed by the shared harness parser itself,
18
+ * so they are in neither set.
18
19
  */
19
- export const REFLECT_FLAGS = [SERVICES_FLAG, ...VALUE_FLAGS, ...BOOL_FLAGS];
20
+ export const REFLECT_FLAGS = [...HARNESS_VALUE_FLAGS, ...VALUE_FLAGS, ...BOOL_FLAGS];
20
21
  /** The subset that takes a value, so `--help` in a value position reads as data. */
21
- export const REFLECT_VALUE_FLAGS = [SERVICES_FLAG, ...VALUE_FLAGS];
22
+ export const REFLECT_VALUE_FLAGS = [...HARNESS_VALUE_FLAGS, ...VALUE_FLAGS];
22
23
  /** The `--help` text, as data, held to {@link REFLECT_FLAGS} by a test. */
23
24
  export const REFLECT_HELP = [
24
- 'Usage: hydranium-cli reflect --services <module> [--json] [--out-file <file>] [--log-level <lvl>] [--log-file <file>] [--log-file-level <lvl>]',
25
+ 'Usage: hydranium-cli reflect --services <module> [--import <specifier>]... [--json] [--out-file <file>] [--log-level <lvl>] [--log-file <file>] [--log-file-level <lvl>]',
25
26
  '',
26
27
  "Dump a head's grammar/AST reflection — the type hierarchy, each language's",
27
28
  'terminals and entry rule, and every cross-reference target. Read-only: no',
@@ -31,6 +32,7 @@ export const REFLECT_HELP = [
31
32
  '',
32
33
  'Options:',
33
34
  ' --services <module> ESM module exporting `createServices(): { shared }` (required).',
35
+ ...importHelpLines(22),
34
36
  ' --json Emit the raw JSON reflection instead of the Markdown report.',
35
37
  ' --out-file <file> Write the report to this file instead of stdout. Written',
36
38
  ' only once the report exists, unlike a shell redirection,',
@@ -38,12 +40,13 @@ export const REFLECT_HELP = [
38
40
  ...logHelpLines(22)
39
41
  ];
40
42
  export function parseReflectArgs(args, onError = exitWithUsage) {
41
- const { servicesModule, options } = parseHarnessArgs(args, 'reflect', VALUE_FLAGS, BOOL_FLAGS, {
43
+ const { servicesModule, imports, options } = parseHarnessArgs(args, 'reflect', VALUE_FLAGS, BOOL_FLAGS, {
42
44
  requireWorkspace: false,
43
45
  onError
44
46
  });
45
47
  return {
46
48
  servicesModule,
49
+ imports,
47
50
  json: options['--json'] === 'true',
48
51
  outFile: options[OUT_FILE_FLAG],
49
52
  ...logOptions(options)
@@ -1 +1 @@
1
- {"version":3,"file":"reflect-args.js","sourceRoot":"","sources":["../../src/commands/reflect-args.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EACJ,aAAa,EACb,aAAa,EACb,eAAe,EACf,YAAY,EACZ,UAAU,EACV,gBAAgB,EAChB,SAAS,EACT,aAAa,EAEf,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,UAAU,EAA8B,MAAM,cAAc,CAAC;AAEtE,MAAM,WAAW,GAAG,CAAC,aAAa,EAAE,GAAG,eAAe,CAAU,CAAC;AACjE,MAAM,UAAU,GAAG,CAAC,QAAQ,CAAU,CAAC;AAEvC;;;;GAIG;AACH,MAAM,CAAC,MAAM,aAAa,GAAsB,CAAC,aAAa,EAAE,GAAG,WAAW,EAAE,GAAG,UAAU,CAAC,CAAC;AAE/F,oFAAoF;AACpF,MAAM,CAAC,MAAM,mBAAmB,GAAsB,CAAC,aAAa,EAAE,GAAG,WAAW,CAAC,CAAC;AAEtF,2EAA2E;AAC3E,MAAM,CAAC,MAAM,YAAY,GAAsB;IAC5C,gJAAgJ;IAChJ,EAAE;IACF,4EAA4E;IAC5E,2EAA2E;IAC3E,0EAA0E;IAC1E,6EAA6E;IAC7E,mFAAmF;IACnF,EAAE;IACF,UAAU;IACV,yFAAyF;IACzF,sFAAsF;IACtF,kFAAkF;IAClF,kFAAkF;IAClF,kFAAkF;IAClF,GAAG,YAAY,CAAC,EAAE,CAAC;CACrB,CAAC;AAEF,MAAM,UAAU,gBAAgB,CAAC,IAAc,EAAE,OAAO,GAAe,aAAa;IACjF,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,GAAG,gBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE;QAC5F,gBAAgB,EAAE,KAAK;QACvB,OAAO;KACT,CAAC,CAAC;IACH,OAAO;QACJ,cAAc;QACd,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,KAAK,MAAM;QAClC,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC;QAC/B,GAAG,UAAU,CAAC,OAAO,CAAC;KACxB,CAAC;AACL,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAc;IAC7C,IAAI,aAAa,CAAC,IAAI,EAAE,mBAAmB,CAAC,EAAE,CAAC;QAC5C,SAAS,CAAC,YAAY,CAAC,CAAC;QACxB,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC5B,CAAC;IACD,OAAO,UAAU,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC;AAC7C,CAAC"}
1
+ {"version":3,"file":"reflect-args.js","sourceRoot":"","sources":["../../src/commands/reflect-args.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EACJ,aAAa,EACb,mBAAmB,EACnB,aAAa,EACb,eAAe,EACf,eAAe,EACf,YAAY,EACZ,UAAU,EACV,gBAAgB,EAChB,SAAS,EAEX,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,UAAU,EAA8B,MAAM,cAAc,CAAC;AAEtE,MAAM,WAAW,GAAG,CAAC,aAAa,EAAE,GAAG,eAAe,CAAU,CAAC;AACjE,MAAM,UAAU,GAAG,CAAC,QAAQ,CAAU,CAAC;AAEvC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,aAAa,GAAsB,CAAC,GAAG,mBAAmB,EAAE,GAAG,WAAW,EAAE,GAAG,UAAU,CAAC,CAAC;AAExG,oFAAoF;AACpF,MAAM,CAAC,MAAM,mBAAmB,GAAsB,CAAC,GAAG,mBAAmB,EAAE,GAAG,WAAW,CAAC,CAAC;AAE/F,2EAA2E;AAC3E,MAAM,CAAC,MAAM,YAAY,GAAsB;IAC5C,0KAA0K;IAC1K,EAAE;IACF,4EAA4E;IAC5E,2EAA2E;IAC3E,0EAA0E;IAC1E,6EAA6E;IAC7E,mFAAmF;IACnF,EAAE;IACF,UAAU;IACV,yFAAyF;IACzF,GAAG,eAAe,CAAC,EAAE,CAAC;IACtB,sFAAsF;IACtF,kFAAkF;IAClF,kFAAkF;IAClF,kFAAkF;IAClF,GAAG,YAAY,CAAC,EAAE,CAAC;CACrB,CAAC;AAEF,MAAM,UAAU,gBAAgB,CAAC,IAAc,EAAE,OAAO,GAAe,aAAa;IACjF,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,gBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE;QACrG,gBAAgB,EAAE,KAAK;QACvB,OAAO;KACT,CAAC,CAAC;IACH,OAAO;QACJ,cAAc;QACd,OAAO;QACP,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,KAAK,MAAM;QAClC,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC;QAC/B,GAAG,UAAU,CAAC,OAAO,CAAC;KACxB,CAAC;AACL,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAc;IAC7C,IAAI,aAAa,CAAC,IAAI,EAAE,mBAAmB,CAAC,EAAE,CAAC;QAC5C,SAAS,CAAC,YAAY,CAAC,CAAC;QACxB,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC5B,CAAC;IACD,OAAO,UAAU,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC;AAC7C,CAAC"}
@@ -10,8 +10,9 @@ import { type UsageError } from './harness-args.js';
10
10
  import { type ValidateCommandOptions } from './validate.js';
11
11
  /**
12
12
  * Every flag `validate` accepts, derived from the sets the parser is handed so
13
- * the list cannot claim a flag the parser would reject. `--services` is consumed
14
- * by the shared harness parser itself, so it is in neither set.
13
+ * the list cannot claim a flag the parser would reject.
14
+ * {@link HARNESS_VALUE_FLAGS} are consumed by the shared harness parser itself,
15
+ * so they are in neither set.
15
16
  */
16
17
  export declare const VALIDATE_FLAGS: readonly string[];
17
18
  /** The subset that takes a value, so `--help` in a value position reads as data. */
@@ -1 +1 @@
1
- {"version":3,"file":"validate-args.d.ts","sourceRoot":"","sources":["../../src/commands/validate-args.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EASJ,KAAK,UAAU,EACjB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAe,KAAK,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAKzE;;;;GAIG;AACH,eAAO,MAAM,cAAc,EAAE,SAAS,MAAM,EAAmD,CAAC;AAEhG,oFAAoF;AACpF,eAAO,MAAM,oBAAoB,EAAE,SAAS,MAAM,EAAoC,CAAC;AAEvF,4EAA4E;AAC5E,eAAO,MAAM,aAAa,EAAE,SAAS,MAAM,EAkB1C,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,GAAE,UAA0B,GAAG,sBAAsB,CAU7G;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAMhE"}
1
+ {"version":3,"file":"validate-args.d.ts","sourceRoot":"","sources":["../../src/commands/validate-args.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAUJ,KAAK,UAAU,EACjB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAe,KAAK,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAKzE;;;;;GAKG;AACH,eAAO,MAAM,cAAc,EAAE,SAAS,MAAM,EAA4D,CAAC;AAEzG,oFAAoF;AACpF,eAAO,MAAM,oBAAoB,EAAE,SAAS,MAAM,EAA6C,CAAC;AAEhG,4EAA4E;AAC5E,eAAO,MAAM,aAAa,EAAE,SAAS,MAAM,EAmB1C,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,GAAE,UAA0B,GAAG,sBAAsB,CAW7G;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAMhE"}
@@ -6,22 +6,23 @@
6
6
  *
7
7
  * SPDX-License-Identifier: MIT
8
8
  ********************************************************************************/
9
- import { exitWithUsage, helpRequested, LOG_VALUE_FLAGS, logHelpLines, logOptions, parseHarnessArgs, printHelp, SERVICES_FLAG } from './harness-args.js';
9
+ import { exitWithUsage, HARNESS_VALUE_FLAGS, helpRequested, importHelpLines, LOG_VALUE_FLAGS, logHelpLines, logOptions, parseHarnessArgs, printHelp } from './harness-args.js';
10
10
  import { OUT_FILE_FLAG } from './headless-harness.js';
11
11
  import { runValidate } from './validate.js';
12
12
  const VALUE_FLAGS = [OUT_FILE_FLAG, ...LOG_VALUE_FLAGS];
13
13
  const BOOL_FLAGS = ['--strict', '--json'];
14
14
  /**
15
15
  * Every flag `validate` accepts, derived from the sets the parser is handed so
16
- * the list cannot claim a flag the parser would reject. `--services` is consumed
17
- * by the shared harness parser itself, so it is in neither set.
16
+ * the list cannot claim a flag the parser would reject.
17
+ * {@link HARNESS_VALUE_FLAGS} are consumed by the shared harness parser itself,
18
+ * so they are in neither set.
18
19
  */
19
- export const VALIDATE_FLAGS = [SERVICES_FLAG, ...VALUE_FLAGS, ...BOOL_FLAGS];
20
+ export const VALIDATE_FLAGS = [...HARNESS_VALUE_FLAGS, ...VALUE_FLAGS, ...BOOL_FLAGS];
20
21
  /** The subset that takes a value, so `--help` in a value position reads as data. */
21
- export const VALIDATE_VALUE_FLAGS = [SERVICES_FLAG, ...VALUE_FLAGS];
22
+ export const VALIDATE_VALUE_FLAGS = [...HARNESS_VALUE_FLAGS, ...VALUE_FLAGS];
22
23
  /** The `--help` text, as data, held to {@link VALIDATE_FLAGS} by a test. */
23
24
  export const VALIDATE_HELP = [
24
- 'Usage: hydranium-cli validate --services <module> <workspace> [--strict] [--json] [--out-file <file>] [--log-level <lvl>] [--log-file <file>] [--log-file-level <lvl>]',
25
+ 'Usage: hydranium-cli validate --services <module> [--import <specifier>]... <workspace> [--strict] [--json] [--out-file <file>] [--log-level <lvl>] [--log-file <file>] [--log-file-level <lvl>]',
25
26
  '',
26
27
  'Build a workspace headlessly and report its validation diagnostics — a CI gate:',
27
28
  'the process exits non-zero when any error is found. `<module>` is an ESM module',
@@ -30,6 +31,7 @@ export const VALIDATE_HELP = [
30
31
  '',
31
32
  'Options:',
32
33
  ' --services <module> ESM module exporting `createServices(): { shared }` (required).',
34
+ ...importHelpLines(22),
33
35
  ' <workspace> Workspace root (path or file URI) to validate (required).',
34
36
  ' --strict Also fail (non-zero exit) on warnings, not only errors.',
35
37
  ' --json Emit the raw JSON result instead of the human report.',
@@ -40,9 +42,10 @@ export const VALIDATE_HELP = [
40
42
  ...logHelpLines(22)
41
43
  ];
42
44
  export function parseValidateArgs(args, onError = exitWithUsage) {
43
- const { servicesModule, workspace, options } = parseHarnessArgs(args, 'validate', VALUE_FLAGS, BOOL_FLAGS, { onError });
45
+ const { servicesModule, imports, workspace, options } = parseHarnessArgs(args, 'validate', VALUE_FLAGS, BOOL_FLAGS, { onError });
44
46
  return {
45
47
  servicesModule,
48
+ imports,
46
49
  workspace,
47
50
  strict: options['--strict'] === 'true',
48
51
  json: options['--json'] === 'true',
@@ -1 +1 @@
1
- {"version":3,"file":"validate-args.js","sourceRoot":"","sources":["../../src/commands/validate-args.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EACJ,aAAa,EACb,aAAa,EACb,eAAe,EACf,YAAY,EACZ,UAAU,EACV,gBAAgB,EAChB,SAAS,EACT,aAAa,EAEf,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,WAAW,EAA+B,MAAM,eAAe,CAAC;AAEzE,MAAM,WAAW,GAAG,CAAC,aAAa,EAAE,GAAG,eAAe,CAAU,CAAC;AACjE,MAAM,UAAU,GAAG,CAAC,UAAU,EAAE,QAAQ,CAAU,CAAC;AAEnD;;;;GAIG;AACH,MAAM,CAAC,MAAM,cAAc,GAAsB,CAAC,aAAa,EAAE,GAAG,WAAW,EAAE,GAAG,UAAU,CAAC,CAAC;AAEhG,oFAAoF;AACpF,MAAM,CAAC,MAAM,oBAAoB,GAAsB,CAAC,aAAa,EAAE,GAAG,WAAW,CAAC,CAAC;AAEvF,4EAA4E;AAC5E,MAAM,CAAC,MAAM,aAAa,GAAsB;IAC7C,wKAAwK;IACxK,EAAE;IACF,iFAAiF;IACjF,iFAAiF;IACjF,mFAAmF;IACnF,4CAA4C;IAC5C,EAAE;IACF,UAAU;IACV,yFAAyF;IACzF,mFAAmF;IACnF,iFAAiF;IACjF,+EAA+E;IAC/E,mFAAmF;IACnF,mFAAmF;IACnF,mFAAmF;IACnF,gFAAgF;IAChF,GAAG,YAAY,CAAC,EAAE,CAAC;CACrB,CAAC;AAEF,MAAM,UAAU,iBAAiB,CAAC,IAAc,EAAE,OAAO,GAAe,aAAa;IAClF,MAAM,EAAE,cAAc,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,gBAAgB,CAAC,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;IACxH,OAAO;QACJ,cAAc;QACd,SAAS;QACT,MAAM,EAAE,OAAO,CAAC,UAAU,CAAC,KAAK,MAAM;QACtC,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,KAAK,MAAM;QAClC,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC;QAC/B,GAAG,UAAU,CAAC,OAAO,CAAC;KACxB,CAAC;AACL,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,IAAc;IAC9C,IAAI,aAAa,CAAC,IAAI,EAAE,oBAAoB,CAAC,EAAE,CAAC;QAC7C,SAAS,CAAC,aAAa,CAAC,CAAC;QACzB,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC5B,CAAC;IACD,OAAO,WAAW,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC;AAC/C,CAAC"}
1
+ {"version":3,"file":"validate-args.js","sourceRoot":"","sources":["../../src/commands/validate-args.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EACJ,aAAa,EACb,mBAAmB,EACnB,aAAa,EACb,eAAe,EACf,eAAe,EACf,YAAY,EACZ,UAAU,EACV,gBAAgB,EAChB,SAAS,EAEX,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,WAAW,EAA+B,MAAM,eAAe,CAAC;AAEzE,MAAM,WAAW,GAAG,CAAC,aAAa,EAAE,GAAG,eAAe,CAAU,CAAC;AACjE,MAAM,UAAU,GAAG,CAAC,UAAU,EAAE,QAAQ,CAAU,CAAC;AAEnD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,cAAc,GAAsB,CAAC,GAAG,mBAAmB,EAAE,GAAG,WAAW,EAAE,GAAG,UAAU,CAAC,CAAC;AAEzG,oFAAoF;AACpF,MAAM,CAAC,MAAM,oBAAoB,GAAsB,CAAC,GAAG,mBAAmB,EAAE,GAAG,WAAW,CAAC,CAAC;AAEhG,4EAA4E;AAC5E,MAAM,CAAC,MAAM,aAAa,GAAsB;IAC7C,kMAAkM;IAClM,EAAE;IACF,iFAAiF;IACjF,iFAAiF;IACjF,mFAAmF;IACnF,4CAA4C;IAC5C,EAAE;IACF,UAAU;IACV,yFAAyF;IACzF,GAAG,eAAe,CAAC,EAAE,CAAC;IACtB,mFAAmF;IACnF,iFAAiF;IACjF,+EAA+E;IAC/E,mFAAmF;IACnF,mFAAmF;IACnF,mFAAmF;IACnF,gFAAgF;IAChF,GAAG,YAAY,CAAC,EAAE,CAAC;CACrB,CAAC;AAEF,MAAM,UAAU,iBAAiB,CAAC,IAAc,EAAE,OAAO,GAAe,aAAa;IAClF,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,gBAAgB,CAAC,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;IACjI,OAAO;QACJ,cAAc;QACd,OAAO;QACP,SAAS;QACT,MAAM,EAAE,OAAO,CAAC,UAAU,CAAC,KAAK,MAAM;QACtC,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,KAAK,MAAM;QAClC,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC;QAC/B,GAAG,UAAU,CAAC,OAAO,CAAC;KACxB,CAAC;AACL,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,IAAc;IAC9C,IAAI,aAAa,CAAC,IAAI,EAAE,oBAAoB,CAAC,EAAE,CAAC;QAC7C,SAAS,CAAC,aAAa,CAAC,CAAC;QACzB,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC5B,CAAC;IACD,OAAO,WAAW,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC;AAC/C,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hydranium/cli",
3
- "version": "1.0.0-next.212",
3
+ "version": "1.0.0-next.213",
4
4
  "description": "Build-time codegen tools + data-server subcommands for the hydranium framework.",
5
5
  "keywords": [
6
6
  "cli",
@@ -69,20 +69,20 @@
69
69
  "ts-morph": "^25.0.0"
70
70
  },
71
71
  "devDependencies": {
72
- "@hydranium/core": "1.0.0-next.212",
73
- "@hydranium/data-server": "1.0.0-next.212",
74
- "@hydranium/langium": "1.0.0-next.212",
75
- "@hydranium/protocol": "1.0.0-next.212",
72
+ "@hydranium/core": "1.0.0-next.213",
73
+ "@hydranium/data-server": "1.0.0-next.213",
74
+ "@hydranium/langium": "1.0.0-next.213",
75
+ "@hydranium/protocol": "1.0.0-next.213",
76
76
  "rimraf": "^5.0.0",
77
77
  "typescript": "^7.0.2",
78
78
  "vscode-jsonrpc": "9.0.0",
79
79
  "vscode-languageserver": "10.0.1"
80
80
  },
81
81
  "peerDependencies": {
82
- "@hydranium/core": "1.0.0-next.212",
83
- "@hydranium/data-server": "1.0.0-next.212",
84
- "@hydranium/langium": "1.0.0-next.212",
85
- "@hydranium/protocol": "1.0.0-next.212",
82
+ "@hydranium/core": "1.0.0-next.213",
83
+ "@hydranium/data-server": "1.0.0-next.213",
84
+ "@hydranium/langium": "1.0.0-next.213",
85
+ "@hydranium/protocol": "1.0.0-next.213",
86
86
  "@memlab/core": "^2.0.3",
87
87
  "@memlab/heap-analysis": "^2.0.3",
88
88
  "vscode-jsonrpc": "^9.0.0"
@@ -10,13 +10,14 @@
10
10
  import { runAstGroundTruth, type AstGroundTruthCommandOptions } from './ast-ground-truth.js';
11
11
  import {
12
12
  exitWithUsage,
13
+ HARNESS_VALUE_FLAGS,
13
14
  helpRequested,
15
+ importHelpLines,
14
16
  LOG_VALUE_FLAGS,
15
17
  logHelpLines,
16
18
  logOptions,
17
19
  parseHarnessArgs,
18
20
  printHelp,
19
- SERVICES_FLAG,
20
21
  type UsageError
21
22
  } from './harness-args.js';
22
23
  import { OUT_FILE_FLAG } from './headless-harness.js';
@@ -25,17 +26,18 @@ const VALUE_FLAGS = [OUT_FILE_FLAG, ...LOG_VALUE_FLAGS] as const;
25
26
 
26
27
  /**
27
28
  * Every flag `ast-ground-truth` accepts, derived from the sets the parser is
28
- * handed so the list cannot claim a flag the parser would reject. `--services`
29
- * is consumed by the shared harness parser itself, so it is in neither set.
29
+ * handed so the list cannot claim a flag the parser would reject.
30
+ * {@link HARNESS_VALUE_FLAGS} are consumed by the shared harness parser itself,
31
+ * so they are in neither set.
30
32
  */
31
- export const AST_GROUND_TRUTH_FLAGS: readonly string[] = [SERVICES_FLAG, ...VALUE_FLAGS];
33
+ export const AST_GROUND_TRUTH_FLAGS: readonly string[] = [...HARNESS_VALUE_FLAGS, ...VALUE_FLAGS];
32
34
 
33
35
  /** The subset that takes a value, so `--help` in a value position reads as data. */
34
36
  export const AST_GROUND_TRUTH_VALUE_FLAGS: readonly string[] = AST_GROUND_TRUTH_FLAGS;
35
37
 
36
38
  /** The `--help` text, as data, held to {@link AST_GROUND_TRUTH_FLAGS} by a test. */
37
39
  export const AST_GROUND_TRUTH_HELP: readonly string[] = [
38
- 'Usage: hydranium-cli ast-ground-truth --services <module> <workspace> [--out-file <file>] [--log-level <lvl>] [--log-file <file>] [--log-file-level <lvl>]',
40
+ 'Usage: hydranium-cli ast-ground-truth --services <module> [--import <specifier>]... <workspace> [--out-file <file>] [--log-level <lvl>] [--log-file <file>] [--log-file-level <lvl>]',
39
41
  '',
40
42
  "Tally a workspace's live-model AST nodes by `$type` — the ground truth that",
41
43
  '`analyze-heap --validate <gt.json>` checks a heap snapshot against. `<module>`',
@@ -44,14 +46,15 @@ export const AST_GROUND_TRUTH_HELP: readonly string[] = [
44
46
  '',
45
47
  'Options:',
46
48
  ' --services <module> ESM module exporting `createServices(): { shared }` (required).',
49
+ ...importHelpLines(22),
47
50
  ' <workspace> Workspace root (path or file URI) to build (required).',
48
51
  ' --out-file <file> Write the JSON to this file instead of stdout.',
49
52
  ...logHelpLines(22)
50
53
  ];
51
54
 
52
55
  export function parseAstGroundTruthArgs(args: string[], onError: UsageError = exitWithUsage): AstGroundTruthCommandOptions {
53
- const { servicesModule, workspace, options } = parseHarnessArgs(args, 'ast-ground-truth', VALUE_FLAGS, [], { onError });
54
- return { servicesModule, workspace, outFile: options[OUT_FILE_FLAG], ...logOptions(options) };
56
+ const { servicesModule, imports, workspace, options } = parseHarnessArgs(args, 'ast-ground-truth', VALUE_FLAGS, [], { onError });
57
+ return { servicesModule, imports, workspace, outFile: options[OUT_FILE_FLAG], ...logOptions(options) };
55
58
  }
56
59
 
57
60
  export function runAstGroundTruthCommand(args: string[]): Promise<void> {
@@ -56,9 +56,18 @@ export function exitWithUsage(message: string): never {
56
56
  process.exit(2);
57
57
  }
58
58
 
59
- /** The value flag {@link parseHarnessArgs} consumes itself, before any the subcommand declares. */
59
+ /** Names the head's services module; every harness subcommand requires it. */
60
60
  export const SERVICES_FLAG = '--services';
61
61
 
62
+ /**
63
+ * Registers a loader in the driver child that imports the head. The child is a
64
+ * fresh `node`, so a loader registered on the CLI's own process never reaches it.
65
+ */
66
+ export const IMPORT_FLAG = '--import';
67
+
68
+ /** The value flags {@link parseHarnessArgs} consumes itself, before any the subcommand declares. */
69
+ export const HARNESS_VALUE_FLAGS = [SERVICES_FLAG, IMPORT_FLAG] as const;
70
+
62
71
  /**
63
72
  * The one spelling of the log threshold, shared by both subcommand families.
64
73
  *
@@ -88,15 +97,22 @@ export const SERVER_SPAWN_VALUE_FLAGS: readonly string[] = ['--server', '--cwd',
88
97
  * next line, at the column.
89
98
  */
90
99
  export function logHelpLines(padTo: number, head = 'the head this boots'): string[] {
91
- const line = (flag: string, text: string): string[] =>
92
- flag.length < padTo - 1 ? [` ${flag.padEnd(padTo)}${text}`] : [` ${flag}`, `${' '.repeat(padTo + 2)}${text}`];
93
100
  return [
94
- line(`${LOG_LEVEL_FLAG} <lvl>`, `Log threshold for ${head} (off|error|warn|info|debug|trace).`),
95
- line(`${LOG_FILE_FLAG} <file>`, `Also write ${head}'s log to <file>; {workspace} expands to the workspace.`),
96
- line(`${LOG_FILE_LEVEL_FLAG} <lvl>`, `Threshold for that file, which the log-level setting does not change.`)
101
+ helpLine(`${LOG_LEVEL_FLAG} <lvl>`, `Log threshold for ${head} (off|error|warn|info|debug|trace).`, padTo),
102
+ helpLine(`${LOG_FILE_FLAG} <file>`, `Also write ${head}'s log to <file>; {workspace} expands to the workspace.`, padTo),
103
+ helpLine(`${LOG_FILE_LEVEL_FLAG} <lvl>`, `Threshold for that file, which the log-level setting does not change.`, padTo)
97
104
  ].flat();
98
105
  }
99
106
 
107
+ /** The `--help` lines every `--services` subcommand describes {@link IMPORT_FLAG} with, aligned as {@link logHelpLines}. */
108
+ export function importHelpLines(padTo: number): string[] {
109
+ return helpLine(`${IMPORT_FLAG} <specifier>`, 'Loader to register before importing <module>, e.g. tsx (repeatable).', padTo);
110
+ }
111
+
112
+ function helpLine(flag: string, text: string, padTo: number): string[] {
113
+ return flag.length < padTo - 1 ? [` ${flag.padEnd(padTo)}${text}`] : [` ${flag}`, `${' '.repeat(padTo + 2)}${text}`];
114
+ }
115
+
100
116
  /**
101
117
  * Narrow the raw {@link LOG_VALUE_FLAGS} values a parser collected, leaving
102
118
  * absent flags absent.
@@ -158,6 +174,8 @@ export function printHelp(lines: readonly string[]): void {
158
174
  /** What {@link parseHarnessArgs} recovered from an argv. */
159
175
  export interface ParsedHarnessArgs {
160
176
  servicesModule: string;
177
+ /** The {@link IMPORT_FLAG} values in the order given, absent when there were none. */
178
+ imports?: string[];
161
179
  /**
162
180
  * An absolute directory path, resolved by {@link resolveWorkspaceArgument} and
163
181
  * checked to exist. `''` when the subcommand declared `requireWorkspace: false`.
@@ -187,12 +205,12 @@ export interface HarnessArgsConfig {
187
205
 
188
206
  /**
189
207
  * Shared parser for the headless-harness subcommands. Consumes the required
190
- * `--services <module>` value flag and a single positional `<workspace>`, plus
191
- * the `valueFlags` (each takes a value) and `boolFlags` (presence-only, recorded
192
- * as `'true'`) the subcommand recognises. Unknown flags or a missing
193
- * `--services`/`<workspace>` are usage errors, and so is a `<workspace>` that
194
- * reaches no directory — see {@link resolveWorkspaceArgument} for why that cannot
195
- * be left to the run.
208
+ * `--services <module>` value flag, the repeatable `--import <specifier>` and a
209
+ * single positional `<workspace>`, plus the `valueFlags` (each takes a value)
210
+ * and `boolFlags` (presence-only, recorded as `'true'`) the subcommand
211
+ * recognises. Unknown flags or a missing `--services`/`<workspace>` are usage
212
+ * errors, and so is a `<workspace>` that reaches no directory — see
213
+ * {@link resolveWorkspaceArgument} for why that cannot be left to the run.
196
214
  */
197
215
  export function parseHarnessArgs(
198
216
  args: string[],
@@ -209,6 +227,7 @@ export function parseHarnessArgs(
209
227
  const options: Record<string, string | undefined> = {};
210
228
  const values: Record<string, string[]> = {};
211
229
  let servicesModule: string | undefined;
230
+ let imports: string[] | undefined;
212
231
  let workspace: string | undefined;
213
232
  for (let index = 0; index < args.length; index += 1) {
214
233
  const flag = args[index];
@@ -220,8 +239,10 @@ export function parseHarnessArgs(
220
239
  index += 1;
221
240
  return value;
222
241
  };
223
- if (flag === '--services') {
242
+ if (flag === SERVICES_FLAG) {
224
243
  servicesModule = next();
244
+ } else if (flag === IMPORT_FLAG) {
245
+ (imports ??= []).push(next());
225
246
  } else if (boolSet.has(flag)) {
226
247
  options[flag] = 'true';
227
248
  } else if (repeatableSet.has(flag)) {
@@ -237,7 +258,8 @@ export function parseHarnessArgs(
237
258
  }
238
259
  }
239
260
  return {
240
- servicesModule: assertRequired(servicesModule, '--services', commandName, onError),
261
+ servicesModule: assertRequired(servicesModule, SERVICES_FLAG, commandName, onError),
262
+ imports,
241
263
  workspace: requireWorkspace
242
264
  ? resolveWorkspaceArgument(assertRequired(workspace, '<workspace>', commandName, onError), commandName, onError)
243
265
  : (workspace ?? ''),
@@ -15,7 +15,7 @@ import * as path from 'node:path';
15
15
  import { pathToFileURL } from 'node:url';
16
16
  import { driverHeapArgs, type HeapReading } from '../driver-heap.js';
17
17
  import { logEnv, type LogOptions } from '../log-level.js';
18
- import { SERVICES_FLAG } from './harness-args.js';
18
+ import { IMPORT_FLAG, SERVICES_FLAG } from './harness-args.js';
19
19
 
20
20
  /** The flag every report-producing subcommand names its destination file with. */
21
21
  export const OUT_FILE_FLAG = '--out-file';
@@ -43,8 +43,9 @@ export interface HeadlessContext {
43
43
  * its `createServices` thunk AND the `@hydranium/core/node` harness, both
44
44
  * resolved from the HEAD's location rather than the CLI's.
45
45
  *
46
- * The module is an ESM file (typically a compiled `lib/*.js`) exporting a
47
- * ZERO-ARG `createServices(): { shared }`. `hydranium-cli` is language-agnostic
46
+ * The module is an ESM file exporting a ZERO-ARG `createServices(): { shared }`:
47
+ * a compiled `lib/*.js`, or the TypeScript source when the child was started
48
+ * with a loader through {@link IMPORT_FLAG}. `hydranium-cli` is language-agnostic
48
49
  * and cannot statically import a head's `create<Lang>Services`, so the dynamic
49
50
  * import is the seam that keeps the binary head-neutral. Resolving the harness
50
51
  * from the head's graph (via `createRequire` rooted at the head module) rather
@@ -65,12 +66,17 @@ export async function loadHeadlessContext(servicesModule: string): Promise<Headl
65
66
  if (stats === undefined || !stats.isFile()) {
66
67
  throw new Error(
67
68
  `${SERVICES_FLAG} must name an existing ESM file; '${servicesModule}' resolved to ${modulePath}, ` +
68
- `which is not one. Pass the head's COMPILED entry, e.g. \`${SERVICES_FLAG} ./lib/services.js\` — ` +
69
- 'not the TypeScript source and not a package name.'
69
+ `which is not one. Pass the path of the head's entry, e.g. \`${SERVICES_FLAG} ./lib/services.js\` — ` +
70
+ 'not a package name.'
70
71
  );
71
72
  }
72
73
  const moduleUrl = pathToFileURL(modulePath).href;
73
- const imported = (await import(moduleUrl)) as Record<string, unknown>;
74
+ let imported: Record<string, unknown>;
75
+ try {
76
+ imported = (await import(moduleUrl)) as Record<string, unknown>;
77
+ } catch (err: unknown) {
78
+ throw withLoaderHint(err, modulePath);
79
+ }
74
80
  const createServices = imported.createServices;
75
81
  if (typeof createServices !== 'function') {
76
82
  throw new Error(
@@ -85,6 +91,32 @@ export async function loadHeadlessContext(servicesModule: string): Promise<Headl
85
91
  return { createServices: createServices as ServicesFactory, coreNode };
86
92
  }
87
93
 
94
+ /** The codes Node fails a TypeScript entry with when no loader handled it, depending on its version. */
95
+ const UNLOADED_TYPESCRIPT_CODES: ReadonlySet<string> = new Set([
96
+ 'ERR_UNKNOWN_FILE_EXTENSION',
97
+ 'ERR_MODULE_NOT_FOUND',
98
+ 'ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX'
99
+ ]);
100
+
101
+ /**
102
+ * Append a loader hint to a TypeScript entry's import failure, unless the child
103
+ * was started with {@link IMPORT_FLAG}, where the hint would only repeat the
104
+ * caller's own command. Appended rather than substituted: a loader set through
105
+ * `NODE_OPTIONS` does not show in `execArgv`, and under it the failure can be a
106
+ * missing module that only Node's own message names.
107
+ */
108
+ function withLoaderHint(err: unknown, modulePath: string): unknown {
109
+ if (!(err instanceof Error) || !/\.[cm]?ts$/.test(modulePath) || !('code' in err) || typeof err.code !== 'string') {
110
+ return err;
111
+ }
112
+ if (!UNLOADED_TYPESCRIPT_CODES.has(err.code) || process.execArgv.some(arg => arg.startsWith(IMPORT_FLAG))) {
113
+ return err;
114
+ }
115
+ return new Error(`${err.message}\nA TypeScript head needs a loader registered with \`${IMPORT_FLAG}\`, e.g. \`${IMPORT_FLAG} tsx\`.`, {
116
+ cause: err
117
+ });
118
+ }
119
+
88
120
  /**
89
121
  * Child-side: deliver a finished report — to `outFile` when one was named, else
90
122
  * to stdout.
@@ -137,6 +169,8 @@ export type SpawnDriverChild = (execArgs: string[], env?: Record<string, string>
137
169
  * variable still wins where a caller set one.
138
170
  */
139
171
  export interface DriverSpawnOptions extends LogOptions {
172
+ /** Specifiers the driver child registers with Node's `--import`, in order, before it imports the head. */
173
+ readonly imports?: readonly string[];
140
174
  /** Test-only: capture the node argv and env instead of spawning the real child. */
141
175
  readonly __spawnForTest?: SpawnDriverChild;
142
176
  /**
@@ -171,8 +205,21 @@ export interface DriverSpawnOptions extends LogOptions {
171
205
  */
172
206
  export async function runDriverChild(execArgs: string[], options: DriverSpawnOptions): Promise<void> {
173
207
  const spawnChild = options.__spawnForTest ?? spawnNodeChild;
174
- const code = await spawnChild([...driverHeapArgs(options.__heapReadingForTest), ...execArgs], logEnv(options));
208
+ const importArgs = (options.imports ?? []).map(specifier => `${IMPORT_FLAG}=${loaderSpecifier(specifier)}`);
209
+ const code = await spawnChild([...driverHeapArgs(options.__heapReadingForTest), ...importArgs, ...execArgs], logEnv(options));
175
210
  if (code) {
176
211
  process.exitCode = code;
177
212
  }
178
213
  }
214
+
215
+ /**
216
+ * A path, absolute or `./`/`../` relative with either separator, becomes a file
217
+ * URL resolved against the caller's directory. Node reads `--import` as a URL or
218
+ * package specifier, so it would take a Windows `C:\…` for the URL scheme `c:`
219
+ * and a `.\…` for a package name. Any other specifier passes through as Node
220
+ * reads it.
221
+ */
222
+ function loaderSpecifier(specifier: string): string {
223
+ const isPath = path.isAbsolute(specifier) || /^\.\.?[\\/]/.test(specifier);
224
+ return isPath ? pathToFileURL(path.resolve(specifier)).href : specifier;
225
+ }