@hydranium/cli 1.0.0-next.408 → 1.0.0-next.411

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 (51) hide show
  1. package/README.md +23 -5
  2. package/lib/cli.js +2 -0
  3. package/lib/cli.js.map +1 -1
  4. package/lib/commands/ast-ground-truth-args.js +2 -2
  5. package/lib/commands/ast-ground-truth-args.js.map +1 -1
  6. package/lib/commands/harness-args.d.ts +6 -5
  7. package/lib/commands/harness-args.d.ts.map +1 -1
  8. package/lib/commands/harness-args.js +66 -7
  9. package/lib/commands/harness-args.js.map +1 -1
  10. package/lib/commands/init-templates.d.ts.map +1 -1
  11. package/lib/commands/init-templates.js +11 -7
  12. package/lib/commands/init-templates.js.map +1 -1
  13. package/lib/commands/init.d.ts.map +1 -1
  14. package/lib/commands/init.js +3 -1
  15. package/lib/commands/init.js.map +1 -1
  16. package/lib/commands/lint-grammar-args.js +2 -2
  17. package/lib/commands/lint-grammar-args.js.map +1 -1
  18. package/lib/commands/measure-memory-args.js +2 -2
  19. package/lib/commands/measure-memory-args.js.map +1 -1
  20. package/lib/commands/message-catalogue-args.d.ts +16 -0
  21. package/lib/commands/message-catalogue-args.d.ts.map +1 -0
  22. package/lib/commands/message-catalogue-args.js +53 -0
  23. package/lib/commands/message-catalogue-args.js.map +1 -0
  24. package/lib/commands/message-catalogue.d.ts +21 -0
  25. package/lib/commands/message-catalogue.d.ts.map +1 -0
  26. package/lib/commands/message-catalogue.js +48 -0
  27. package/lib/commands/message-catalogue.js.map +1 -0
  28. package/lib/commands/model-docs-args.js +2 -2
  29. package/lib/commands/model-docs-args.js.map +1 -1
  30. package/lib/commands/reflect-args.js +2 -2
  31. package/lib/commands/reflect-args.js.map +1 -1
  32. package/lib/commands/validate-args.js +2 -2
  33. package/lib/commands/validate-args.js.map +1 -1
  34. package/lib/index.d.ts +1 -0
  35. package/lib/index.d.ts.map +1 -1
  36. package/lib/index.js +1 -0
  37. package/lib/index.js.map +1 -1
  38. package/package.json +19 -18
  39. package/src/cli.ts +2 -0
  40. package/src/commands/ast-ground-truth-args.ts +2 -2
  41. package/src/commands/harness-args.ts +69 -7
  42. package/src/commands/init-templates.ts +11 -7
  43. package/src/commands/init.ts +5 -1
  44. package/src/commands/lint-grammar-args.ts +2 -2
  45. package/src/commands/measure-memory-args.ts +2 -2
  46. package/src/commands/message-catalogue-args.ts +55 -0
  47. package/src/commands/message-catalogue.ts +56 -0
  48. package/src/commands/model-docs-args.ts +2 -2
  49. package/src/commands/reflect-args.ts +2 -2
  50. package/src/commands/validate-args.ts +2 -2
  51. package/src/index.ts +1 -0
@@ -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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"}
@@ -0,0 +1,16 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2026 CrossBreeze, EclipseSource and others.
3
+ *
4
+ * This program and the accompanying materials are made available under the
5
+ * terms of the MIT License which is available in the project root.
6
+ *
7
+ * SPDX-License-Identifier: MIT
8
+ ********************************************************************************/
9
+ import { type UsageError } from './harness-args.js';
10
+ import { type MessageCatalogueCommandOptions } from './message-catalogue.js';
11
+ export declare const MESSAGE_CATALOGUE_FLAGS: readonly string[];
12
+ export declare const MESSAGE_CATALOGUE_VALUE_FLAGS: readonly string[];
13
+ export declare const MESSAGE_CATALOGUE_HELP: readonly string[];
14
+ export declare function parseMessageCatalogueArgs(args: string[], onError?: UsageError): MessageCatalogueCommandOptions;
15
+ export declare function runMessageCatalogueCommand(args: string[]): Promise<void>;
16
+ //# sourceMappingURL=message-catalogue-args.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message-catalogue-args.d.ts","sourceRoot":"","sources":["../../src/commands/message-catalogue-args.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAA2D,KAAK,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC7G,OAAO,EAAuB,KAAK,8BAA8B,EAAE,MAAM,wBAAwB,CAAC;AAElG,eAAO,MAAM,uBAAuB,EAAE,SAAS,MAAM,EAA+B,CAAC;AACrF,eAAO,MAAM,6BAA6B,mBAA0B,CAAC;AACrE,eAAO,MAAM,sBAAsB,EAAE,SAAS,MAAM,EAUnD,CAAC;AAEF,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,GAAE,UAA0B,GAAG,8BAA8B,CAoB7H;AAED,wBAAsB,0BAA0B,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAM9E"}
@@ -0,0 +1,53 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2026 CrossBreeze, EclipseSource and others.
3
+ *
4
+ * This program and the accompanying materials are made available under the
5
+ * terms of the MIT License which is available in the project root.
6
+ *
7
+ * SPDX-License-Identifier: MIT
8
+ ********************************************************************************/
9
+ import { assertRequired, exitWithUsage, helpRequested, printHelp } from './harness-args.js';
10
+ import { runMessageCatalogue } from './message-catalogue.js';
11
+ export const MESSAGE_CATALOGUE_FLAGS = ['--barrel', '--out-file'];
12
+ export const MESSAGE_CATALOGUE_VALUE_FLAGS = MESSAGE_CATALOGUE_FLAGS;
13
+ export const MESSAGE_CATALOGUE_HELP = [
14
+ 'Usage: hydranium-cli message-catalogue --barrel <module>... [--out-file <file>]',
15
+ '',
16
+ 'Emit a flat JSON starter catalogue mapping message codes to English defaults.',
17
+ 'Modules are resolved from the current project and must be built first.',
18
+ 'Repeat --barrel for each framework head and your own messages. No server starts.',
19
+ '',
20
+ 'Options:',
21
+ ' --barrel <module> Messages package specifier or ESM file (required). Repeatable.',
22
+ ' --out-file <file> Write JSON here instead of stdout, after all imports succeed.'
23
+ ];
24
+ export function parseMessageCatalogueArgs(args, onError = exitWithUsage) {
25
+ const barrels = [];
26
+ let outFile;
27
+ for (let index = 0; index < args.length; index++) {
28
+ const flag = args[index];
29
+ if (!MESSAGE_CATALOGUE_FLAGS.includes(flag)) {
30
+ return onError(`Unexpected argument: ${flag} (hydranium-cli message-catalogue --help)`);
31
+ }
32
+ const value = args[++index];
33
+ if (value === undefined || value.startsWith('--')) {
34
+ return onError(`Missing value for ${flag}`);
35
+ }
36
+ if (flag === '--barrel') {
37
+ barrels.push(value);
38
+ }
39
+ else {
40
+ outFile = value;
41
+ }
42
+ }
43
+ assertRequired(barrels[0], '--barrel', 'message-catalogue', onError);
44
+ return { barrels, outFile };
45
+ }
46
+ export async function runMessageCatalogueCommand(args) {
47
+ if (helpRequested(args, MESSAGE_CATALOGUE_VALUE_FLAGS)) {
48
+ printHelp(MESSAGE_CATALOGUE_HELP);
49
+ return;
50
+ }
51
+ await runMessageCatalogue(parseMessageCatalogueArgs(args));
52
+ }
53
+ //# sourceMappingURL=message-catalogue-args.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message-catalogue-args.js","sourceRoot":"","sources":["../../src/commands/message-catalogue-args.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,EAAE,SAAS,EAAmB,MAAM,mBAAmB,CAAC;AAC7G,OAAO,EAAE,mBAAmB,EAAuC,MAAM,wBAAwB,CAAC;AAElG,MAAM,CAAC,MAAM,uBAAuB,GAAsB,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;AACrF,MAAM,CAAC,MAAM,6BAA6B,GAAG,uBAAuB,CAAC;AACrE,MAAM,CAAC,MAAM,sBAAsB,GAAsB;IACtD,iFAAiF;IACjF,EAAE;IACF,+EAA+E;IAC/E,wEAAwE;IACxE,kFAAkF;IAClF,EAAE;IACF,UAAU;IACV,uFAAuF;IACvF,qFAAqF;CACvF,CAAC;AAEF,MAAM,UAAU,yBAAyB,CAAC,IAAc,EAAE,OAAO,GAAe,aAAa;IAC1F,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,OAA2B,CAAC;IAChC,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;QAChD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;QACzB,IAAI,CAAC,uBAAuB,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3C,OAAO,OAAO,CAAC,wBAAwB,IAAI,2CAA2C,CAAC,CAAC;QAC3F,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;QAC5B,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACjD,OAAO,OAAO,CAAC,qBAAqB,IAAI,EAAE,CAAC,CAAC;QAC/C,CAAC;QACD,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;YACvB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACvB,CAAC;aAAM,CAAC;YACL,OAAO,GAAG,KAAK,CAAC;QACnB,CAAC;IACJ,CAAC;IACD,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,mBAAmB,EAAE,OAAO,CAAC,CAAC;IACrE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;AAC/B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAAC,IAAc;IAC5D,IAAI,aAAa,CAAC,IAAI,EAAE,6BAA6B,CAAC,EAAE,CAAC;QACtD,SAAS,CAAC,sBAAsB,CAAC,CAAC;QAClC,OAAO;IACV,CAAC;IACD,MAAM,mBAAmB,CAAC,yBAAyB,CAAC,IAAI,CAAC,CAAC,CAAC;AAC9D,CAAC"}
@@ -0,0 +1,21 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2026 CrossBreeze, EclipseSource and others.
3
+ *
4
+ * This program and the accompanying materials are made available under the
5
+ * terms of the MIT License which is available in the project root.
6
+ *
7
+ * SPDX-License-Identifier: MIT
8
+ ********************************************************************************/
9
+ import { type MessageCatalogue } from '@hydranium/protocol';
10
+ /**
11
+ * Enumerate declarations rather than scanning source. Conflicting defaults
12
+ * must fail before any output is written, or import order chooses the English.
13
+ */
14
+ export declare function createMessageCatalogue(barrels: readonly object[]): MessageCatalogue;
15
+ export interface MessageCatalogueCommandOptions {
16
+ readonly barrels: readonly string[];
17
+ readonly outFile?: string;
18
+ }
19
+ /** Resolve against the caller's project, including when the CLI is installed globally. */
20
+ export declare function runMessageCatalogue(options: MessageCatalogueCommandOptions): Promise<void>;
21
+ //# sourceMappingURL=message-catalogue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message-catalogue.d.ts","sourceRoot":"","sources":["../../src/commands/message-catalogue.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAAmB,KAAK,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAM7E;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,gBAAgB,CAYnF;AAED,MAAM,WAAW,8BAA8B;IAC5C,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,0FAA0F;AAC1F,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,8BAA8B,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBhG"}
@@ -0,0 +1,48 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2026 CrossBreeze, EclipseSource and others.
3
+ *
4
+ * This program and the accompanying materials are made available under the
5
+ * terms of the MIT License which is available in the project root.
6
+ *
7
+ * SPDX-License-Identifier: MIT
8
+ ********************************************************************************/
9
+ import { collectMessages } from '@hydranium/protocol';
10
+ import { resolve as resolveModule } from 'import-meta-resolve';
11
+ import { isAbsolute, resolve } from 'node:path';
12
+ import { pathToFileURL } from 'node:url';
13
+ import { emitReport } from './headless-harness.js';
14
+ /**
15
+ * Enumerate declarations rather than scanning source. Conflicting defaults
16
+ * must fail before any output is written, or import order chooses the English.
17
+ */
18
+ export function createMessageCatalogue(barrels) {
19
+ const entries = new Map();
20
+ for (const barrel of barrels) {
21
+ for (const message of collectMessages(barrel)) {
22
+ const previous = entries.get(message.code);
23
+ if (previous !== undefined && previous !== message.text) {
24
+ throw new Error(`Conflicting English defaults for message '${message.code}'.`);
25
+ }
26
+ entries.set(message.code, message.text);
27
+ }
28
+ }
29
+ return Object.fromEntries([...entries].sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0)));
30
+ }
31
+ /** Resolve against the caller's project, including when the CLI is installed globally. */
32
+ export async function runMessageCatalogue(options) {
33
+ const projectUrl = pathToFileURL(resolve('package.json')).href;
34
+ const barrels = [];
35
+ for (const specifier of options.barrels) {
36
+ const target = specifier.startsWith('.') || isAbsolute(specifier) ? pathToFileURL(resolve(specifier)).href : resolveModule(specifier, projectUrl);
37
+ const barrel = (await import(target));
38
+ if (collectMessages(barrel).length === 0) {
39
+ throw new Error(`Message barrel '${specifier}' exports no declarations. Pass a built messages module.`);
40
+ }
41
+ barrels.push(barrel);
42
+ }
43
+ if (barrels.length === 0) {
44
+ throw new Error('Pass at least one --barrel messages module.');
45
+ }
46
+ emitReport(JSON.stringify(createMessageCatalogue(barrels), undefined, 2), options.outFile);
47
+ }
48
+ //# sourceMappingURL=message-catalogue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message-catalogue.js","sourceRoot":"","sources":["../../src/commands/message-catalogue.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAAE,eAAe,EAAyB,MAAM,qBAAqB,CAAC;AAC7E,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAEnD;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CAAC,OAA0B;IAC9D,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC1C,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC5B,KAAK,MAAM,OAAO,IAAI,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC;YAC7C,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAC3C,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,OAAO,CAAC,IAAI,EAAE,CAAC;gBACvD,MAAM,IAAI,KAAK,CAAC,6CAA6C,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC;YAClF,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QAC3C,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC,WAAW,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC5F,CAAC;AAOD,0FAA0F;AAC1F,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,OAAuC;IAC9E,MAAM,UAAU,GAAG,aAAa,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC;IAC/D,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,SAAS,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACvC,MAAM,MAAM,GACT,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;QACtI,MAAM,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,CAAW,CAAC;QAChD,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CAAC,mBAAmB,SAAS,0DAA0D,CAAC,CAAC;QAC3G,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACxB,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;IAClE,CAAC;IACD,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,sBAAsB,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;AAC9F,CAAC"}
@@ -21,7 +21,7 @@ export const MODEL_DOCS_FLAGS = [...HARNESS_VALUE_FLAGS, ...VALUE_FLAGS];
21
21
  export const MODEL_DOCS_VALUE_FLAGS = MODEL_DOCS_FLAGS;
22
22
  /** The `--help` text, as data, held to {@link MODEL_DOCS_FLAGS} by a test. */
23
23
  export const MODEL_DOCS_HELP = [
24
- 'Usage: hydranium-cli model-docs --services <module> [--import <specifier>]... [--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>]',
25
25
  '',
26
26
  'Generate a navigable Markdown reference of every AST node type — a type index,',
27
27
  'cross-linked super/sub types, a reverse "referenced by" index, and a per-language',
@@ -31,7 +31,7 @@ export const MODEL_DOCS_HELP = [
31
31
  'zero-arg `createServices(): { shared }` thunk. Needs @hydranium/core.',
32
32
  '',
33
33
  'Options:',
34
- ' --services <module> ESM module exporting `createServices(): { shared }` (required).',
34
+ ' --services <module> ESM module exporting `createServices(): { shared }` (required) unless package.json sets hydranium.services.',
35
35
  ...importHelpLines(22),
36
36
  ' --out-file <file> Write the Markdown to this file instead of stdout. Written',
37
37
  ' only once the report exists, unlike a shell redirection,',
@@ -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,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"}
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,sKAAsK;IACtK,EAAE;IACF,gFAAgF;IAChF,mFAAmF;IACnF,gFAAgF;IAChF,kFAAkF;IAClF,4EAA4E;IAC5E,uEAAuE;IACvE,EAAE;IACF,UAAU;IACV,qIAAqI;IACrI,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"}
@@ -22,7 +22,7 @@ export const REFLECT_FLAGS = [...HARNESS_VALUE_FLAGS, ...VALUE_FLAGS, ...BOOL_FL
22
22
  export const REFLECT_VALUE_FLAGS = [...HARNESS_VALUE_FLAGS, ...VALUE_FLAGS];
23
23
  /** The `--help` text, as data, held to {@link REFLECT_FLAGS} by a test. */
24
24
  export const REFLECT_HELP = [
25
- 'Usage: hydranium-cli reflect --services <module> [--import <specifier>]... [--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>]',
26
26
  '',
27
27
  "Dump a head's grammar/AST reflection — the type hierarchy, each language's",
28
28
  'terminals and entry rule, and every cross-reference target. Read-only: no',
@@ -31,7 +31,7 @@ export const REFLECT_HELP = [
31
31
  'exporting a zero-arg `createServices(): { shared }` thunk. Needs @hydranium/core.',
32
32
  '',
33
33
  'Options:',
34
- ' --services <module> ESM module exporting `createServices(): { shared }` (required).',
34
+ ' --services <module> ESM module exporting `createServices(): { shared }` (required) unless package.json sets hydranium.services.',
35
35
  ...importHelpLines(22),
36
36
  ' --json Emit the raw JSON reflection instead of the Markdown report.',
37
37
  ' --out-file <file> Write the report to this file instead of stdout. Written',
@@ -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,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"}
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,4KAA4K;IAC5K,EAAE;IACF,4EAA4E;IAC5E,2EAA2E;IAC3E,0EAA0E;IAC1E,6EAA6E;IAC7E,mFAAmF;IACnF,EAAE;IACF,UAAU;IACV,qIAAqI;IACrI,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"}
@@ -22,7 +22,7 @@ export const VALIDATE_FLAGS = [...HARNESS_VALUE_FLAGS, ...VALUE_FLAGS, ...BOOL_F
22
22
  export const VALIDATE_VALUE_FLAGS = [...HARNESS_VALUE_FLAGS, ...VALUE_FLAGS];
23
23
  /** The `--help` text, as data, held to {@link VALIDATE_FLAGS} by a test. */
24
24
  export const VALIDATE_HELP = [
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
+ 'Usage: hydranium-cli validate [--services <module>] [--import <specifier>]... <workspace> [--strict] [--json] [--out-file <file>] [--log-level <lvl>] [--log-file <file>] [--log-file-level <lvl>]',
26
26
  '',
27
27
  'Build a workspace headlessly and report its validation diagnostics — a CI gate:',
28
28
  'the process exits non-zero when any error is found. `<module>` is an ESM module',
@@ -30,7 +30,7 @@ export const VALIDATE_HELP = [
30
30
  'filesystem inside). Needs @hydranium/core.',
31
31
  '',
32
32
  'Options:',
33
- ' --services <module> ESM module exporting `createServices(): { shared }` (required).',
33
+ ' --services <module> ESM module exporting `createServices(): { shared }` (required) unless package.json sets hydranium.services.',
34
34
  ...importHelpLines(22),
35
35
  ' <workspace> Workspace root (path or file URI) to validate (required).',
36
36
  ' --strict Also fail (non-zero exit) on warnings, not only errors.',
@@ -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,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"}
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,oMAAoM;IACpM,EAAE;IACF,iFAAiF;IACjF,iFAAiF;IACjF,mFAAmF;IACnF,4CAA4C;IAC5C,EAAE;IACF,UAAU;IACV,qIAAqI;IACrI,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/lib/index.d.ts CHANGED
@@ -16,4 +16,5 @@ export * from './commands/save.js';
16
16
  export * from './commands/watch.js';
17
17
  export * from './package-name.js';
18
18
  export * from './spawn-data-server.js';
19
+ export * from './commands/message-catalogue.js';
19
20
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oCAAoC,CAAC;AACnD,cAAc,uCAAuC,CAAC;AACtD,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oCAAoC,CAAC;AACnD,cAAc,uCAAuC,CAAC;AACtD,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,iCAAiC,CAAC"}
package/lib/index.js CHANGED
@@ -16,4 +16,5 @@ export * from './commands/save.js';
16
16
  export * from './commands/watch.js';
17
17
  export * from './package-name.js';
18
18
  export * from './spawn-data-server.js';
19
+ export * from './commands/message-catalogue.js';
19
20
  //# sourceMappingURL=index.js.map
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oCAAoC,CAAC;AACnD,cAAc,uCAAuC,CAAC;AACtD,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oCAAoC,CAAC;AACnD,cAAc,uCAAuC,CAAC;AACtD,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,iCAAiC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hydranium/cli",
3
- "version": "1.0.0-next.408",
3
+ "version": "1.0.0-next.411",
4
4
  "description": "Build-time codegen tools + data-server subcommands for the hydranium framework.",
5
5
  "keywords": [
6
6
  "cli",
@@ -67,6 +67,7 @@
67
67
  "dependencies": {
68
68
  "@clack/prompts": "~1.7.0",
69
69
  "commander": "^14.0.3",
70
+ "import-meta-resolve": "^4.2.0",
70
71
  "oxfmt": "0.71.0",
71
72
  "ts-morph": "^25.0.0"
72
73
  },
@@ -78,19 +79,19 @@
78
79
  "@eclipse-glsp/theia-integration": "2.8.0",
79
80
  "@eclipse-glsp/vscode-integration": "2.8.0",
80
81
  "@eclipse-glsp/vscode-integration-webview": "2.8.0",
81
- "@hydranium/client-browser": "1.0.0-next.408",
82
- "@hydranium/client-theia": "1.0.0-next.408",
83
- "@hydranium/client-vscode": "1.0.0-next.408",
84
- "@hydranium/core": "1.0.0-next.408",
85
- "@hydranium/data-client-theia": "1.0.0-next.408",
86
- "@hydranium/data-client-vscode": "1.0.0-next.408",
87
- "@hydranium/data-server": "1.0.0-next.408",
88
- "@hydranium/glsp-client": "1.0.0-next.408",
89
- "@hydranium/glsp-client-theia": "1.0.0-next.408",
90
- "@hydranium/glsp-client-vscode": "1.0.0-next.408",
91
- "@hydranium/glsp-server": "1.0.0-next.408",
92
- "@hydranium/langium": "1.0.0-next.408",
93
- "@hydranium/protocol": "1.0.0-next.408",
82
+ "@hydranium/client-browser": "1.0.0-next.411",
83
+ "@hydranium/client-theia": "1.0.0-next.411",
84
+ "@hydranium/client-vscode": "1.0.0-next.411",
85
+ "@hydranium/core": "1.0.0-next.411",
86
+ "@hydranium/data-client-theia": "1.0.0-next.411",
87
+ "@hydranium/data-client-vscode": "1.0.0-next.411",
88
+ "@hydranium/data-server": "1.0.0-next.411",
89
+ "@hydranium/glsp-client": "1.0.0-next.411",
90
+ "@hydranium/glsp-client-theia": "1.0.0-next.411",
91
+ "@hydranium/glsp-client-vscode": "1.0.0-next.411",
92
+ "@hydranium/glsp-server": "1.0.0-next.411",
93
+ "@hydranium/langium": "1.0.0-next.411",
94
+ "@hydranium/protocol": "1.0.0-next.411",
94
95
  "@playwright/test": "^1.55.0",
95
96
  "@theia/cli": "1.74.3",
96
97
  "@theia/core": "1.74.3",
@@ -129,10 +130,10 @@
129
130
  "vscode-languageserver-types": "3.18.4"
130
131
  },
131
132
  "peerDependencies": {
132
- "@hydranium/core": "1.0.0-next.408",
133
- "@hydranium/data-server": "1.0.0-next.408",
134
- "@hydranium/langium": "1.0.0-next.408",
135
- "@hydranium/protocol": "1.0.0-next.408",
133
+ "@hydranium/core": "1.0.0-next.411",
134
+ "@hydranium/data-server": "1.0.0-next.411",
135
+ "@hydranium/langium": "1.0.0-next.411",
136
+ "@hydranium/protocol": "1.0.0-next.411",
136
137
  "@memlab/core": "^2.0.3",
137
138
  "@memlab/heap-analysis": "^2.0.3",
138
139
  "vscode-jsonrpc": "^9.0.3"
package/src/cli.ts CHANGED
@@ -20,6 +20,7 @@ import { runInitCommand } from './commands/init-args.js';
20
20
  import { InitWizardCancelled } from './commands/init-prompt.js';
21
21
  import { runLintGrammarCommand } from './commands/lint-grammar-args.js';
22
22
  import { runMeasureMemoryCommand } from './commands/measure-memory-args.js';
23
+ import { runMessageCatalogueCommand } from './commands/message-catalogue-args.js';
23
24
  import { runModelDocsCommand } from './commands/model-docs-args.js';
24
25
  import { runProjectsCommand } from './commands/projects-args.js';
25
26
  import { runQueryCommand } from './commands/query-args.js';
@@ -56,6 +57,7 @@ const COMMANDS: Record<string, { readonly summary: string; readonly run: (args:
56
57
  init: { summary: 'Scaffold a new Hydranium language project (grammar + server head).', run: runInitCommand },
57
58
  'lint-grammar': { summary: 'Check a grammar against framework conventions (CI gate).', run: runLintGrammarCommand },
58
59
  'measure-memory': { summary: 'Measure model-store memory for a workspace (needs @hydranium/core).', run: runMeasureMemoryCommand },
60
+ 'message-catalogue': { summary: 'Emit a starter translation catalogue from message barrels.', run: runMessageCatalogueCommand },
59
61
  'model-docs': { summary: 'Generate a navigable Markdown model reference for adopter docs.', run: runModelDocsCommand },
60
62
  projects: { summary: 'List projects exposed by a data-server subprocess.', run: runProjectsCommand },
61
63
  query: { summary: 'Print the data-server document envelope for a URI.', run: runQueryCommand },
@@ -37,7 +37,7 @@ export const AST_GROUND_TRUTH_VALUE_FLAGS: readonly string[] = AST_GROUND_TRUTH_
37
37
 
38
38
  /** The `--help` text, as data, held to {@link AST_GROUND_TRUTH_FLAGS} by a test. */
39
39
  export const AST_GROUND_TRUTH_HELP: readonly string[] = [
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>]',
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>]',
41
41
  '',
42
42
  "Tally a workspace's live-model AST nodes by `$type` — the ground truth that",
43
43
  '`analyze-heap --validate <gt.json>` checks a heap snapshot against. `<module>`',
@@ -45,7 +45,7 @@ export const AST_GROUND_TRUTH_HELP: readonly string[] = [
45
45
  '`{ documents, totalAstNodes, byType }` JSON on stdout (or `--out-file`).',
46
46
  '',
47
47
  'Options:',
48
- ' --services <module> ESM module exporting `createServices(): { shared }` (required).',
48
+ ' --services <module> ESM module exporting `createServices(): { shared }` (required) unless package.json sets hydranium.services.',
49
49
  ...importHelpLines(22),
50
50
  ' <workspace> Workspace root (path or file URI) to build (required).',
51
51
  ' --out-file <file> Write the JSON to this file instead of stdout.',
@@ -32,7 +32,7 @@
32
32
  */
33
33
 
34
34
  import { describeError, type LogThreshold } from '@hydranium/protocol';
35
- import { statSync } from 'node:fs';
35
+ import { readFileSync, statSync } from 'node:fs';
36
36
  import * as fs from 'node:fs/promises';
37
37
  import * as path from 'node:path';
38
38
  import { fileURLToPath } from 'node:url';
@@ -57,7 +57,7 @@ export function exitWithUsage(message: string): never {
57
57
  process.exit(2);
58
58
  }
59
59
 
60
- /** Names the head's services module; every harness subcommand requires it. */
60
+ /** Overrides the services module configured by the project. */
61
61
  export const SERVICES_FLAG = '--services';
62
62
 
63
63
  /**
@@ -209,12 +209,13 @@ export interface HarnessArgsConfig {
209
209
  }
210
210
 
211
211
  /**
212
- * Shared parser for the headless-harness subcommands. Consumes the required
213
- * `--services <module>` value flag, the repeatable `--import <specifier>` and a
212
+ * Shared parser for the headless-harness subcommands. Consumes the
213
+ * `--services <module>` override, the repeatable `--import <specifier>` and a
214
214
  * single positional `<workspace>`, plus the `valueFlags` (each takes a value)
215
215
  * and `boolFlags` (presence-only, recorded as `'true'`) the subcommand
216
- * recognises. Unknown flags or a missing `--services`/`<workspace>` are usage
217
- * errors, and so is a `<workspace>` that reaches no directory — see
216
+ * recognises. Services default to the nearest package manifest. Unknown flags,
217
+ * missing services or a missing `<workspace>` are usage errors, and so is a
218
+ * `<workspace>` that reaches no directory — see
218
219
  * {@link resolveWorkspaceArgument} for why that cannot be left to the run.
219
220
  */
220
221
  export function parseHarnessArgs(
@@ -262,8 +263,14 @@ export function parseHarnessArgs(
262
263
  onError(`Unexpected argument: ${flag} (hydranium-cli ${commandName} --help)`);
263
264
  }
264
265
  }
266
+ servicesModule ??= configuredServicesModule(onError);
267
+ if (servicesModule === undefined) {
268
+ return onError(
269
+ `Missing required option: ${SERVICES_FLAG} (hydranium-cli ${commandName} --help). Pass --services or set hydranium.services in package.json.`
270
+ );
271
+ }
265
272
  return {
266
- servicesModule: assertRequired(servicesModule, SERVICES_FLAG, commandName, onError),
273
+ servicesModule,
267
274
  imports,
268
275
  workspace: requireWorkspace
269
276
  ? resolveWorkspaceArgument(assertRequired(workspace, '<workspace>', commandName, onError), commandName, onError)
@@ -273,6 +280,61 @@ export function parseHarnessArgs(
273
280
  };
274
281
  }
275
282
 
283
+ /**
284
+ * Stop at the nearest manifest even when it has no setting: inheriting through
285
+ * a workspace member would silently select another package's composition.
286
+ * Read only after argv, so an explicit override needs no valid project config.
287
+ */
288
+ function configuredServicesModule(onError: UsageError): string | undefined {
289
+ let directory = process.cwd();
290
+ for (;;) {
291
+ const manifestPath = path.join(directory, 'package.json');
292
+ if (statSync(manifestPath, { throwIfNoEntry: false }) !== undefined) {
293
+ let manifest: unknown;
294
+ try {
295
+ manifest = JSON.parse(readFileSync(manifestPath, 'utf8'));
296
+ } catch (error: unknown) {
297
+ return onError(`Cannot read ${manifestPath}: ${describeError(error)}`);
298
+ }
299
+ if (typeof manifest !== 'object' || manifest === null || Array.isArray(manifest)) {
300
+ return onError(`${manifestPath} must contain a JSON object.`);
301
+ }
302
+ if (!('hydranium' in manifest)) {
303
+ return undefined;
304
+ }
305
+ const configuration = manifest.hydranium;
306
+ if (typeof configuration !== 'object' || configuration === null || Array.isArray(configuration)) {
307
+ return onError(`hydranium in ${manifestPath} must be an object.`);
308
+ }
309
+ if (!('services' in configuration)) {
310
+ return undefined;
311
+ }
312
+ const services = configuration.services;
313
+ if (typeof services !== 'string' || services.trim() === '') {
314
+ return onError(`hydranium.services in ${manifestPath} must be a non-empty file path.`);
315
+ }
316
+ const modulePath = path.resolve(directory, services);
317
+ let stats;
318
+ try {
319
+ stats = statSync(modulePath, { throwIfNoEntry: false });
320
+ } catch (error: unknown) {
321
+ return onError(`Cannot read hydranium.services in ${manifestPath}: ${describeError(error)}`);
322
+ }
323
+ if (stats === undefined || !stats.isFile()) {
324
+ return onError(
325
+ `hydranium.services in ${manifestPath} points to '${services}' (${modulePath}), which is not an existing file. Build the project or correct the setting.`
326
+ );
327
+ }
328
+ return modulePath;
329
+ }
330
+ const parent = path.dirname(directory);
331
+ if (parent === directory) {
332
+ return undefined;
333
+ }
334
+ directory = parent;
335
+ }
336
+ }
337
+
276
338
  /**
277
339
  * Resolve the `<workspace>` positional to an absolute directory path, reporting
278
340
  * a usage error when it reaches anything else.
@@ -596,6 +596,9 @@ __DEPENDENCIES__
596
596
  },
597
597
  "engines": {
598
598
  "node": ">=22.13"
599
+ },
600
+ "hydranium": {
601
+ "services": "./lib/node/services.js"
599
602
  }
600
603
  }
601
604
  `;
@@ -977,7 +980,6 @@ ${importList(
977
980
  'createLspServerLanguageModule',
978
981
  'createLspServerSharedModule',
979
982
  'type HydraniumSemanticTokenProviderOptions',
980
- 'type LspServerAddedServices',
981
983
  'type LspServerAddedSharedServices'
982
984
  ],
983
985
  '@hydranium/core/lsp',
@@ -991,8 +993,7 @@ ${languageImports}
991
993
 
992
994
  export type __NAME__SharedServices = ServerSharedServices & LspServerAddedSharedServices;
993
995
  export type __NAME__Services = LangiumServices &
994
- ServerAddedServices &
995
- LspServerAddedServices & {
996
+ ServerAddedServices & {
996
997
  shared: __NAME__SharedServices;
997
998
  };
998
999
 
@@ -1002,7 +1003,7 @@ export interface __NAME__Options extends HydraniumSemanticTokenProviderOptions {
1002
1003
  * Shared modules layered in after the framework's own bindings.
1003
1004
  *
1004
1005
  * The framework constructs most shared services with no options —
1005
- * \`DocumentBuilder: services => new HydraniumDocumentBuilder(services)\` — so
1006
+ * \`DocumentBuilder: services => new DefaultHydraniumDocumentBuilder(services)\` — so
1006
1007
  * rebinding the slot is the only way to boot one configured differently, and
1007
1008
  * a factory that hard-codes its composition leaves a test nowhere to do it.
1008
1009
  * That is what this is for: pass a module binding \`workspace.DocumentBuilder\`
@@ -1797,13 +1798,13 @@ function readme(composition: InitComposition): string {
1797
1798
  // nowhere else.
1798
1799
  '```bash',
1799
1800
  '# Grammar / AST reflection',
1800
- 'npx hydranium-cli reflect --services ./lib/node/services.js',
1801
+ 'npx hydranium-cli reflect',
1801
1802
  '',
1802
1803
  '# Grammar-convention lint (CI gate)',
1803
- 'npx hydranium-cli lint-grammar --services ./lib/node/services.js',
1804
+ 'npx hydranium-cli lint-grammar',
1804
1805
  '',
1805
1806
  '# Validate a workspace of model files (non-zero exit on errors)',
1806
- 'npx hydranium-cli validate --services ./lib/node/services.js ../workspace',
1807
+ 'npx hydranium-cli validate ../workspace',
1807
1808
  ...(data
1808
1809
  ? [
1809
1810
  '',
@@ -4548,6 +4549,9 @@ ${sortedBlock(devDependencies, ' ')}
4548
4549
  },
4549
4550
  "engines": {
4550
4551
  "node": ">=22.13"
4552
+ },
4553
+ "hydranium": {
4554
+ "services": "./server/lib/node/services.js"
4551
4555
  }
4552
4556
  }
4553
4557
  `;
@@ -720,7 +720,11 @@ export function runInit(options: InitCommandOptions): void {
720
720
  }
721
721
  // `npx`, not a bare invocation: `@hydranium/cli` is a devDependency of the
722
722
  // scaffold, so the binary is on PATH inside an npm script and nowhere else.
723
- write(` npx hydranium-cli reflect --services ./${server}/lib/node/services.js\n`);
723
+ write(
724
+ detection === undefined
725
+ ? ' npx hydranium-cli reflect\n'
726
+ : ` npx hydranium-cli reflect --services ./${server}/lib/node/services.js\n`
727
+ );
724
728
  const hostDir = (host: InitHost): string => (detection === undefined ? `host-${host}` : `${detection.targetPath}/host-${host}`);
725
729
  // A standalone root runs a host as `start:<host>`. A surrounding workspace's root is not ours to add to.
726
730
  const start = (host: InitHost): string => (detection === undefined ? `npm run start:${host}` : `npm --prefix ${hostDir(host)} start`);
@@ -38,7 +38,7 @@ export const LINT_GRAMMAR_VALUE_FLAGS: readonly string[] = [...HARNESS_VALUE_FLA
38
38
 
39
39
  /** The `--help` text, as data, held to {@link LINT_GRAMMAR_FLAGS} by a test. */
40
40
  export const LINT_GRAMMAR_HELP: readonly string[] = [
41
- 'Usage: hydranium-cli lint-grammar --services <module> [--import <specifier>]... [--name-property <p>]... [--strict] [--json] [--log-level <lvl>] [--log-file <file>] [--log-file-level <lvl>]',
41
+ 'Usage: hydranium-cli lint-grammar [--services <module>] [--import <specifier>]... [--name-property <p>]... [--strict] [--json] [--log-level <lvl>] [--log-file <file>] [--log-file-level <lvl>]',
42
42
  '',
43
43
  "Check a head's grammar against the framework's conventions — a CI gate: the",
44
44
  'process exits non-zero when a violation is found. Read-only: no workspace is',
@@ -49,7 +49,7 @@ export const LINT_GRAMMAR_HELP: readonly string[] = [
49
49
  'zero-arg `createServices(): { shared }` thunk. Needs @hydranium/core.',
50
50
  '',
51
51
  'Options:',
52
- ' --services <module> ESM module exporting `createServices(): { shared }` (required).',
52
+ ' --services <module> ESM module exporting `createServices(): { shared }` (required) unless package.json sets hydranium.services.',
53
53
  ...importHelpLines(23),
54
54
  ' --name-property <p> Property that satisfies the nameability convention',
55
55
  ' (repeatable). Default: name.',
@@ -49,7 +49,7 @@ export const MEASURE_MEMORY_VALUE_FLAGS: readonly string[] = [...HARNESS_VALUE_F
49
49
 
50
50
  /** The `--help` text, as data, held to {@link MEASURE_MEMORY_FLAGS} by a test. */
51
51
  export const MEASURE_MEMORY_HELP: readonly string[] = [
52
- 'Usage: hydranium-cli measure-memory --services <module> [--import <specifier>]... <workspace> [options]',
52
+ 'Usage: hydranium-cli measure-memory [--services <module>] [--import <specifier>]... <workspace> [options]',
53
53
  '',
54
54
  'Measure model-store memory for a workspace. `<module>` is an ESM module that',
55
55
  'exports a zero-arg `createServices(): { shared }` thunk (the head wires its own',
@@ -57,7 +57,7 @@ export const MEASURE_MEMORY_HELP: readonly string[] = [
57
57
  'baseline / after-build / churn lines print on stdout. Needs @hydranium/core.',
58
58
  '',
59
59
  'Options:',
60
- ' --services <module> ESM module exporting `createServices(): { shared }` (required).',
60
+ ' --services <module> ESM module exporting `createServices(): { shared }` (required) unless package.json sets hydranium.services.',
61
61
  ...importHelpLines(22),
62
62
  ' <workspace> Workspace root (path or file URI) to build (required).',
63
63
  ' --edits <N> Rebuild-churn cycles to probe for retention. Default: 0 (skip).',