@hydranium/cli 1.0.0-next.10
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/LICENSE +21 -0
- package/README.md +240 -0
- package/heap-analysis/analyze-heap.mjs +798 -0
- package/heap-analysis/heap/core/aggregate.mjs +152 -0
- package/heap-analysis/heap/core/bucket-label.mjs +23 -0
- package/heap-analysis/heap/core/cutpoints.mjs +51 -0
- package/heap-analysis/heap/core/diff.mjs +56 -0
- package/heap-analysis/heap/core/format.mjs +47 -0
- package/heap-analysis/heap/core/holders.mjs +80 -0
- package/heap-analysis/heap/core/load.mjs +46 -0
- package/heap-analysis/heap/core/report.mjs +68 -0
- package/heap-analysis/heap/core/strings.mjs +80 -0
- package/heap-analysis/heap/langium/concepts.mjs +230 -0
- package/heap-analysis/heap/langium/glsp.classifier.mjs +80 -0
- package/heap-analysis/heap/langium/langium.classifier.mjs +203 -0
- package/heap-analysis/heap/renderer/renderer.mjs +122 -0
- package/lib/cli-version.d.ts +21 -0
- package/lib/cli-version.d.ts.map +1 -0
- package/lib/cli-version.js +30 -0
- package/lib/cli-version.js.map +1 -0
- package/lib/cli.d.ts +11 -0
- package/lib/cli.d.ts.map +1 -0
- package/lib/cli.js +135 -0
- package/lib/cli.js.map +1 -0
- package/lib/commands/analyze-heap-args.d.ts +46 -0
- package/lib/commands/analyze-heap-args.d.ts.map +1 -0
- package/lib/commands/analyze-heap-args.js +174 -0
- package/lib/commands/analyze-heap-args.js.map +1 -0
- package/lib/commands/analyze-heap.d.ts +37 -0
- package/lib/commands/analyze-heap.d.ts.map +1 -0
- package/lib/commands/analyze-heap.js +63 -0
- package/lib/commands/analyze-heap.js.map +1 -0
- package/lib/commands/ast-ground-truth-args.d.ts +23 -0
- package/lib/commands/ast-ground-truth-args.d.ts.map +1 -0
- package/lib/commands/ast-ground-truth-args.js +47 -0
- package/lib/commands/ast-ground-truth-args.js.map +1 -0
- package/lib/commands/ast-ground-truth-driver.d.ts +10 -0
- package/lib/commands/ast-ground-truth-driver.d.ts.map +1 -0
- package/lib/commands/ast-ground-truth-driver.js +72 -0
- package/lib/commands/ast-ground-truth-driver.js.map +1 -0
- package/lib/commands/ast-ground-truth.d.ts +31 -0
- package/lib/commands/ast-ground-truth.d.ts.map +1 -0
- package/lib/commands/ast-ground-truth.js +36 -0
- package/lib/commands/ast-ground-truth.js.map +1 -0
- package/lib/commands/generate-transfer-model-args.d.ts +38 -0
- package/lib/commands/generate-transfer-model-args.d.ts.map +1 -0
- package/lib/commands/generate-transfer-model-args.js +183 -0
- package/lib/commands/generate-transfer-model-args.js.map +1 -0
- package/lib/commands/generate-transfer-model-config.d.ts +32 -0
- package/lib/commands/generate-transfer-model-config.d.ts.map +1 -0
- package/lib/commands/generate-transfer-model-config.js +122 -0
- package/lib/commands/generate-transfer-model-config.js.map +1 -0
- package/lib/commands/generate-transfer-model.d.ts +110 -0
- package/lib/commands/generate-transfer-model.d.ts.map +1 -0
- package/lib/commands/generate-transfer-model.js +587 -0
- package/lib/commands/generate-transfer-model.js.map +1 -0
- package/lib/commands/harness-args.d.ts +198 -0
- package/lib/commands/harness-args.d.ts.map +1 -0
- package/lib/commands/harness-args.js +339 -0
- package/lib/commands/harness-args.js.map +1 -0
- package/lib/commands/headless-harness.d.ts +97 -0
- package/lib/commands/headless-harness.d.ts.map +1 -0
- package/lib/commands/headless-harness.js +121 -0
- package/lib/commands/headless-harness.js.map +1 -0
- package/lib/commands/init-args.d.ts +81 -0
- package/lib/commands/init-args.d.ts.map +1 -0
- package/lib/commands/init-args.js +250 -0
- package/lib/commands/init-args.js.map +1 -0
- package/lib/commands/init-prompt.d.ts +66 -0
- package/lib/commands/init-prompt.d.ts.map +1 -0
- package/lib/commands/init-prompt.js +71 -0
- package/lib/commands/init-prompt.js.map +1 -0
- package/lib/commands/init-templates.d.ts +42 -0
- package/lib/commands/init-templates.d.ts.map +1 -0
- package/lib/commands/init-templates.js +1902 -0
- package/lib/commands/init-templates.js.map +1 -0
- package/lib/commands/init-wizard.d.ts +65 -0
- package/lib/commands/init-wizard.d.ts.map +1 -0
- package/lib/commands/init-wizard.js +302 -0
- package/lib/commands/init-wizard.js.map +1 -0
- package/lib/commands/init-workspace.d.ts +168 -0
- package/lib/commands/init-workspace.d.ts.map +1 -0
- package/lib/commands/init-workspace.js +372 -0
- package/lib/commands/init-workspace.js.map +1 -0
- package/lib/commands/init.d.ts +273 -0
- package/lib/commands/init.d.ts.map +1 -0
- package/lib/commands/init.js +303 -0
- package/lib/commands/init.js.map +1 -0
- package/lib/commands/lint-grammar-args.d.ts +23 -0
- package/lib/commands/lint-grammar-args.d.ts.map +1 -0
- package/lib/commands/lint-grammar-args.js +63 -0
- package/lib/commands/lint-grammar-args.js.map +1 -0
- package/lib/commands/lint-grammar-driver.d.ts +10 -0
- package/lib/commands/lint-grammar-driver.d.ts.map +1 -0
- package/lib/commands/lint-grammar-driver.js +72 -0
- package/lib/commands/lint-grammar-driver.js.map +1 -0
- package/lib/commands/lint-grammar-report.d.ts +24 -0
- package/lib/commands/lint-grammar-report.d.ts.map +1 -0
- package/lib/commands/lint-grammar-report.js +65 -0
- package/lib/commands/lint-grammar-report.js.map +1 -0
- package/lib/commands/lint-grammar.d.ts +33 -0
- package/lib/commands/lint-grammar.d.ts.map +1 -0
- package/lib/commands/lint-grammar.js +42 -0
- package/lib/commands/lint-grammar.js.map +1 -0
- package/lib/commands/measure-memory-args.d.ts +23 -0
- package/lib/commands/measure-memory-args.d.ts.map +1 -0
- package/lib/commands/measure-memory-args.js +106 -0
- package/lib/commands/measure-memory-args.js.map +1 -0
- package/lib/commands/measure-memory-driver.d.ts +10 -0
- package/lib/commands/measure-memory-driver.d.ts.map +1 -0
- package/lib/commands/measure-memory-driver.js +110 -0
- package/lib/commands/measure-memory-driver.js.map +1 -0
- package/lib/commands/measure-memory.d.ts +68 -0
- package/lib/commands/measure-memory.d.ts.map +1 -0
- package/lib/commands/measure-memory.js +100 -0
- package/lib/commands/measure-memory.js.map +1 -0
- package/lib/commands/model-docs-args.d.ts +23 -0
- package/lib/commands/model-docs-args.d.ts.map +1 -0
- package/lib/commands/model-docs-args.js +53 -0
- package/lib/commands/model-docs-args.js.map +1 -0
- package/lib/commands/model-docs-driver.d.ts +10 -0
- package/lib/commands/model-docs-driver.d.ts.map +1 -0
- package/lib/commands/model-docs-driver.js +61 -0
- package/lib/commands/model-docs-driver.js.map +1 -0
- package/lib/commands/model-docs-report.d.ts +18 -0
- package/lib/commands/model-docs-report.d.ts.map +1 -0
- package/lib/commands/model-docs-report.js +123 -0
- package/lib/commands/model-docs-report.js.map +1 -0
- package/lib/commands/model-docs.d.ts +30 -0
- package/lib/commands/model-docs.d.ts.map +1 -0
- package/lib/commands/model-docs.js +37 -0
- package/lib/commands/model-docs.js.map +1 -0
- package/lib/commands/projects-args.d.ts +25 -0
- package/lib/commands/projects-args.d.ts.map +1 -0
- package/lib/commands/projects-args.js +49 -0
- package/lib/commands/projects-args.js.map +1 -0
- package/lib/commands/projects.d.ts +45 -0
- package/lib/commands/projects.d.ts.map +1 -0
- package/lib/commands/projects.js +39 -0
- package/lib/commands/projects.js.map +1 -0
- package/lib/commands/query-args.d.ts +25 -0
- package/lib/commands/query-args.d.ts.map +1 -0
- package/lib/commands/query-args.js +46 -0
- package/lib/commands/query-args.js.map +1 -0
- package/lib/commands/query.d.ts +32 -0
- package/lib/commands/query.d.ts.map +1 -0
- package/lib/commands/query.js +29 -0
- package/lib/commands/query.js.map +1 -0
- package/lib/commands/reflect-args.d.ts +23 -0
- package/lib/commands/reflect-args.d.ts.map +1 -0
- package/lib/commands/reflect-args.js +59 -0
- package/lib/commands/reflect-args.js.map +1 -0
- package/lib/commands/reflect-driver.d.ts +10 -0
- package/lib/commands/reflect-driver.d.ts.map +1 -0
- package/lib/commands/reflect-driver.js +66 -0
- package/lib/commands/reflect-driver.js.map +1 -0
- package/lib/commands/reflect-report.d.ts +20 -0
- package/lib/commands/reflect-report.d.ts.map +1 -0
- package/lib/commands/reflect-report.js +127 -0
- package/lib/commands/reflect-report.js.map +1 -0
- package/lib/commands/reflect.d.ts +30 -0
- package/lib/commands/reflect.d.ts.map +1 -0
- package/lib/commands/reflect.js +38 -0
- package/lib/commands/reflect.js.map +1 -0
- package/lib/commands/save-args.d.ts +26 -0
- package/lib/commands/save-args.d.ts.map +1 -0
- package/lib/commands/save-args.js +59 -0
- package/lib/commands/save-args.js.map +1 -0
- package/lib/commands/save.d.ts +38 -0
- package/lib/commands/save.d.ts.map +1 -0
- package/lib/commands/save.js +48 -0
- package/lib/commands/save.js.map +1 -0
- package/lib/commands/validate-args.d.ts +23 -0
- package/lib/commands/validate-args.d.ts.map +1 -0
- package/lib/commands/validate-args.js +60 -0
- package/lib/commands/validate-args.js.map +1 -0
- package/lib/commands/validate-driver.d.ts +10 -0
- package/lib/commands/validate-driver.d.ts.map +1 -0
- package/lib/commands/validate-driver.js +72 -0
- package/lib/commands/validate-driver.js.map +1 -0
- package/lib/commands/validate-report.d.ts +30 -0
- package/lib/commands/validate-report.d.ts.map +1 -0
- package/lib/commands/validate-report.js +87 -0
- package/lib/commands/validate-report.js.map +1 -0
- package/lib/commands/validate.d.ts +34 -0
- package/lib/commands/validate.d.ts.map +1 -0
- package/lib/commands/validate.js +41 -0
- package/lib/commands/validate.js.map +1 -0
- package/lib/commands/watch-args.d.ts +26 -0
- package/lib/commands/watch-args.d.ts.map +1 -0
- package/lib/commands/watch-args.js +59 -0
- package/lib/commands/watch-args.js.map +1 -0
- package/lib/commands/watch.d.ts +75 -0
- package/lib/commands/watch.d.ts.map +1 -0
- package/lib/commands/watch.js +112 -0
- package/lib/commands/watch.js.map +1 -0
- package/lib/index.d.ts +16 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +16 -0
- package/lib/index.js.map +1 -0
- package/lib/log-level.d.ts +39 -0
- package/lib/log-level.d.ts.map +1 -0
- package/lib/log-level.js +47 -0
- package/lib/log-level.js.map +1 -0
- package/lib/package-name.d.ts +33 -0
- package/lib/package-name.d.ts.map +1 -0
- package/lib/package-name.js +37 -0
- package/lib/package-name.js.map +1 -0
- package/lib/spawn-data-server.d.ts +102 -0
- package/lib/spawn-data-server.d.ts.map +1 -0
- package/lib/spawn-data-server.js +154 -0
- package/lib/spawn-data-server.js.map +1 -0
- package/lib/testing/echo-server.d.ts +11 -0
- package/lib/testing/echo-server.d.ts.map +1 -0
- package/lib/testing/echo-server.js +79 -0
- package/lib/testing/echo-server.js.map +1 -0
- package/package.json +105 -0
- package/src/cli-version.ts +32 -0
- package/src/cli.ts +139 -0
- package/src/commands/analyze-heap-args.ts +184 -0
- package/src/commands/analyze-heap.ts +76 -0
- package/src/commands/ast-ground-truth-args.ts +63 -0
- package/src/commands/ast-ground-truth-driver.ts +81 -0
- package/src/commands/ast-ground-truth.ts +49 -0
- package/src/commands/generate-transfer-model-args.ts +203 -0
- package/src/commands/generate-transfer-model-config.ts +128 -0
- package/src/commands/generate-transfer-model.ts +716 -0
- package/src/commands/harness-args.ts +429 -0
- package/src/commands/headless-harness.ts +165 -0
- package/src/commands/init-args.ts +273 -0
- package/src/commands/init-prompt.ts +149 -0
- package/src/commands/init-templates.ts +2037 -0
- package/src/commands/init-wizard.ts +378 -0
- package/src/commands/init-workspace.ts +442 -0
- package/src/commands/init.ts +554 -0
- package/src/commands/lint-grammar-args.ts +79 -0
- package/src/commands/lint-grammar-driver.ts +83 -0
- package/src/commands/lint-grammar-report.ts +74 -0
- package/src/commands/lint-grammar.ts +57 -0
- package/src/commands/measure-memory-args.ts +123 -0
- package/src/commands/measure-memory-driver.ts +128 -0
- package/src/commands/measure-memory.ts +143 -0
- package/src/commands/model-docs-args.ts +69 -0
- package/src/commands/model-docs-driver.ts +68 -0
- package/src/commands/model-docs-report.ts +133 -0
- package/src/commands/model-docs.ts +48 -0
- package/src/commands/projects-args.ts +62 -0
- package/src/commands/projects.ts +76 -0
- package/src/commands/query-args.ts +61 -0
- package/src/commands/query.ts +58 -0
- package/src/commands/reflect-args.ts +75 -0
- package/src/commands/reflect-driver.ts +76 -0
- package/src/commands/reflect-report.ts +138 -0
- package/src/commands/reflect.ts +51 -0
- package/src/commands/save-args.ts +74 -0
- package/src/commands/save.ts +84 -0
- package/src/commands/validate-args.ts +76 -0
- package/src/commands/validate-driver.ts +84 -0
- package/src/commands/validate-report.ts +95 -0
- package/src/commands/validate.ts +58 -0
- package/src/commands/watch-args.ts +74 -0
- package/src/commands/watch.ts +185 -0
- package/src/index.ts +16 -0
- package/src/log-level.ts +49 -0
- package/src/package-name.ts +39 -0
- package/src/spawn-data-server.ts +247 -0
- package/src/testing/echo-server.ts +93 -0
|
@@ -0,0 +1,121 @@
|
|
|
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 { spawn } from 'node:child_process';
|
|
10
|
+
import { statSync, writeFileSync } from 'node:fs';
|
|
11
|
+
import { createRequire } from 'node:module';
|
|
12
|
+
import * as path from 'node:path';
|
|
13
|
+
import { pathToFileURL } from 'node:url';
|
|
14
|
+
import { logLevelEnv } from '../log-level.js';
|
|
15
|
+
import { SERVICES_FLAG } from './harness-args.js';
|
|
16
|
+
/** The flag every report-producing subcommand names its destination file with. */
|
|
17
|
+
export const OUT_FILE_FLAG = '--out-file';
|
|
18
|
+
/**
|
|
19
|
+
* Child-side: load everything a driver needs from a head's `--services` module —
|
|
20
|
+
* its `createServices` thunk AND the `@hydranium/core/node` harness, both
|
|
21
|
+
* resolved from the HEAD's location rather than the CLI's.
|
|
22
|
+
*
|
|
23
|
+
* The module is an ESM file (typically a compiled `lib/*.js`) exporting a
|
|
24
|
+
* ZERO-ARG `createServices(): { shared }`. `hydranium-cli` is language-agnostic
|
|
25
|
+
* and cannot statically import a head's `create<Lang>Services`, so the dynamic
|
|
26
|
+
* import is the seam that keeps the binary head-neutral. Resolving the harness
|
|
27
|
+
* from the head's graph (via `createRequire` rooted at the head module) means the
|
|
28
|
+
* CLI itself needs no `@hydranium/core` dependency — the head always has it — and
|
|
29
|
+
* guarantees the harness runs against the SAME core copy as `createServices`.
|
|
30
|
+
*
|
|
31
|
+
* Throws a clear error when the path names no file, and when the export is
|
|
32
|
+
* missing or not a function.
|
|
33
|
+
*/
|
|
34
|
+
export async function loadHeadlessContext(servicesModule) {
|
|
35
|
+
const modulePath = path.resolve(servicesModule);
|
|
36
|
+
// Checked before the import, not caught after it: Node's
|
|
37
|
+
// ERR_MODULE_NOT_FOUND names neither the flag nor this file's role, and a
|
|
38
|
+
// catch could not tell a missing --services module from a missing dependency
|
|
39
|
+
// OF that module, which deserves Node's message verbatim.
|
|
40
|
+
const stats = statSync(modulePath, { throwIfNoEntry: false });
|
|
41
|
+
if (stats === undefined || !stats.isFile()) {
|
|
42
|
+
throw new Error(`${SERVICES_FLAG} must name an existing ESM file; '${servicesModule}' resolved to ${modulePath}, ` +
|
|
43
|
+
`which is not one. Pass the head's COMPILED entry, e.g. \`${SERVICES_FLAG} ./lib/services.js\` — ` +
|
|
44
|
+
'not the TypeScript source and not a package name.');
|
|
45
|
+
}
|
|
46
|
+
const moduleUrl = pathToFileURL(modulePath).href;
|
|
47
|
+
const imported = (await import(moduleUrl));
|
|
48
|
+
const createServices = imported.createServices;
|
|
49
|
+
if (typeof createServices !== 'function') {
|
|
50
|
+
throw new Error(`Services module '${servicesModule}' must export a zero-arg 'createServices(): { shared }' ` +
|
|
51
|
+
`function (found ${typeof createServices}). The head wires its own filesystem inside, ` +
|
|
52
|
+
'e.g. `export const createServices = () => createMyLangServices({ ...NodeFileSystem })`.');
|
|
53
|
+
}
|
|
54
|
+
const headRequire = createRequire(moduleUrl);
|
|
55
|
+
const coreNodePath = headRequire.resolve('@hydranium/core/node');
|
|
56
|
+
const coreNode = (await import(pathToFileURL(coreNodePath).href));
|
|
57
|
+
return { createServices: createServices, coreNode };
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Child-side: deliver a finished report — to `outFile` when one was named, else
|
|
61
|
+
* to stdout.
|
|
62
|
+
*
|
|
63
|
+
* The file is created only once the report EXISTS, which is what the flag buys
|
|
64
|
+
* over the shell redirection it replaces: `> report.md` truncates the destination
|
|
65
|
+
* before the command runs, so a head that throws while booting leaves a
|
|
66
|
+
* zero-length file that a later step reads as an empty report rather than as a
|
|
67
|
+
* failed run.
|
|
68
|
+
*/
|
|
69
|
+
export function emitReport(report, outFile) {
|
|
70
|
+
if (outFile === undefined) {
|
|
71
|
+
console.log(report);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
writeFileSync(outFile, report.endsWith('\n') ? report : `${report}\n`);
|
|
75
|
+
// Progress on stderr, so a caller that also captures stdout gets a clean
|
|
76
|
+
// stream rather than a note where the report used to be.
|
|
77
|
+
console.error(`Wrote ${outFile}`);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Parent-side: spawn `node <execArgs...>` inheriting stdio and resolve with the
|
|
81
|
+
* child's exit code. The harness subcommands need a child process anyway — the
|
|
82
|
+
* heads' services and a workspace build run in isolation, and `measure-memory`
|
|
83
|
+
* additionally needs `--expose-gc` for post-GC readings.
|
|
84
|
+
*
|
|
85
|
+
* `env` is MERGED over the parent's rather than replacing it: the child resolves
|
|
86
|
+
* the head's module graph, so dropping `PATH` / `NODE_OPTIONS` / the platform's
|
|
87
|
+
* own variables would break the import the driver exists to perform.
|
|
88
|
+
*/
|
|
89
|
+
export function spawnNodeChild(execArgs, env) {
|
|
90
|
+
return new Promise((resolve, reject) => {
|
|
91
|
+
const child = spawn(process.execPath, execArgs, {
|
|
92
|
+
stdio: 'inherit',
|
|
93
|
+
env: env === undefined ? process.env : { ...process.env, ...env }
|
|
94
|
+
});
|
|
95
|
+
child.on('error', reject);
|
|
96
|
+
child.on('close', code => resolve(code ?? 0));
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Parent-side: run a subcommand's driver child and propagate its exit code, so a
|
|
101
|
+
* shell or CI step sees the gate.
|
|
102
|
+
*
|
|
103
|
+
* **The log threshold travels in the child's ENVIRONMENT, not its argv.** The
|
|
104
|
+
* head's logger reads `HYDRANIUM_LOG_LEVEL` while `createServices` constructs it,
|
|
105
|
+
* which is inside the driver's dynamic import — a flag the driver parsed would
|
|
106
|
+
* arrive after the only moment it can be read. Setting it here rather than
|
|
107
|
+
* exporting it also leaves the CLI's own output alone, unlike an ambient
|
|
108
|
+
* `HYDRANIUM_LOG_LEVEL=…` the parent would carry too.
|
|
109
|
+
*
|
|
110
|
+
* A head that binds a logger of its own decides for itself whether the flag means
|
|
111
|
+
* anything, which is the intended seam: the CLI is language-agnostic and cannot
|
|
112
|
+
* reach past `createServices`.
|
|
113
|
+
*/
|
|
114
|
+
export async function runDriverChild(execArgs, options) {
|
|
115
|
+
const spawnChild = options.__spawnForTest ?? spawnNodeChild;
|
|
116
|
+
const code = await spawnChild(execArgs, options.logLevel === undefined ? undefined : logLevelEnv(options.logLevel));
|
|
117
|
+
if (code) {
|
|
118
|
+
process.exitCode = code;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=headless-harness.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"headless-harness.js","sourceRoot":"","sources":["../../src/commands/headless-harness.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,81 @@
|
|
|
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
|
+
/**
|
|
10
|
+
* `init`'s argv parser.
|
|
11
|
+
*
|
|
12
|
+
* Its own module rather than a function in the CLI entry point, because the
|
|
13
|
+
* entry point runs `main()` on import: a test that wants to read an argv the
|
|
14
|
+
* way the command does would otherwise have to execute the whole binary. That
|
|
15
|
+
* matters more here than for the other subcommands, since the wizard's entire
|
|
16
|
+
* contract is that its composed argv means exactly what a typed one would — a
|
|
17
|
+
* claim only a test that round-trips through THIS function can check.
|
|
18
|
+
*
|
|
19
|
+
* The parsing is hand-written rather than declared to `commander` because the
|
|
20
|
+
* grammar-scoped flags are ORDER-dependent across different option names:
|
|
21
|
+
* `--extensions` applies to the `--grammar` it follows, so
|
|
22
|
+
* `--grammar A --extensions x --grammar B` and
|
|
23
|
+
* `--grammar A --grammar B --extensions x` mean different things. A declarative
|
|
24
|
+
* option model collects `{grammar: [A, B], extensions: [x]}` for both and the
|
|
25
|
+
* association is gone.
|
|
26
|
+
*/
|
|
27
|
+
import { type UsageError } from './harness-args.js';
|
|
28
|
+
import { type InitHead } from './init.js';
|
|
29
|
+
/** One grammar as the command line collected it, before any derivation. */
|
|
30
|
+
export interface ParsedInitGrammar {
|
|
31
|
+
name: string;
|
|
32
|
+
extensions?: string[];
|
|
33
|
+
languageId?: string;
|
|
34
|
+
diagram?: boolean;
|
|
35
|
+
}
|
|
36
|
+
/** `init`'s argv, parsed but not validated — a missing `--name` is the wizard's cue, not an error. */
|
|
37
|
+
export interface ParsedInitArgs {
|
|
38
|
+
targetDir?: string;
|
|
39
|
+
name?: string;
|
|
40
|
+
force: boolean;
|
|
41
|
+
heads?: InitHead[];
|
|
42
|
+
monorepo: boolean;
|
|
43
|
+
scope?: string;
|
|
44
|
+
public: boolean;
|
|
45
|
+
grammars: ParsedInitGrammar[];
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Every flag `init` accepts, as data.
|
|
49
|
+
*
|
|
50
|
+
* The single source the parser's own switch and the `--help` text both read,
|
|
51
|
+
* with a test asserting they agree. A flag added to one and not the other is
|
|
52
|
+
* the silent drift this list exists to make impossible.
|
|
53
|
+
*/
|
|
54
|
+
export declare const INIT_FLAGS: readonly string[];
|
|
55
|
+
/**
|
|
56
|
+
* The subset that takes a value, so `--help` in a value position reads as data.
|
|
57
|
+
* The rest are presence-only.
|
|
58
|
+
*/
|
|
59
|
+
export declare const INIT_VALUE_FLAGS: readonly string[];
|
|
60
|
+
/**
|
|
61
|
+
* Parse `init`'s flags without deciding whether the result is complete.
|
|
62
|
+
*
|
|
63
|
+
* Shared by the wizard and the flag path so both read an argv with ONE parser:
|
|
64
|
+
* the wizard's contract is that its composed argv means exactly what a typed
|
|
65
|
+
* one would, which only holds if the same code reads both.
|
|
66
|
+
*
|
|
67
|
+
* `onError` receives a usage message. It defaults to reporting and exiting,
|
|
68
|
+
* which is what a command line wants; a caller that would rather handle the
|
|
69
|
+
* problem passes its own and the function throws instead of ending the process.
|
|
70
|
+
*/
|
|
71
|
+
export declare function parseInitArgs(args: string[], onError?: UsageError): ParsedInitArgs;
|
|
72
|
+
/**
|
|
73
|
+
* The `init --help` text, as data.
|
|
74
|
+
*
|
|
75
|
+
* Exported so a test can assert it documents every flag {@link INIT_FLAGS}
|
|
76
|
+
* names. Help that drifts from the parser is worse than none: it is read as
|
|
77
|
+
* authoritative, and a flag missing from it is a capability nobody finds.
|
|
78
|
+
*/
|
|
79
|
+
export declare const INIT_HELP: readonly string[];
|
|
80
|
+
export declare function runInitCommand(args: string[]): Promise<void>;
|
|
81
|
+
//# sourceMappingURL=init-args.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init-args.d.ts","sourceRoot":"","sources":["../../src/commands/init-args.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAA2D,KAAK,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC7G,OAAO,EAA0B,KAAK,QAAQ,EAAE,MAAM,WAAW,CAAC;AAKlE,2EAA2E;AAC3E,MAAM,WAAW,iBAAiB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,sGAAsG;AACtG,MAAM,WAAW,cAAc;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,iBAAiB,EAAE,CAAC;CAChC;AAED;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,EAAE,SAAS,MAAM,EAWvC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,SAAS,MAAM,EAAmF,CAAC;AAElI;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,GAAE,UAA0B,GAAG,cAAc,CAiFjG;AAED;;;;;;GAMG;AACH,eAAO,MAAM,SAAS,EAAE,SAAS,MAAM,EA6DtC,CAAC;AAEF,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA4BlE"}
|
|
@@ -0,0 +1,250 @@
|
|
|
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
|
+
/**
|
|
10
|
+
* `init`'s argv parser.
|
|
11
|
+
*
|
|
12
|
+
* Its own module rather than a function in the CLI entry point, because the
|
|
13
|
+
* entry point runs `main()` on import: a test that wants to read an argv the
|
|
14
|
+
* way the command does would otherwise have to execute the whole binary. That
|
|
15
|
+
* matters more here than for the other subcommands, since the wizard's entire
|
|
16
|
+
* contract is that its composed argv means exactly what a typed one would — a
|
|
17
|
+
* claim only a test that round-trips through THIS function can check.
|
|
18
|
+
*
|
|
19
|
+
* The parsing is hand-written rather than declared to `commander` because the
|
|
20
|
+
* grammar-scoped flags are ORDER-dependent across different option names:
|
|
21
|
+
* `--extensions` applies to the `--grammar` it follows, so
|
|
22
|
+
* `--grammar A --extensions x --grammar B` and
|
|
23
|
+
* `--grammar A --grammar B --extensions x` mean different things. A declarative
|
|
24
|
+
* option model collects `{grammar: [A, B], extensions: [x]}` for both and the
|
|
25
|
+
* association is gone.
|
|
26
|
+
*/
|
|
27
|
+
import { assertRequired, exitWithUsage, helpRequested, printHelp } from './harness-args.js';
|
|
28
|
+
import { isNonEmptyDir, runInit } from './init.js';
|
|
29
|
+
import { createClackPrompt } from './init-prompt.js';
|
|
30
|
+
import { runInitWizard } from './init-wizard.js';
|
|
31
|
+
import { createNodeWorkspaceProbe, detectWorkspace } from './init-workspace.js';
|
|
32
|
+
/**
|
|
33
|
+
* Every flag `init` accepts, as data.
|
|
34
|
+
*
|
|
35
|
+
* The single source the parser's own switch and the `--help` text both read,
|
|
36
|
+
* with a test asserting they agree. A flag added to one and not the other is
|
|
37
|
+
* the silent drift this list exists to make impossible.
|
|
38
|
+
*/
|
|
39
|
+
export const INIT_FLAGS = [
|
|
40
|
+
'--name',
|
|
41
|
+
'--heads',
|
|
42
|
+
'--force',
|
|
43
|
+
'--monorepo',
|
|
44
|
+
'--scope',
|
|
45
|
+
'--public',
|
|
46
|
+
'--grammar',
|
|
47
|
+
'--extensions',
|
|
48
|
+
'--language-id',
|
|
49
|
+
'--diagram'
|
|
50
|
+
];
|
|
51
|
+
/**
|
|
52
|
+
* The subset that takes a value, so `--help` in a value position reads as data.
|
|
53
|
+
* The rest are presence-only.
|
|
54
|
+
*/
|
|
55
|
+
export const INIT_VALUE_FLAGS = ['--name', '--heads', '--scope', '--grammar', '--extensions', '--language-id'];
|
|
56
|
+
/**
|
|
57
|
+
* Parse `init`'s flags without deciding whether the result is complete.
|
|
58
|
+
*
|
|
59
|
+
* Shared by the wizard and the flag path so both read an argv with ONE parser:
|
|
60
|
+
* the wizard's contract is that its composed argv means exactly what a typed
|
|
61
|
+
* one would, which only holds if the same code reads both.
|
|
62
|
+
*
|
|
63
|
+
* `onError` receives a usage message. It defaults to reporting and exiting,
|
|
64
|
+
* which is what a command line wants; a caller that would rather handle the
|
|
65
|
+
* problem passes its own and the function throws instead of ending the process.
|
|
66
|
+
*/
|
|
67
|
+
export function parseInitArgs(args, onError = exitWithUsage) {
|
|
68
|
+
let targetDir;
|
|
69
|
+
let name;
|
|
70
|
+
let force = false;
|
|
71
|
+
let heads;
|
|
72
|
+
let monorepo = false;
|
|
73
|
+
let scope;
|
|
74
|
+
let isPublic = false;
|
|
75
|
+
const grammars = [];
|
|
76
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
77
|
+
const flag = args[index];
|
|
78
|
+
const next = () => {
|
|
79
|
+
const value = args[index + 1];
|
|
80
|
+
if (value === undefined) {
|
|
81
|
+
onError(`Missing value for ${flag}`);
|
|
82
|
+
}
|
|
83
|
+
index += 1;
|
|
84
|
+
return value;
|
|
85
|
+
};
|
|
86
|
+
// A grammar-scoped flag modifies the grammar it follows, so with no
|
|
87
|
+
// `--grammar` yet there is nothing for it to mean. Refusing loudly beats
|
|
88
|
+
// silently attaching it to a grammar the user never named.
|
|
89
|
+
const scoped = () => {
|
|
90
|
+
const current = grammars[grammars.length - 1];
|
|
91
|
+
if (current === undefined) {
|
|
92
|
+
onError(`${flag} must follow a --grammar (hydranium-cli init --help)`);
|
|
93
|
+
}
|
|
94
|
+
return current;
|
|
95
|
+
};
|
|
96
|
+
switch (flag) {
|
|
97
|
+
case '--name':
|
|
98
|
+
name = next();
|
|
99
|
+
break;
|
|
100
|
+
case '--grammar':
|
|
101
|
+
grammars.push({ name: next() });
|
|
102
|
+
break;
|
|
103
|
+
case '--extensions': {
|
|
104
|
+
const grammar = scoped();
|
|
105
|
+
grammar.extensions = [...(grammar.extensions ?? []), ...next().split(',')];
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
case '--language-id':
|
|
109
|
+
scoped().languageId = next();
|
|
110
|
+
break;
|
|
111
|
+
case '--diagram':
|
|
112
|
+
scoped().diagram = true;
|
|
113
|
+
break;
|
|
114
|
+
case '--heads': {
|
|
115
|
+
// Validated in `resolveInitComposition`, which owns the rule that
|
|
116
|
+
// `lsp` is mandatory; the cast only gets the strings that far.
|
|
117
|
+
heads = next().split(',');
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
case '--force':
|
|
121
|
+
force = true;
|
|
122
|
+
break;
|
|
123
|
+
case '--monorepo':
|
|
124
|
+
monorepo = true;
|
|
125
|
+
break;
|
|
126
|
+
case '--scope':
|
|
127
|
+
scope = next();
|
|
128
|
+
break;
|
|
129
|
+
case '--public':
|
|
130
|
+
isPublic = true;
|
|
131
|
+
break;
|
|
132
|
+
default:
|
|
133
|
+
// A grammar takes N extensions, so the flag is plural. Naming the
|
|
134
|
+
// singular spelling beats a bare "unknown option" for what is
|
|
135
|
+
// otherwise a silent typo.
|
|
136
|
+
if (flag === '--extension') {
|
|
137
|
+
onError('Unknown option: --extension — did you mean --extensions? (hydranium-cli init --help)');
|
|
138
|
+
}
|
|
139
|
+
else if (flag.startsWith('--')) {
|
|
140
|
+
onError(`Unknown option: ${flag} (hydranium-cli init --help)`);
|
|
141
|
+
}
|
|
142
|
+
else if (targetDir === undefined) {
|
|
143
|
+
targetDir = flag;
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
onError(`Unexpected argument: ${flag} (hydranium-cli init --help)`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return { targetDir, name, force, heads, monorepo, scope, public: isPublic, grammars };
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* The `init --help` text, as data.
|
|
154
|
+
*
|
|
155
|
+
* Exported so a test can assert it documents every flag {@link INIT_FLAGS}
|
|
156
|
+
* names. Help that drifts from the parser is worse than none: it is read as
|
|
157
|
+
* authoritative, and a flag missing from it is a capability nobody finds.
|
|
158
|
+
*/
|
|
159
|
+
export const INIT_HELP = [
|
|
160
|
+
'Usage: hydranium-cli init <target-dir> --name <Name> [--heads <list>] [--force]',
|
|
161
|
+
' [--monorepo] [--scope <@scope>] [--public]',
|
|
162
|
+
' ( --grammar <Name> [--extensions <list>]',
|
|
163
|
+
' [--language-id <id>] [--diagram] )...',
|
|
164
|
+
'',
|
|
165
|
+
'Scaffold a new Hydranium language project end-to-end: a starter grammar per',
|
|
166
|
+
'--grammar, the `create<Name>Services` DI wiring, an LSP + data-server launch,',
|
|
167
|
+
'langium-config, package.json, and build scripts. Does NOT run `npm install` or',
|
|
168
|
+
'`langium generate` — those are printed as next steps. Refuses a non-empty',
|
|
169
|
+
'directory without --force.',
|
|
170
|
+
'',
|
|
171
|
+
'Run it with no --name on a terminal to be prompted instead. The wizard echoes',
|
|
172
|
+
'the command it composed before running it, so every answer is reproducible as',
|
|
173
|
+
'flags. Without a terminal a missing --name stays an error, so CI never hangs.',
|
|
174
|
+
'',
|
|
175
|
+
'Project options (position-free):',
|
|
176
|
+
' <target-dir> Directory to scaffold into (required).',
|
|
177
|
+
' --name <Name> PascalCase PROJECT name; drives the services and the',
|
|
178
|
+
' Langium projectName, i.e. the shared generated symbols',
|
|
179
|
+
' (<Name>AstReflection, <Name>GeneratedSharedModule) (required).',
|
|
180
|
+
' --heads <list> Comma-separated protocol heads: lsp, data, glsp.',
|
|
181
|
+
' `lsp` is mandatory — it owns the workspace, the build',
|
|
182
|
+
' pipeline and the shared tier the others read through.',
|
|
183
|
+
' The emitted dependencies, main.ts and module bindings',
|
|
184
|
+
' all follow this set. Default: lsp,data.',
|
|
185
|
+
' --force Scaffold into a non-empty directory anyway.',
|
|
186
|
+
' --monorepo Scaffold a member of the surrounding npm workspace:',
|
|
187
|
+
' tsconfig extends the root config that actually carries',
|
|
188
|
+
' compilerOptions, .gitignore is left to the root, and the',
|
|
189
|
+
' scripts address the package by --prefix. Errors when no',
|
|
190
|
+
' ancestor declares `workspaces`. Never writes outside the',
|
|
191
|
+
' target — the root `workspaces` entry is printed, not added.',
|
|
192
|
+
' --scope <@scope> npm scope for the package name, e.g. @acme. Not inferred:',
|
|
193
|
+
' a root manifest is usually named for the repo, not the',
|
|
194
|
+
' scope. The wizard offers the siblings’ scope as a default.',
|
|
195
|
+
' --public Omit "private": true, so the package can be published.',
|
|
196
|
+
' The scaffold emits it by default, because the manifest',
|
|
197
|
+
' it also emits declares license "UNLICENSED": a package',
|
|
198
|
+
' granting no rights on a public registry contradicts',
|
|
199
|
+
' itself. Pass this once the project has picked a licence.',
|
|
200
|
+
'',
|
|
201
|
+
'Grammar options — each applies to the PRECEDING --grammar:',
|
|
202
|
+
' --grammar <Name> PascalCase GRAMMAR name; drives the `grammar X` declaration',
|
|
203
|
+
' and the per-language generated symbols',
|
|
204
|
+
' (<Grammar>GeneratedModule, <Grammar>LanguageMetaData).',
|
|
205
|
+
' Repeatable — pass it once per grammar. Default: --name.',
|
|
206
|
+
' --extensions <list> Comma-separated file extensions for that grammar, leading',
|
|
207
|
+
' dot optional. Repeatable; accumulates. Default: the kebab',
|
|
208
|
+
' grammar name.',
|
|
209
|
+
' --language-id <id> Override that grammar’s derived routing key',
|
|
210
|
+
' (default: <project-id>-<grammar-id>).',
|
|
211
|
+
' --diagram Scaffold a GLSP diagram for that grammar. Requires',
|
|
212
|
+
' `glsp` in --heads. Derived when there is exactly one',
|
|
213
|
+
' grammar; required when there are several, because a',
|
|
214
|
+
' diagram type binds exactly one grammar.',
|
|
215
|
+
'',
|
|
216
|
+
'Example — three grammars, one with a differing extension, three heads:',
|
|
217
|
+
' hydranium-cli init ./order-flow --name OrderFlow --heads lsp,data,glsp \\',
|
|
218
|
+
' --grammar Domain --grammar Process --diagram \\',
|
|
219
|
+
' --grammar Layout --extensions diagram'
|
|
220
|
+
];
|
|
221
|
+
export async function runInitCommand(args) {
|
|
222
|
+
if (helpRequested(args, INIT_VALUE_FLAGS)) {
|
|
223
|
+
printHelp(INIT_HELP);
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
const parsed = parseInitArgs(args);
|
|
227
|
+
// The wizard's entry point: no `--name` on an interactive terminal. Safe
|
|
228
|
+
// because that combination has no non-wizard meaning, and gated on a TTY
|
|
229
|
+
// because a non-interactive caller must keep failing fast — a prompt in CI
|
|
230
|
+
// hangs the job instead of reporting the missing flag.
|
|
231
|
+
if (parsed.name === undefined && process.stdin.isTTY && process.stdout.isTTY) {
|
|
232
|
+
const prompt = await createClackPrompt();
|
|
233
|
+
const argv = await runInitWizard(prompt, targetDir => detectWorkspace(targetDir, createNodeWorkspaceProbe()), {
|
|
234
|
+
targetDir: parsed.targetDir,
|
|
235
|
+
isOccupied: isNonEmptyDir
|
|
236
|
+
});
|
|
237
|
+
return runInitCommand(argv);
|
|
238
|
+
}
|
|
239
|
+
runInit({
|
|
240
|
+
targetDir: assertRequired(parsed.targetDir, '<target-dir>', 'init'),
|
|
241
|
+
name: assertRequired(parsed.name, '--name', 'init'),
|
|
242
|
+
grammars: parsed.grammars,
|
|
243
|
+
heads: parsed.heads,
|
|
244
|
+
force: parsed.force,
|
|
245
|
+
monorepo: parsed.monorepo,
|
|
246
|
+
scope: parsed.scope,
|
|
247
|
+
public: parsed.public
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
//# sourceMappingURL=init-args.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init-args.js","sourceRoot":"","sources":["../../src/commands/init-args.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,66 @@
|
|
|
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 { InitHead } from './init.js';
|
|
10
|
+
/** One choice in a {@link PromptPort.select} or {@link PromptPort.multiselect} list. */
|
|
11
|
+
export interface PromptChoice<Value extends string> {
|
|
12
|
+
readonly value: Value;
|
|
13
|
+
readonly label: string;
|
|
14
|
+
/** Dimmed trailing text, for the rule or consequence behind the choice. */
|
|
15
|
+
readonly hint?: string;
|
|
16
|
+
}
|
|
17
|
+
/** A free-text question. `validate` returns a message to re-ask with, or `undefined` to accept. */
|
|
18
|
+
export interface PromptTextOptions {
|
|
19
|
+
readonly message: string;
|
|
20
|
+
readonly initialValue?: string;
|
|
21
|
+
readonly placeholder?: string;
|
|
22
|
+
readonly validate?: (value: string) => string | undefined;
|
|
23
|
+
}
|
|
24
|
+
/** Thrown when the user cancels — Ctrl-C, or an EOF on the input stream. */
|
|
25
|
+
export declare class InitWizardCancelled extends Error {
|
|
26
|
+
constructor();
|
|
27
|
+
}
|
|
28
|
+
/** The prompts the wizard needs, and nothing more. */
|
|
29
|
+
export interface PromptPort {
|
|
30
|
+
/** Open the session with a title. */
|
|
31
|
+
readonly intro: (title: string) => void;
|
|
32
|
+
/** Show a block of context that is not a question. */
|
|
33
|
+
readonly note: (message: string, title?: string) => void;
|
|
34
|
+
/** Ask for a line of text. */
|
|
35
|
+
readonly text: (options: PromptTextOptions) => Promise<string>;
|
|
36
|
+
/** Ask for exactly one of several choices. */
|
|
37
|
+
readonly select: <Value extends string>(options: {
|
|
38
|
+
readonly message: string;
|
|
39
|
+
readonly choices: ReadonlyArray<PromptChoice<Value>>;
|
|
40
|
+
readonly initialValue?: Value;
|
|
41
|
+
}) => Promise<Value>;
|
|
42
|
+
/** Ask for any number of several choices, including none. */
|
|
43
|
+
readonly multiselect: <Value extends string>(options: {
|
|
44
|
+
readonly message: string;
|
|
45
|
+
readonly choices: ReadonlyArray<PromptChoice<Value>>;
|
|
46
|
+
readonly initialValues?: readonly Value[];
|
|
47
|
+
}) => Promise<Value[]>;
|
|
48
|
+
/** Ask a yes/no question. */
|
|
49
|
+
readonly confirm: (options: {
|
|
50
|
+
readonly message: string;
|
|
51
|
+
readonly initialValue?: boolean;
|
|
52
|
+
}) => Promise<boolean>;
|
|
53
|
+
/** Close the session with a closing line. */
|
|
54
|
+
readonly outro: (message: string) => void;
|
|
55
|
+
}
|
|
56
|
+
/** The optional heads, as a checkbox list. `lsp` is not offered — see `askHeads`. */
|
|
57
|
+
export declare const OPTIONAL_HEAD_CHOICES: ReadonlyArray<PromptChoice<Exclude<InitHead, 'lsp'>>>;
|
|
58
|
+
/**
|
|
59
|
+
* The real prompt, backed by `@clack/prompts`.
|
|
60
|
+
*
|
|
61
|
+
* Imported dynamically so the library loads only when someone actually reaches
|
|
62
|
+
* the interactive path: every non-interactive `init`, and all twelve other
|
|
63
|
+
* subcommands, keep their previous startup cost.
|
|
64
|
+
*/
|
|
65
|
+
export declare function createClackPrompt(): Promise<PromptPort>;
|
|
66
|
+
//# sourceMappingURL=init-prompt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init-prompt.d.ts","sourceRoot":"","sources":["../../src/commands/init-prompt.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAqBlF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAE1C,wFAAwF;AACxF,MAAM,WAAW,YAAY,CAAC,KAAK,SAAS,MAAM;IAC/C,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,2EAA2E;IAC3E,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,mGAAmG;AACnG,MAAM,WAAW,iBAAiB;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;CAC5D;AAED,4EAA4E;AAC5E,qBAAa,mBAAoB,SAAQ,KAAK;;CAK7C;AAED,sDAAsD;AACtD,MAAM,WAAW,UAAU;IACxB,qCAAqC;IACrC,QAAQ,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,sDAAsD;IACtD,QAAQ,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACzD,8BAA8B;IAC9B,QAAQ,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,iBAAiB,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/D,8CAA8C;IAC9C,QAAQ,CAAC,MAAM,EAAE,CAAC,KAAK,SAAS,MAAM,EAAE,OAAO,EAAE;QAC9C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;QACrD,QAAQ,CAAC,YAAY,CAAC,EAAE,KAAK,CAAC;KAChC,KAAK,OAAO,CAAC,KAAK,CAAC,CAAC;IACrB,6DAA6D;IAC7D,QAAQ,CAAC,WAAW,EAAE,CAAC,KAAK,SAAS,MAAM,EAAE,OAAO,EAAE;QACnD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;QACrD,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,KAAK,EAAE,CAAC;KAC5C,KAAK,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;IACvB,6BAA6B;IAC7B,QAAQ,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/G,6CAA6C;IAC7C,QAAQ,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAC5C;AAED,qFAAqF;AACrF,eAAO,MAAM,qBAAqB,EAAE,aAAa,CAAC,YAAY,CAAC,OAAO,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAGvF,CAAC;AAEF;;;;;;GAMG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,UAAU,CAAC,CAuD7D"}
|
|
@@ -0,0 +1,71 @@
|
|
|
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
|
+
/** Thrown when the user cancels — Ctrl-C, or an EOF on the input stream. */
|
|
10
|
+
export class InitWizardCancelled extends Error {
|
|
11
|
+
constructor() {
|
|
12
|
+
super('Scaffolding cancelled.');
|
|
13
|
+
this.name = 'InitWizardCancelled';
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
/** The optional heads, as a checkbox list. `lsp` is not offered — see `askHeads`. */
|
|
17
|
+
export const OPTIONAL_HEAD_CHOICES = [
|
|
18
|
+
{ value: 'data', label: 'data', hint: 'typed JSON-RPC for forms, trees and code-gen' },
|
|
19
|
+
{ value: 'glsp', label: 'glsp', hint: 'graphical editing; adds a scaffolded diagram' }
|
|
20
|
+
];
|
|
21
|
+
/**
|
|
22
|
+
* The real prompt, backed by `@clack/prompts`.
|
|
23
|
+
*
|
|
24
|
+
* Imported dynamically so the library loads only when someone actually reaches
|
|
25
|
+
* the interactive path: every non-interactive `init`, and all twelve other
|
|
26
|
+
* subcommands, keep their previous startup cost.
|
|
27
|
+
*/
|
|
28
|
+
export async function createClackPrompt() {
|
|
29
|
+
const clack = await import('@clack/prompts');
|
|
30
|
+
/** Unwrap a clack answer, turning its cancel sentinel into a throw. */
|
|
31
|
+
const unwrap = (answer) => {
|
|
32
|
+
if (clack.isCancel(answer)) {
|
|
33
|
+
throw new InitWizardCancelled();
|
|
34
|
+
}
|
|
35
|
+
return answer;
|
|
36
|
+
};
|
|
37
|
+
// `Option<Value>` is a conditional type over the value, which stays deferred
|
|
38
|
+
// under our own generic parameter and so refuses a structurally identical
|
|
39
|
+
// literal. The cast asserts the shape the branch resolves to for `string`.
|
|
40
|
+
const toOptions = (choices) => choices.map(choice => ({
|
|
41
|
+
value: choice.value,
|
|
42
|
+
label: choice.label,
|
|
43
|
+
...(choice.hint === undefined ? {} : { hint: choice.hint })
|
|
44
|
+
}));
|
|
45
|
+
return {
|
|
46
|
+
intro: title => clack.intro(title),
|
|
47
|
+
note: (message, title) => clack.note(message, title),
|
|
48
|
+
text: async (options) => unwrap(await clack.text({
|
|
49
|
+
message: options.message,
|
|
50
|
+
initialValue: options.initialValue,
|
|
51
|
+
placeholder: options.placeholder,
|
|
52
|
+
validate: value => options.validate?.((value ?? '').trim())
|
|
53
|
+
})).trim(),
|
|
54
|
+
select: async (options) => unwrap(await clack.select({
|
|
55
|
+
message: options.message,
|
|
56
|
+
options: toOptions(options.choices),
|
|
57
|
+
initialValue: options.initialValue
|
|
58
|
+
})),
|
|
59
|
+
multiselect: async (options) => unwrap(await clack.multiselect({
|
|
60
|
+
message: options.message,
|
|
61
|
+
options: toOptions(options.choices),
|
|
62
|
+
initialValues: options.initialValues ? [...options.initialValues] : [],
|
|
63
|
+
// Legal and meaningful: an `lsp`-only project is a plain LSP
|
|
64
|
+
// server, so an empty selection must not be rejected.
|
|
65
|
+
required: false
|
|
66
|
+
})),
|
|
67
|
+
confirm: async (options) => unwrap(await clack.confirm({ message: options.message, initialValue: options.initialValue })),
|
|
68
|
+
outro: message => clack.outro(message)
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=init-prompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init-prompt.js","sourceRoot":"","sources":["../../src/commands/init-prompt.ts"],"names":[],"mappings":"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"}
|