@hydranium/cli 1.0.0-next.22 → 1.0.0-next.220
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -5
- package/bin/hydranium-cli.js +13 -0
- package/lib/cli-version.js.map +1 -1
- package/lib/cli.js +0 -0
- package/lib/commands/analyze-heap-args.js.map +1 -1
- package/lib/commands/analyze-heap.d.ts +3 -0
- package/lib/commands/analyze-heap.d.ts.map +1 -1
- package/lib/commands/analyze-heap.js +2 -1
- package/lib/commands/analyze-heap.js.map +1 -1
- package/lib/commands/ast-ground-truth-args.d.ts +3 -2
- package/lib/commands/ast-ground-truth-args.d.ts.map +1 -1
- package/lib/commands/ast-ground-truth-args.js +11 -9
- package/lib/commands/ast-ground-truth-args.js.map +1 -1
- package/lib/commands/ast-ground-truth.js +1 -1
- package/lib/commands/ast-ground-truth.js.map +1 -1
- package/lib/commands/generate-ast-builder.d.ts +49 -0
- package/lib/commands/generate-ast-builder.d.ts.map +1 -0
- package/lib/commands/generate-ast-builder.js +200 -0
- package/lib/commands/generate-ast-builder.js.map +1 -0
- package/lib/commands/generate-transfer-model-args.d.ts.map +1 -1
- package/lib/commands/generate-transfer-model-args.js +11 -1
- package/lib/commands/generate-transfer-model-args.js.map +1 -1
- package/lib/commands/generate-transfer-model-config.d.ts.map +1 -1
- package/lib/commands/generate-transfer-model-config.js +3 -1
- package/lib/commands/generate-transfer-model-config.js.map +1 -1
- package/lib/commands/generate-transfer-model.d.ts +9 -0
- package/lib/commands/generate-transfer-model.d.ts.map +1 -1
- package/lib/commands/generate-transfer-model.js +16 -3
- package/lib/commands/generate-transfer-model.js.map +1 -1
- package/lib/commands/harness-args.d.ts +37 -42
- package/lib/commands/harness-args.d.ts.map +1 -1
- package/lib/commands/harness-args.js +65 -25
- package/lib/commands/harness-args.js.map +1 -1
- package/lib/commands/headless-harness.d.ts +37 -20
- package/lib/commands/headless-harness.d.ts.map +1 -1
- package/lib/commands/headless-harness.js +68 -17
- package/lib/commands/headless-harness.js.map +1 -1
- package/lib/commands/init-args.js.map +1 -1
- package/lib/commands/init-prompt.d.ts.map +1 -1
- package/lib/commands/init-templates.d.ts +0 -9
- package/lib/commands/init-templates.d.ts.map +1 -1
- package/lib/commands/init-templates.js +210 -96
- package/lib/commands/init-templates.js.map +1 -1
- package/lib/commands/init-wizard.js.map +1 -1
- package/lib/commands/init-workspace.d.ts +13 -3
- package/lib/commands/init-workspace.d.ts.map +1 -1
- package/lib/commands/init-workspace.js +21 -6
- package/lib/commands/init-workspace.js.map +1 -1
- package/lib/commands/init.d.ts +10 -2
- package/lib/commands/init.d.ts.map +1 -1
- package/lib/commands/init.js +10 -11
- package/lib/commands/init.js.map +1 -1
- package/lib/commands/lint-grammar-args.d.ts +3 -2
- package/lib/commands/lint-grammar-args.d.ts.map +1 -1
- package/lib/commands/lint-grammar-args.js +13 -10
- package/lib/commands/lint-grammar-args.js.map +1 -1
- package/lib/commands/lint-grammar-report.js.map +1 -1
- package/lib/commands/lint-grammar.js +1 -1
- package/lib/commands/lint-grammar.js.map +1 -1
- package/lib/commands/measure-memory-args.d.ts +3 -2
- package/lib/commands/measure-memory-args.d.ts.map +1 -1
- package/lib/commands/measure-memory-args.js +20 -10
- package/lib/commands/measure-memory-args.js.map +1 -1
- package/lib/commands/measure-memory-driver.js +3 -2
- package/lib/commands/measure-memory-driver.js.map +1 -1
- package/lib/commands/measure-memory.js +1 -1
- package/lib/commands/measure-memory.js.map +1 -1
- package/lib/commands/model-docs-args.d.ts +4 -3
- package/lib/commands/model-docs-args.d.ts.map +1 -1
- package/lib/commands/model-docs-args.js +12 -10
- package/lib/commands/model-docs-args.js.map +1 -1
- package/lib/commands/model-docs.js +1 -1
- package/lib/commands/model-docs.js.map +1 -1
- package/lib/commands/projects-args.d.ts.map +1 -1
- package/lib/commands/projects-args.js +5 -5
- package/lib/commands/projects-args.js.map +1 -1
- package/lib/commands/projects.d.ts +3 -4
- package/lib/commands/projects.d.ts.map +1 -1
- package/lib/commands/projects.js +2 -2
- package/lib/commands/projects.js.map +1 -1
- package/lib/commands/query-args.d.ts.map +1 -1
- package/lib/commands/query-args.js +5 -5
- package/lib/commands/query-args.js.map +1 -1
- package/lib/commands/query.d.ts +3 -4
- package/lib/commands/query.d.ts.map +1 -1
- package/lib/commands/query.js +2 -2
- package/lib/commands/query.js.map +1 -1
- package/lib/commands/reflect-args.d.ts +3 -2
- package/lib/commands/reflect-args.d.ts.map +1 -1
- package/lib/commands/reflect-args.js +13 -10
- package/lib/commands/reflect-args.js.map +1 -1
- package/lib/commands/reflect-report.js.map +1 -1
- package/lib/commands/reflect.js +1 -1
- package/lib/commands/reflect.js.map +1 -1
- package/lib/commands/save-args.d.ts.map +1 -1
- package/lib/commands/save-args.js +6 -4
- package/lib/commands/save-args.js.map +1 -1
- package/lib/commands/save.d.ts +8 -4
- package/lib/commands/save.d.ts.map +1 -1
- package/lib/commands/save.js +31 -6
- package/lib/commands/save.js.map +1 -1
- package/lib/commands/validate-args.d.ts +3 -2
- package/lib/commands/validate-args.d.ts.map +1 -1
- package/lib/commands/validate-args.js +13 -10
- package/lib/commands/validate-args.js.map +1 -1
- package/lib/commands/validate-report.js.map +1 -1
- package/lib/commands/validate.js +1 -1
- package/lib/commands/validate.js.map +1 -1
- package/lib/commands/watch-args.d.ts.map +1 -1
- package/lib/commands/watch-args.js +6 -4
- package/lib/commands/watch-args.js.map +1 -1
- package/lib/commands/watch.d.ts +3 -4
- package/lib/commands/watch.d.ts.map +1 -1
- package/lib/commands/watch.js +20 -2
- package/lib/commands/watch.js.map +1 -1
- package/lib/driver-heap.d.ts +52 -0
- package/lib/driver-heap.d.ts.map +1 -0
- package/lib/driver-heap.js +51 -0
- package/lib/driver-heap.js.map +1 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/lib/log-level.d.ts +21 -11
- package/lib/log-level.d.ts.map +1 -1
- package/lib/log-level.js +25 -14
- package/lib/log-level.js.map +1 -1
- package/lib/spawn-data-server.d.ts +6 -1
- package/lib/spawn-data-server.d.ts.map +1 -1
- package/lib/spawn-data-server.js +2 -1
- package/lib/spawn-data-server.js.map +1 -1
- package/lib/stderr-connection-logger.d.ts +12 -0
- package/lib/stderr-connection-logger.d.ts.map +1 -0
- package/lib/stderr-connection-logger.js +16 -0
- package/lib/stderr-connection-logger.js.map +1 -0
- package/lib/testing/echo-server.js +8 -1
- package/lib/testing/echo-server.js.map +1 -1
- package/package.json +39 -39
- package/src/commands/analyze-heap.ts +4 -1
- package/src/commands/ast-ground-truth-args.ts +15 -12
- package/src/commands/ast-ground-truth.ts +1 -1
- package/src/commands/generate-ast-builder.ts +246 -0
- package/src/commands/generate-transfer-model-args.ts +11 -1
- package/src/commands/generate-transfer-model-config.ts +3 -1
- package/src/commands/generate-transfer-model.ts +25 -3
- package/src/commands/harness-args.ts +73 -28
- package/src/commands/headless-harness.ts +86 -26
- package/src/commands/init-templates.ts +216 -97
- package/src/commands/init-workspace.ts +31 -7
- package/src/commands/init.ts +21 -14
- package/src/commands/lint-grammar-args.ts +17 -13
- package/src/commands/lint-grammar.ts +1 -1
- package/src/commands/measure-memory-args.ts +25 -13
- package/src/commands/measure-memory-driver.ts +3 -2
- package/src/commands/measure-memory.ts +1 -1
- package/src/commands/model-docs-args.ts +16 -13
- package/src/commands/model-docs.ts +1 -1
- package/src/commands/projects-args.ts +5 -4
- package/src/commands/projects.ts +4 -6
- package/src/commands/query-args.ts +5 -4
- package/src/commands/query.ts +4 -6
- package/src/commands/reflect-args.ts +17 -13
- package/src/commands/reflect.ts +1 -1
- package/src/commands/save-args.ts +6 -3
- package/src/commands/save.ts +49 -10
- package/src/commands/validate-args.ts +17 -13
- package/src/commands/validate.ts +1 -1
- package/src/commands/watch-args.ts +6 -3
- package/src/commands/watch.ts +28 -7
- package/src/driver-heap.ts +65 -0
- package/src/index.ts +1 -0
- package/src/log-level.ts +42 -14
- package/src/spawn-data-server.ts +14 -2
- package/src/stderr-connection-logger.ts +18 -0
- package/src/testing/echo-server.ts +10 -2
package/src/commands/init.ts
CHANGED
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
|
|
10
10
|
import * as fs from 'node:fs';
|
|
11
11
|
import * as path from 'node:path';
|
|
12
|
-
import { buildInitTemplates, readFrameworkVersion
|
|
13
|
-
import { createNodeWorkspaceProbe, detectWorkspace, type JsonValue, type WorkspaceProbe } from './init-workspace.js';
|
|
12
|
+
import { buildInitTemplates, readFrameworkVersion } from './init-templates.js';
|
|
13
|
+
import { createNodeWorkspaceProbe, detectWorkspace, parseNpmVersion, type JsonValue, type WorkspaceProbe } from './init-workspace.js';
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* The protocol heads a scaffold can start, in composition order.
|
|
@@ -128,10 +128,16 @@ export interface InitWorkspacePlacement {
|
|
|
128
128
|
readonly baseTsconfig?: string;
|
|
129
129
|
/** That tsconfig's `compilerOptions`, so the emitted one can omit what it would inherit unchanged. */
|
|
130
130
|
readonly baseCompilerOptions?: Readonly<Record<string, JsonValue>>;
|
|
131
|
-
/** The workspace's
|
|
131
|
+
/** The workspace's formatter `printWidth`, so emitted sources wrap where the repo wraps. */
|
|
132
132
|
readonly printWidth?: number;
|
|
133
133
|
/** Filename of the workspace's eslint config; its presence is what makes the scaffold emit a `lint` script. */
|
|
134
134
|
readonly eslintConfig?: string;
|
|
135
|
+
/** Filename of the workspace Oxlint config, when present. */
|
|
136
|
+
readonly oxlintConfig?: string;
|
|
137
|
+
/** The npm version the workspace root's `packageManager` declares; with {@link npmVersion} it decides the scaffold's `vitest` range. */
|
|
138
|
+
readonly packageManagerNpm?: string;
|
|
139
|
+
/** The npm running `init`, when known. npm does not enforce `packageManager`, so a declaration alone cannot lift `vitest`. */
|
|
140
|
+
readonly npmVersion?: string;
|
|
135
141
|
}
|
|
136
142
|
|
|
137
143
|
/**
|
|
@@ -432,6 +438,8 @@ export interface InitPackagingOptions {
|
|
|
432
438
|
readonly scope?: string;
|
|
433
439
|
readonly public?: boolean;
|
|
434
440
|
readonly probe?: WorkspaceProbe;
|
|
441
|
+
/** The npm running `init`. Defaults to the one `npm_config_user_agent` names, which `npx` and `npm run` set. */
|
|
442
|
+
readonly npmVersion?: string;
|
|
435
443
|
}
|
|
436
444
|
|
|
437
445
|
/**
|
|
@@ -466,7 +474,10 @@ export function resolveInitPackaging(targetDir: string, options: InitPackagingOp
|
|
|
466
474
|
baseTsconfig: detection.baseTsconfig,
|
|
467
475
|
baseCompilerOptions: detection.baseCompilerOptions,
|
|
468
476
|
printWidth: detection.printWidth,
|
|
469
|
-
eslintConfig: detection.eslintConfig
|
|
477
|
+
eslintConfig: detection.eslintConfig,
|
|
478
|
+
oxlintConfig: detection.oxlintConfig,
|
|
479
|
+
packageManagerNpm: detection.packageManagerNpm,
|
|
480
|
+
npmVersion: options.npmVersion ?? parseNpmVersion(process.env.npm_config_user_agent)
|
|
470
481
|
}
|
|
471
482
|
};
|
|
472
483
|
}
|
|
@@ -515,10 +526,12 @@ export function runInit(options: InitCommandOptions): void {
|
|
|
515
526
|
}
|
|
516
527
|
write(" .gitignore holds `syntaxes/` only — the workspace root's covers the rest.\n");
|
|
517
528
|
if (detection.printWidth !== undefined) {
|
|
518
|
-
write(` Sources wrapped at ${detection.printWidth} columns, from ${detection.rootDir}'s
|
|
529
|
+
write(` Sources wrapped at ${detection.printWidth} columns, from ${detection.rootDir}'s formatter config.\n`);
|
|
519
530
|
}
|
|
520
|
-
if (detection.eslintConfig !== undefined) {
|
|
521
|
-
write(
|
|
531
|
+
if (detection.oxlintConfig !== undefined || detection.eslintConfig !== undefined) {
|
|
532
|
+
write(
|
|
533
|
+
` A lint script was added — ${detection.oxlintConfig ?? detection.eslintConfig} says this repo lints. Adjust it if your invocation differs.\n`
|
|
534
|
+
);
|
|
522
535
|
}
|
|
523
536
|
// Printed rather than applied: `init` writes inside the target directory
|
|
524
537
|
// and nowhere else, so a scaffold can never surprise-edit a manifest that
|
|
@@ -536,13 +549,7 @@ export function runInit(options: InitCommandOptions): void {
|
|
|
536
549
|
write('\n');
|
|
537
550
|
write('Next steps:\n');
|
|
538
551
|
write(` cd ${options.targetDir}\n`);
|
|
539
|
-
|
|
540
|
-
// `UNPUBLISHED_FRAMEWORK_VERSION`.
|
|
541
|
-
write(
|
|
542
|
-
composition.frameworkVersion === UNPUBLISHED_FRAMEWORK_VERSION
|
|
543
|
-
? ' npm install # 404s until @hydranium/* is published — see README\n'
|
|
544
|
-
: ' npm install\n'
|
|
545
|
-
);
|
|
552
|
+
write(' npm install\n');
|
|
546
553
|
write(' npm run build # langium generate + tsc\n');
|
|
547
554
|
write(' npm test # the scaffolded DI-composition test\n');
|
|
548
555
|
// `npx`, not a bare invocation: `@hydranium/cli` is a devDependency of the
|
|
@@ -9,34 +9,36 @@
|
|
|
9
9
|
|
|
10
10
|
import {
|
|
11
11
|
exitWithUsage,
|
|
12
|
+
HARNESS_VALUE_FLAGS,
|
|
12
13
|
helpRequested,
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
importHelpLines,
|
|
15
|
+
LOG_VALUE_FLAGS,
|
|
16
|
+
logHelpLines,
|
|
17
|
+
logOptions,
|
|
16
18
|
parseHarnessArgs,
|
|
17
19
|
printHelp,
|
|
18
|
-
SERVICES_FLAG,
|
|
19
20
|
type UsageError
|
|
20
21
|
} from './harness-args.js';
|
|
21
22
|
import { runLintGrammar, type LintGrammarCommandOptions } from './lint-grammar.js';
|
|
22
23
|
|
|
23
|
-
const VALUE_FLAGS = [
|
|
24
|
+
const VALUE_FLAGS = [...LOG_VALUE_FLAGS] as const;
|
|
24
25
|
const BOOL_FLAGS = ['--strict', '--json'] as const;
|
|
25
26
|
const REPEATABLE_VALUE_FLAGS = ['--name-property'] as const;
|
|
26
27
|
|
|
27
28
|
/**
|
|
28
29
|
* Every flag `lint-grammar` accepts, derived from the sets the parser is handed
|
|
29
|
-
* so the list cannot claim a flag the parser would reject.
|
|
30
|
-
* consumed by the shared harness parser itself,
|
|
30
|
+
* so the list cannot claim a flag the parser would reject.
|
|
31
|
+
* {@link HARNESS_VALUE_FLAGS} are consumed by the shared harness parser itself,
|
|
32
|
+
* so they are in neither set.
|
|
31
33
|
*/
|
|
32
|
-
export const LINT_GRAMMAR_FLAGS: readonly string[] = [
|
|
34
|
+
export const LINT_GRAMMAR_FLAGS: readonly string[] = [...HARNESS_VALUE_FLAGS, ...REPEATABLE_VALUE_FLAGS, ...VALUE_FLAGS, ...BOOL_FLAGS];
|
|
33
35
|
|
|
34
36
|
/** The subset that takes a value, so `--help` in a value position reads as data. */
|
|
35
|
-
export const LINT_GRAMMAR_VALUE_FLAGS: readonly string[] = [
|
|
37
|
+
export const LINT_GRAMMAR_VALUE_FLAGS: readonly string[] = [...HARNESS_VALUE_FLAGS, ...REPEATABLE_VALUE_FLAGS, ...VALUE_FLAGS];
|
|
36
38
|
|
|
37
39
|
/** The `--help` text, as data, held to {@link LINT_GRAMMAR_FLAGS} by a test. */
|
|
38
40
|
export const LINT_GRAMMAR_HELP: readonly string[] = [
|
|
39
|
-
'Usage: hydranium-cli lint-grammar --services <module> [--name-property <p>]... [--strict] [--json] [--log-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>]',
|
|
40
42
|
'',
|
|
41
43
|
"Check a head's grammar against the framework's conventions — a CI gate: the",
|
|
42
44
|
'process exits non-zero when a violation is found. Read-only: no workspace is',
|
|
@@ -48,25 +50,27 @@ export const LINT_GRAMMAR_HELP: readonly string[] = [
|
|
|
48
50
|
'',
|
|
49
51
|
'Options:',
|
|
50
52
|
' --services <module> ESM module exporting `createServices(): { shared }` (required).',
|
|
53
|
+
...importHelpLines(23),
|
|
51
54
|
' --name-property <p> Property that satisfies the nameability convention',
|
|
52
55
|
' (repeatable). Default: name.',
|
|
53
56
|
' --strict Also fail (non-zero exit) on warnings, not only errors.',
|
|
54
57
|
' --json Emit the raw JSON result instead of the human report.',
|
|
55
|
-
|
|
58
|
+
...logHelpLines(23)
|
|
56
59
|
];
|
|
57
60
|
|
|
58
61
|
export function parseLintGrammarArgs(args: string[], onError: UsageError = exitWithUsage): LintGrammarCommandOptions {
|
|
59
|
-
const { servicesModule, options, values } = parseHarnessArgs(args, 'lint-grammar', VALUE_FLAGS, BOOL_FLAGS, {
|
|
62
|
+
const { servicesModule, imports, options, values } = parseHarnessArgs(args, 'lint-grammar', VALUE_FLAGS, BOOL_FLAGS, {
|
|
60
63
|
requireWorkspace: false,
|
|
61
64
|
repeatableValueFlags: REPEATABLE_VALUE_FLAGS,
|
|
62
65
|
onError
|
|
63
66
|
});
|
|
64
67
|
return {
|
|
65
68
|
servicesModule,
|
|
69
|
+
imports,
|
|
66
70
|
nameProperties: values['--name-property'],
|
|
67
71
|
strict: options['--strict'] === 'true',
|
|
68
72
|
json: options['--json'] === 'true',
|
|
69
|
-
|
|
73
|
+
...logOptions(options)
|
|
70
74
|
};
|
|
71
75
|
}
|
|
72
76
|
|
|
@@ -53,5 +53,5 @@ export function buildLintGrammarDriverArgs(options: LintGrammarCommandOptions):
|
|
|
53
53
|
* `createServices` module, keeping the binary language-agnostic.
|
|
54
54
|
*/
|
|
55
55
|
export function runLintGrammar(options: LintGrammarCommandOptions): Promise<void> {
|
|
56
|
-
return runDriverChild([
|
|
56
|
+
return runDriverChild([DRIVER, ...buildLintGrammarDriverArgs(options)], options);
|
|
57
57
|
}
|
|
@@ -9,14 +9,16 @@
|
|
|
9
9
|
|
|
10
10
|
import {
|
|
11
11
|
exitWithUsage,
|
|
12
|
+
HARNESS_VALUE_FLAGS,
|
|
12
13
|
helpRequested,
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
importHelpLines,
|
|
15
|
+
LOG_FILE_FLAG,
|
|
16
|
+
LOG_VALUE_FLAGS,
|
|
17
|
+
logHelpLines,
|
|
18
|
+
logOptions,
|
|
16
19
|
numericOption,
|
|
17
20
|
parseHarnessArgs,
|
|
18
21
|
printHelp,
|
|
19
|
-
SERVICES_FLAG,
|
|
20
22
|
type UsageError
|
|
21
23
|
} from './harness-args.js';
|
|
22
24
|
import { parseProfileDimensions, runMeasureMemory, type MeasureMemoryCommandOptions } from './measure-memory.js';
|
|
@@ -29,23 +31,24 @@ const VALUE_FLAGS = [
|
|
|
29
31
|
'--snapshot-path',
|
|
30
32
|
'--profile',
|
|
31
33
|
'--session-out',
|
|
32
|
-
|
|
34
|
+
...LOG_VALUE_FLAGS
|
|
33
35
|
] as const;
|
|
34
36
|
const BOOL_FLAGS = ['--snapshot', '--json'] as const;
|
|
35
37
|
|
|
36
38
|
/**
|
|
37
39
|
* Every flag `measure-memory` accepts, derived from the sets the parser is
|
|
38
|
-
* handed so the list cannot claim a flag the parser would reject.
|
|
39
|
-
*
|
|
40
|
+
* handed so the list cannot claim a flag the parser would reject.
|
|
41
|
+
* {@link HARNESS_VALUE_FLAGS} are consumed by the shared harness parser itself,
|
|
42
|
+
* so they are in neither set.
|
|
40
43
|
*/
|
|
41
|
-
export const MEASURE_MEMORY_FLAGS: readonly string[] = [
|
|
44
|
+
export const MEASURE_MEMORY_FLAGS: readonly string[] = [...HARNESS_VALUE_FLAGS, ...VALUE_FLAGS, ...BOOL_FLAGS];
|
|
42
45
|
|
|
43
46
|
/** The subset that takes a value, so `--help` in a value position reads as data. */
|
|
44
|
-
export const MEASURE_MEMORY_VALUE_FLAGS: readonly string[] = [
|
|
47
|
+
export const MEASURE_MEMORY_VALUE_FLAGS: readonly string[] = [...HARNESS_VALUE_FLAGS, ...VALUE_FLAGS];
|
|
45
48
|
|
|
46
49
|
/** The `--help` text, as data, held to {@link MEASURE_MEMORY_FLAGS} by a test. */
|
|
47
50
|
export const MEASURE_MEMORY_HELP: readonly string[] = [
|
|
48
|
-
'Usage: hydranium-cli measure-memory --services <module> <workspace> [options]',
|
|
51
|
+
'Usage: hydranium-cli measure-memory --services <module> [--import <specifier>]... <workspace> [options]',
|
|
49
52
|
'',
|
|
50
53
|
'Measure model-store memory for a workspace. `<module>` is an ESM module that',
|
|
51
54
|
'exports a zero-arg `createServices(): { shared }` thunk (the head wires its own',
|
|
@@ -54,6 +57,7 @@ export const MEASURE_MEMORY_HELP: readonly string[] = [
|
|
|
54
57
|
'',
|
|
55
58
|
'Options:',
|
|
56
59
|
' --services <module> ESM module exporting `createServices(): { shared }` (required).',
|
|
60
|
+
...importHelpLines(22),
|
|
57
61
|
' <workspace> Workspace root (path or file URI) to build (required).',
|
|
58
62
|
' --edits <N> Rebuild-churn cycles to probe for retention. Default: 0 (skip).',
|
|
59
63
|
' --edit-docs <N> Documents to churn per cycle. Default: 25.',
|
|
@@ -67,11 +71,13 @@ export const MEASURE_MEMORY_HELP: readonly string[] = [
|
|
|
67
71
|
' --profile <dims> Capture sampled profiles around the build (+churn) into a',
|
|
68
72
|
' profiling session. Comma-separated: cpu,alloc,gc,eld,heap.',
|
|
69
73
|
' --session-out <dir> Parent directory for the profiling session folder (with --profile).',
|
|
74
|
+
' The session logs to its server.log at --log-file-level, else at',
|
|
75
|
+
' --log-level, else info; --log-file is refused beside --profile.',
|
|
70
76
|
' --json Emit the measurement as one JSON document instead of the',
|
|
71
77
|
' progress lines: documentCount, buildMs, emptyHeapBytes,',
|
|
72
78
|
' afterBuildHeapBytes, and churnGrowthBytes / snapshotPath /',
|
|
73
79
|
' profilingSession where the run produced them.',
|
|
74
|
-
|
|
80
|
+
...logHelpLines(22)
|
|
75
81
|
];
|
|
76
82
|
|
|
77
83
|
/**
|
|
@@ -97,9 +103,15 @@ function validatedProfile(csv: string | undefined, onError: UsageError): string
|
|
|
97
103
|
}
|
|
98
104
|
|
|
99
105
|
export function parseMeasureMemoryArgs(args: string[], onError: UsageError = exitWithUsage): MeasureMemoryCommandOptions {
|
|
100
|
-
const { servicesModule, workspace, options } = parseHarnessArgs(args, 'measure-memory', VALUE_FLAGS, BOOL_FLAGS, { onError });
|
|
106
|
+
const { servicesModule, imports, workspace, options } = parseHarnessArgs(args, 'measure-memory', VALUE_FLAGS, BOOL_FLAGS, { onError });
|
|
107
|
+
// The profiling session points the log at its own `server.log`, which would
|
|
108
|
+
// replace the requested file without a word.
|
|
109
|
+
if (options['--profile'] !== undefined && options[LOG_FILE_FLAG] !== undefined) {
|
|
110
|
+
onError(`${LOG_FILE_FLAG} cannot be combined with --profile, which logs to the session's server.log`);
|
|
111
|
+
}
|
|
101
112
|
return {
|
|
102
113
|
servicesModule,
|
|
114
|
+
imports,
|
|
103
115
|
workspace,
|
|
104
116
|
editCycles: numericOption(options['--edits'], '--edits', onError),
|
|
105
117
|
editDocs: numericOption(options['--edit-docs'], '--edit-docs', onError),
|
|
@@ -110,7 +122,7 @@ export function parseMeasureMemoryArgs(args: string[], onError: UsageError = exi
|
|
|
110
122
|
profile: validatedProfile(options['--profile'], onError),
|
|
111
123
|
sessionOut: options['--session-out'],
|
|
112
124
|
json: options['--json'] === 'true',
|
|
113
|
-
|
|
125
|
+
...logOptions(options)
|
|
114
126
|
};
|
|
115
127
|
}
|
|
116
128
|
|
|
@@ -9,8 +9,9 @@
|
|
|
9
9
|
|
|
10
10
|
/*
|
|
11
11
|
* Spawned child of the `measure-memory` subcommand. Launched by the parent with
|
|
12
|
-
* `node --expose-gc
|
|
13
|
-
* so the underlying harness gets post-GC readings.
|
|
12
|
+
* `node [heap ceiling] --expose-gc <this> --services <module> <workspace> ...`
|
|
13
|
+
* so the underlying harness gets post-GC readings. The ceiling is whatever
|
|
14
|
+
* `driverHeapArgs` decides, which is nothing at all inside a container. It dynamic-imports the head's
|
|
14
15
|
* services module and runs the framework's `measureModelMemory`, streaming the
|
|
15
16
|
* baseline / after-build / churn lines to stdout. Never imported — only spawned.
|
|
16
17
|
*/
|
|
@@ -139,5 +139,5 @@ export function buildDriverArgs(options: MeasureMemoryCommandOptions): string[]
|
|
|
139
139
|
* module and reports the baseline / after-build / churn lines on stdout.
|
|
140
140
|
*/
|
|
141
141
|
export function runMeasureMemory(options: MeasureMemoryCommandOptions): Promise<void> {
|
|
142
|
-
return runDriverChild(['--expose-gc',
|
|
142
|
+
return runDriverChild(['--expose-gc', DRIVER, ...buildDriverArgs(options)], options);
|
|
143
143
|
}
|
|
@@ -9,33 +9,35 @@
|
|
|
9
9
|
|
|
10
10
|
import {
|
|
11
11
|
exitWithUsage,
|
|
12
|
+
HARNESS_VALUE_FLAGS,
|
|
12
13
|
helpRequested,
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
importHelpLines,
|
|
15
|
+
LOG_VALUE_FLAGS,
|
|
16
|
+
logHelpLines,
|
|
17
|
+
logOptions,
|
|
16
18
|
parseHarnessArgs,
|
|
17
19
|
printHelp,
|
|
18
|
-
SERVICES_FLAG,
|
|
19
20
|
type UsageError
|
|
20
21
|
} from './harness-args.js';
|
|
21
22
|
import { OUT_FILE_FLAG } from './headless-harness.js';
|
|
22
23
|
import { runModelDocs, type ModelDocsCommandOptions } from './model-docs.js';
|
|
23
24
|
|
|
24
|
-
const VALUE_FLAGS = [OUT_FILE_FLAG,
|
|
25
|
+
const VALUE_FLAGS = [OUT_FILE_FLAG, ...LOG_VALUE_FLAGS] as const;
|
|
25
26
|
|
|
26
27
|
/**
|
|
27
|
-
* Every flag `model-docs` accepts, derived from the sets the parser is handed
|
|
28
|
-
* the list cannot claim a flag the parser would reject.
|
|
29
|
-
* by the shared harness parser itself,
|
|
28
|
+
* Every flag `model-docs` accepts, derived from the sets the parser is handed
|
|
29
|
+
* 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 MODEL_DOCS_FLAGS: readonly string[] = [
|
|
33
|
+
export const MODEL_DOCS_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 MODEL_DOCS_VALUE_FLAGS: readonly string[] = MODEL_DOCS_FLAGS;
|
|
35
37
|
|
|
36
38
|
/** The `--help` text, as data, held to {@link MODEL_DOCS_FLAGS} by a test. */
|
|
37
39
|
export const MODEL_DOCS_HELP: readonly string[] = [
|
|
38
|
-
'Usage: hydranium-cli model-docs --services <module> [--out-file <file>] [--log-level <lvl>]',
|
|
40
|
+
'Usage: hydranium-cli model-docs --services <module> [--import <specifier>]... [--out-file <file>] [--log-level <lvl>] [--log-file <file>] [--log-file-level <lvl>]',
|
|
39
41
|
'',
|
|
40
42
|
'Generate a navigable Markdown reference of every AST node type — a type index,',
|
|
41
43
|
'cross-linked super/sub types, a reverse "referenced by" index, and a per-language',
|
|
@@ -46,18 +48,19 @@ export const MODEL_DOCS_HELP: readonly string[] = [
|
|
|
46
48
|
'',
|
|
47
49
|
'Options:',
|
|
48
50
|
' --services <module> ESM module exporting `createServices(): { shared }` (required).',
|
|
51
|
+
...importHelpLines(22),
|
|
49
52
|
' --out-file <file> Write the Markdown to this file instead of stdout. Written',
|
|
50
53
|
' only once the report exists, unlike a shell redirection,',
|
|
51
54
|
' which truncates the file before the head is even booted.',
|
|
52
|
-
|
|
55
|
+
...logHelpLines(22)
|
|
53
56
|
];
|
|
54
57
|
|
|
55
58
|
export function parseModelDocsArgs(args: string[], onError: UsageError = exitWithUsage): ModelDocsCommandOptions {
|
|
56
|
-
const { servicesModule, options } = parseHarnessArgs(args, 'model-docs', VALUE_FLAGS, [], {
|
|
59
|
+
const { servicesModule, imports, options } = parseHarnessArgs(args, 'model-docs', VALUE_FLAGS, [], {
|
|
57
60
|
requireWorkspace: false,
|
|
58
61
|
onError
|
|
59
62
|
});
|
|
60
|
-
return { servicesModule, outFile: options[OUT_FILE_FLAG],
|
|
63
|
+
return { servicesModule, imports, outFile: options[OUT_FILE_FLAG], ...logOptions(options) };
|
|
61
64
|
}
|
|
62
65
|
|
|
63
66
|
export function runModelDocsCommand(args: string[]): Promise<void> {
|
|
@@ -44,5 +44,5 @@ export function buildModelDocsDriverArgs(options: ModelDocsCommandOptions): stri
|
|
|
44
44
|
* module, keeping the binary language-agnostic.
|
|
45
45
|
*/
|
|
46
46
|
export function runModelDocs(options: ModelDocsCommandOptions): Promise<void> {
|
|
47
|
-
return runDriverChild([
|
|
47
|
+
return runDriverChild([DRIVER, ...buildModelDocsDriverArgs(options)], options);
|
|
48
48
|
}
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
import {
|
|
11
11
|
exitWithUsage,
|
|
12
12
|
helpRequested,
|
|
13
|
+
logHelpLines,
|
|
13
14
|
parseFlagOptions,
|
|
14
15
|
parseServerSpawnOptions,
|
|
15
16
|
printHelp,
|
|
@@ -32,7 +33,7 @@ export const PROJECTS_VALUE_FLAGS: readonly string[] = PROJECTS_FLAGS;
|
|
|
32
33
|
|
|
33
34
|
/** The `--help` text, as data, held to {@link PROJECTS_FLAGS} by a test. */
|
|
34
35
|
export const PROJECTS_HELP: readonly string[] = [
|
|
35
|
-
'Usage: hydranium-cli projects --server "<cmd> [args...]" [--cwd <dir>] [--log-level <level>]',
|
|
36
|
+
'Usage: hydranium-cli projects --server "<cmd> [args...]" [--cwd <dir>] [--log-level <lvl>] [--log-file <file>] [--log-file-level <lvl>]',
|
|
36
37
|
'',
|
|
37
38
|
'List projects exposed by the data-server subprocess. Output is newline-delimited',
|
|
38
39
|
'JSON — one project envelope per line.',
|
|
@@ -40,17 +41,17 @@ export const PROJECTS_HELP: readonly string[] = [
|
|
|
40
41
|
'Options:',
|
|
41
42
|
' --server "<cmd>" Command-line for the data-server subprocess (required).',
|
|
42
43
|
' --cwd <dir> Working directory for the spawned child. Default: cwd.',
|
|
43
|
-
'
|
|
44
|
+
...logHelpLines(19, 'the spawned server')
|
|
44
45
|
];
|
|
45
46
|
|
|
46
47
|
export function parseProjectsArgs(args: string[], onError: UsageError = exitWithUsage): ProjectsCommandOptions {
|
|
47
|
-
const { serverCommand, serverArgs, cwd, logLevel, extra } = parseServerSpawnOptions(args, 'projects', onError);
|
|
48
|
+
const { serverCommand, serverArgs, cwd, logLevel, logFile, logFileLevel, extra } = parseServerSpawnOptions(args, 'projects', onError);
|
|
48
49
|
// `projects` declares no options beyond the shared ones, so nothing may
|
|
49
50
|
// survive the spawn parser. Draining `extra` against an empty set is what
|
|
50
51
|
// makes a typo an error here rather than a flag that silently did nothing —
|
|
51
52
|
// the siblings get this from the option list they pass.
|
|
52
53
|
parseFlagOptions(extra, 'projects', [], onError);
|
|
53
|
-
return { serverCommand, serverArgs, cwd, logLevel };
|
|
54
|
+
return { serverCommand, serverArgs, cwd, logLevel, logFile, logFileLevel };
|
|
54
55
|
}
|
|
55
56
|
|
|
56
57
|
export function runProjectsCommand(args: string[]): Promise<void> {
|
package/src/commands/projects.ts
CHANGED
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
* SPDX-License-Identifier: MIT
|
|
8
8
|
********************************************************************************/
|
|
9
9
|
|
|
10
|
-
import type {
|
|
10
|
+
import type { Project, TransferElement } from '@hydranium/protocol';
|
|
11
11
|
import type { DataServerProtocol } from '@hydranium/protocol/data';
|
|
12
|
-
import {
|
|
12
|
+
import { logEnv, type LogOptions } from '../log-level.js';
|
|
13
13
|
import { withDataServer } from '../spawn-data-server.js';
|
|
14
14
|
|
|
15
15
|
/**
|
|
@@ -17,7 +17,7 @@ import { withDataServer } from '../spawn-data-server.js';
|
|
|
17
17
|
* `serverArgs` mirror what an adopter would pass to spawn the data-server
|
|
18
18
|
* subprocess.
|
|
19
19
|
*/
|
|
20
|
-
export interface ProjectsCommandOptions {
|
|
20
|
+
export interface ProjectsCommandOptions extends LogOptions {
|
|
21
21
|
/**
|
|
22
22
|
* Command-line tokens used to spawn the data-server child. Mirrors
|
|
23
23
|
* the `--server "<cmd> [args...]"` shape on the CLI surface — split
|
|
@@ -26,8 +26,6 @@ export interface ProjectsCommandOptions {
|
|
|
26
26
|
readonly serverCommand: string;
|
|
27
27
|
readonly serverArgs?: readonly string[];
|
|
28
28
|
readonly cwd?: string;
|
|
29
|
-
/** Log threshold for the spawned server, set on its `HYDRANIUM_LOG_LEVEL` env. */
|
|
30
|
-
readonly logLevel?: LogThreshold;
|
|
31
29
|
/**
|
|
32
30
|
* Output sink. Default: `process.stdout.write`. Tests inject a
|
|
33
31
|
* capturing stub.
|
|
@@ -60,7 +58,7 @@ export async function runProjects(options: ProjectsCommandOptions): Promise<void
|
|
|
60
58
|
command: options.serverCommand,
|
|
61
59
|
args: options.serverArgs,
|
|
62
60
|
cwd: options.cwd,
|
|
63
|
-
env:
|
|
61
|
+
env: logEnv(options)
|
|
64
62
|
},
|
|
65
63
|
async server => {
|
|
66
64
|
const projects = await server.getProjects();
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
assertRequired,
|
|
12
12
|
exitWithUsage,
|
|
13
13
|
helpRequested,
|
|
14
|
+
logHelpLines,
|
|
14
15
|
parseFlagOptions,
|
|
15
16
|
parseServerSpawnOptions,
|
|
16
17
|
printHelp,
|
|
@@ -35,7 +36,7 @@ export const QUERY_VALUE_FLAGS: readonly string[] = QUERY_FLAGS;
|
|
|
35
36
|
|
|
36
37
|
/** The `--help` text, as data, held to {@link QUERY_FLAGS} by a test. */
|
|
37
38
|
export const QUERY_HELP: readonly string[] = [
|
|
38
|
-
'Usage: hydranium-cli query --server "<cmd> [args...]" --uri <uri> [--cwd <dir>] [--log-level <level>]',
|
|
39
|
+
'Usage: hydranium-cli query --server "<cmd> [args...]" --uri <uri> [--cwd <dir>] [--log-level <lvl>] [--log-file <file>] [--log-file-level <lvl>]',
|
|
39
40
|
'',
|
|
40
41
|
'Print the data-server document envelope for `<uri>` as a single JSON line.',
|
|
41
42
|
'',
|
|
@@ -43,13 +44,13 @@ export const QUERY_HELP: readonly string[] = [
|
|
|
43
44
|
' --server "<cmd>" Command-line for the data-server subprocess (required).',
|
|
44
45
|
' --uri <uri> Document URI (required).',
|
|
45
46
|
' --cwd <dir> Working directory for the spawned child. Default: cwd.',
|
|
46
|
-
'
|
|
47
|
+
...logHelpLines(19, 'the spawned server')
|
|
47
48
|
];
|
|
48
49
|
|
|
49
50
|
export function parseQueryArgs(args: string[], onError: UsageError = exitWithUsage): QueryCommandOptions {
|
|
50
|
-
const { serverCommand, serverArgs, cwd, logLevel, extra } = parseServerSpawnOptions(args, 'query', onError);
|
|
51
|
+
const { serverCommand, serverArgs, cwd, logLevel, logFile, logFileLevel, extra } = parseServerSpawnOptions(args, 'query', onError);
|
|
51
52
|
const { uri } = parseFlagOptions(extra, 'query', OWN_FLAGS, onError);
|
|
52
|
-
return { serverCommand, serverArgs, cwd, logLevel, uri: assertRequired(uri, '--uri', 'query', onError) };
|
|
53
|
+
return { serverCommand, serverArgs, cwd, logLevel, logFile, logFileLevel, uri: assertRequired(uri, '--uri', 'query', onError) };
|
|
53
54
|
}
|
|
54
55
|
|
|
55
56
|
export function runQueryCommand(args: string[]): Promise<void> {
|
package/src/commands/query.ts
CHANGED
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
* SPDX-License-Identifier: MIT
|
|
8
8
|
********************************************************************************/
|
|
9
9
|
|
|
10
|
-
import type {
|
|
10
|
+
import type { TransferElement } from '@hydranium/protocol';
|
|
11
11
|
import type { DataServerProtocol } from '@hydranium/protocol/data';
|
|
12
|
-
import {
|
|
12
|
+
import { logEnv, type LogOptions } from '../log-level.js';
|
|
13
13
|
import { withDataServer } from '../spawn-data-server.js';
|
|
14
14
|
|
|
15
15
|
/**
|
|
@@ -22,12 +22,10 @@ import { withDataServer } from '../spawn-data-server.js';
|
|
|
22
22
|
* Test-only `__proxyForTest` bypasses the spawn for unit tests; the
|
|
23
23
|
* production CLI never passes it.
|
|
24
24
|
*/
|
|
25
|
-
export interface QueryCommandOptions {
|
|
25
|
+
export interface QueryCommandOptions extends LogOptions {
|
|
26
26
|
readonly serverCommand: string;
|
|
27
27
|
readonly serverArgs?: readonly string[];
|
|
28
28
|
readonly cwd?: string;
|
|
29
|
-
/** Log threshold for the spawned server, set on its `HYDRANIUM_LOG_LEVEL` env. */
|
|
30
|
-
readonly logLevel?: LogThreshold;
|
|
31
29
|
readonly uri: string;
|
|
32
30
|
readonly write?: (line: string) => void;
|
|
33
31
|
readonly __proxyForTest?: DataServerProtocol<TransferElement>;
|
|
@@ -48,7 +46,7 @@ export async function runQuery(options: QueryCommandOptions): Promise<void> {
|
|
|
48
46
|
command: options.serverCommand,
|
|
49
47
|
args: options.serverArgs,
|
|
50
48
|
cwd: options.cwd,
|
|
51
|
-
env:
|
|
49
|
+
env: logEnv(options)
|
|
52
50
|
},
|
|
53
51
|
async server => {
|
|
54
52
|
const doc = await server.getModelDocument({ uri: options.uri, includeDiagnostics: true });
|
|
@@ -9,34 +9,36 @@
|
|
|
9
9
|
|
|
10
10
|
import {
|
|
11
11
|
exitWithUsage,
|
|
12
|
+
HARNESS_VALUE_FLAGS,
|
|
12
13
|
helpRequested,
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
importHelpLines,
|
|
15
|
+
LOG_VALUE_FLAGS,
|
|
16
|
+
logHelpLines,
|
|
17
|
+
logOptions,
|
|
16
18
|
parseHarnessArgs,
|
|
17
19
|
printHelp,
|
|
18
|
-
SERVICES_FLAG,
|
|
19
20
|
type UsageError
|
|
20
21
|
} from './harness-args.js';
|
|
21
22
|
import { OUT_FILE_FLAG } from './headless-harness.js';
|
|
22
23
|
import { runReflect, type ReflectCommandOptions } from './reflect.js';
|
|
23
24
|
|
|
24
|
-
const VALUE_FLAGS = [OUT_FILE_FLAG,
|
|
25
|
+
const VALUE_FLAGS = [OUT_FILE_FLAG, ...LOG_VALUE_FLAGS] as const;
|
|
25
26
|
const BOOL_FLAGS = ['--json'] as const;
|
|
26
27
|
|
|
27
28
|
/**
|
|
28
29
|
* Every flag `reflect` accepts, derived from the sets the parser is handed so
|
|
29
|
-
* the list cannot claim a flag the parser would reject.
|
|
30
|
-
* by the shared harness parser itself,
|
|
30
|
+
* the list cannot claim a flag the parser would reject.
|
|
31
|
+
* {@link HARNESS_VALUE_FLAGS} are consumed by the shared harness parser itself,
|
|
32
|
+
* so they are in neither set.
|
|
31
33
|
*/
|
|
32
|
-
export const REFLECT_FLAGS: readonly string[] = [
|
|
34
|
+
export const REFLECT_FLAGS: readonly string[] = [...HARNESS_VALUE_FLAGS, ...VALUE_FLAGS, ...BOOL_FLAGS];
|
|
33
35
|
|
|
34
36
|
/** The subset that takes a value, so `--help` in a value position reads as data. */
|
|
35
|
-
export const REFLECT_VALUE_FLAGS: readonly string[] = [
|
|
37
|
+
export const REFLECT_VALUE_FLAGS: readonly string[] = [...HARNESS_VALUE_FLAGS, ...VALUE_FLAGS];
|
|
36
38
|
|
|
37
39
|
/** The `--help` text, as data, held to {@link REFLECT_FLAGS} by a test. */
|
|
38
40
|
export const REFLECT_HELP: readonly string[] = [
|
|
39
|
-
'Usage: hydranium-cli reflect --services <module> [--json] [--out-file <file>] [--log-level <lvl>]',
|
|
41
|
+
'Usage: hydranium-cli reflect --services <module> [--import <specifier>]... [--json] [--out-file <file>] [--log-level <lvl>] [--log-file <file>] [--log-file-level <lvl>]',
|
|
40
42
|
'',
|
|
41
43
|
"Dump a head's grammar/AST reflection — the type hierarchy, each language's",
|
|
42
44
|
'terminals and entry rule, and every cross-reference target. Read-only: no',
|
|
@@ -46,23 +48,25 @@ export const REFLECT_HELP: readonly string[] = [
|
|
|
46
48
|
'',
|
|
47
49
|
'Options:',
|
|
48
50
|
' --services <module> ESM module exporting `createServices(): { shared }` (required).',
|
|
51
|
+
...importHelpLines(22),
|
|
49
52
|
' --json Emit the raw JSON reflection instead of the Markdown report.',
|
|
50
53
|
' --out-file <file> Write the report to this file instead of stdout. Written',
|
|
51
54
|
' only once the report exists, unlike a shell redirection,',
|
|
52
55
|
' which truncates the file before the head is even booted.',
|
|
53
|
-
|
|
56
|
+
...logHelpLines(22)
|
|
54
57
|
];
|
|
55
58
|
|
|
56
59
|
export function parseReflectArgs(args: string[], onError: UsageError = exitWithUsage): ReflectCommandOptions {
|
|
57
|
-
const { servicesModule, options } = parseHarnessArgs(args, 'reflect', VALUE_FLAGS, BOOL_FLAGS, {
|
|
60
|
+
const { servicesModule, imports, options } = parseHarnessArgs(args, 'reflect', VALUE_FLAGS, BOOL_FLAGS, {
|
|
58
61
|
requireWorkspace: false,
|
|
59
62
|
onError
|
|
60
63
|
});
|
|
61
64
|
return {
|
|
62
65
|
servicesModule,
|
|
66
|
+
imports,
|
|
63
67
|
json: options['--json'] === 'true',
|
|
64
68
|
outFile: options[OUT_FILE_FLAG],
|
|
65
|
-
|
|
69
|
+
...logOptions(options)
|
|
66
70
|
};
|
|
67
71
|
}
|
|
68
72
|
|
package/src/commands/reflect.ts
CHANGED
|
@@ -47,5 +47,5 @@ export function buildReflectDriverArgs(options: ReflectCommandOptions): string[]
|
|
|
47
47
|
* the binary language-agnostic.
|
|
48
48
|
*/
|
|
49
49
|
export function runReflect(options: ReflectCommandOptions): Promise<void> {
|
|
50
|
-
return runDriverChild([
|
|
50
|
+
return runDriverChild([DRIVER, ...buildReflectDriverArgs(options)], options);
|
|
51
51
|
}
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
assertRequired,
|
|
12
12
|
exitWithUsage,
|
|
13
13
|
helpRequested,
|
|
14
|
+
logHelpLines,
|
|
14
15
|
parseFlagOptions,
|
|
15
16
|
parseServerSpawnOptions,
|
|
16
17
|
printHelp,
|
|
@@ -36,7 +37,7 @@ export const SAVE_VALUE_FLAGS: readonly string[] = SAVE_FLAGS;
|
|
|
36
37
|
|
|
37
38
|
/** The `--help` text, as data, held to {@link SAVE_FLAGS} by a test. */
|
|
38
39
|
export const SAVE_HELP: readonly string[] = [
|
|
39
|
-
'Usage: hydranium-cli save --server "<cmd>..." --uri <uri> --content <text|@file> [--client-id <id>] [--cwd <dir>] [--log-level <level>]',
|
|
40
|
+
'Usage: hydranium-cli save --server "<cmd>..." --uri <uri> --content <text|@file> [--client-id <id>] [--cwd <dir>] [--log-level <lvl>] [--log-file <file>] [--log-file-level <lvl>]',
|
|
40
41
|
'',
|
|
41
42
|
'Update the document at `<uri>` with `<content>` and persist via saveModelDocument.',
|
|
42
43
|
'Output is the post-save envelope as a single JSON line.',
|
|
@@ -48,17 +49,19 @@ export const SAVE_HELP: readonly string[] = [
|
|
|
48
49
|
' (escape with `\\@` for literal `@`-leading content).',
|
|
49
50
|
' --client-id <id> clientId for authorship attribution. Default: hydranium-cli.',
|
|
50
51
|
' --cwd <dir> Working directory for the spawned child. Default: cwd.',
|
|
51
|
-
'
|
|
52
|
+
...logHelpLines(22, 'the spawned server')
|
|
52
53
|
];
|
|
53
54
|
|
|
54
55
|
export function parseSaveArgs(args: string[], onError: UsageError = exitWithUsage): SaveCommandOptions {
|
|
55
|
-
const { serverCommand, serverArgs, cwd, logLevel, extra } = parseServerSpawnOptions(args, 'save', onError);
|
|
56
|
+
const { serverCommand, serverArgs, cwd, logLevel, logFile, logFileLevel, extra } = parseServerSpawnOptions(args, 'save', onError);
|
|
56
57
|
const { uri, content, clientId } = parseFlagOptions(extra, 'save', OWN_FLAGS, onError);
|
|
57
58
|
return {
|
|
58
59
|
serverCommand,
|
|
59
60
|
serverArgs,
|
|
60
61
|
cwd,
|
|
61
62
|
logLevel,
|
|
63
|
+
logFile,
|
|
64
|
+
logFileLevel,
|
|
62
65
|
uri: assertRequired(uri, '--uri', 'save', onError),
|
|
63
66
|
content: assertRequired(content, '--content', 'save', onError),
|
|
64
67
|
clientId
|