@nylorun/cli 0.3.0-beta → 0.4.1-beta

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 (44) hide show
  1. package/CHANGELOG.md +65 -1
  2. package/README.md +55 -78
  3. package/dist/{runtime/baseline.js → baseline.js} +0 -1
  4. package/dist/cli.d.ts +1 -1
  5. package/dist/cli.js +34 -115
  6. package/dist/doctor.d.ts +1 -12
  7. package/dist/doctor.js +6 -96
  8. package/dist/home.d.ts +6 -0
  9. package/dist/home.js +15 -0
  10. package/dist/model/host-model.js +1 -1
  11. package/dist/project/create-tenant.d.ts +3 -1
  12. package/dist/project/create-tenant.js +3 -2
  13. package/dist/project/credentials.js +1 -1
  14. package/dist/project/env.d.ts +3 -0
  15. package/dist/project/env.js +21 -0
  16. package/dist/project/link.js +1 -1
  17. package/dist/project/root.js +2 -1
  18. package/dist/project/seed.d.ts +6 -0
  19. package/dist/project/seed.js +9 -7
  20. package/dist/tenant/commands.js +73 -14
  21. package/package.json +7 -10
  22. package/dist/dev-entry.d.ts +0 -5
  23. package/dist/dev-entry.js +0 -7
  24. package/dist/dev.d.ts +0 -47
  25. package/dist/dev.js +0 -278
  26. package/dist/launcher.d.ts +0 -5
  27. package/dist/launcher.js +0 -7
  28. package/dist/project/attach.d.ts +0 -32
  29. package/dist/project/attach.js +0 -241
  30. package/dist/runtime/commands.d.ts +0 -16
  31. package/dist/runtime/commands.js +0 -292
  32. package/dist/runtime/ephemeral.d.ts +0 -37
  33. package/dist/runtime/ephemeral.js +0 -84
  34. package/dist/runtime/exit-codes.d.ts +0 -9
  35. package/dist/runtime/exit-codes.js +0 -43
  36. package/dist/runtime/index.d.ts +0 -8
  37. package/dist/runtime/index.js +0 -6
  38. package/dist/runtime/launcher.d.ts +0 -81
  39. package/dist/runtime/launcher.js +0 -243
  40. package/dist/runtime/progress.d.ts +0 -10
  41. package/dist/runtime/progress.js +0 -8
  42. package/dist/runtime/version.d.ts +0 -6
  43. package/dist/runtime/version.js +0 -27
  44. /package/dist/{runtime/baseline.d.ts → baseline.d.ts} +0 -0
@@ -1,243 +0,0 @@
1
- import { spawn } from "node:child_process";
2
- import { existsSync, realpathSync, statSync } from "node:fs";
3
- import { homedir } from "node:os";
4
- import { delimiter, dirname, join, resolve } from "node:path";
5
- import { PROTOCOL_VERSION } from "@nylorun/agents";
6
- import { CliError } from "../errors.js";
7
- import { exitCodeForLauncherError, } from "./exit-codes.js";
8
- import { renderProgress } from "./progress.js";
9
- import { runtimeVersion } from "./version.js";
10
- /** The launcher command `@nylorun/runtime` installs (npm bin). */
11
- export const LAUNCHER_BIN = "nylorun-runtime";
12
- /** The `nylorun-runtime --json` contract this CLI speaks (core LAUNCHER_PROTOCOL). */
13
- const LAUNCHER_PROTOCOL = 1;
14
- /** Resolve NYLORUN_HOME, an explicit home, or `~/.nylorun`. */
15
- export function resolveHome(home) {
16
- if (home !== undefined && home.trim() !== "")
17
- return resolve(home);
18
- const fromEnv = process.env.NYLORUN_HOME?.trim();
19
- if (fromEnv)
20
- return resolve(fromEnv);
21
- return resolve(join(homedir(), ".nylorun"));
22
- }
23
- /** Install command shown whenever the Runtime is missing or incompatible. */
24
- export function runtimeInstallCommand() {
25
- return `npm install --global @nylorun/runtime@${runtimeVersion()}`;
26
- }
27
- /** Find `name` on PATH (with PATHEXT on Windows). */
28
- export function findOnPath(name, env) {
29
- const dirs = (env.PATH ?? env.Path ?? "").split(delimiter).filter(Boolean);
30
- const extensions = process.platform === "win32"
31
- ? (env.PATHEXT ?? ".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean)
32
- : [""];
33
- for (const dir of dirs) {
34
- for (const extension of extensions) {
35
- const candidate = join(dir, `${name}${extension.toLowerCase()}`);
36
- try {
37
- if (statSync(candidate).isFile())
38
- return candidate;
39
- }
40
- catch {
41
- /* not here */
42
- }
43
- }
44
- }
45
- return undefined;
46
- }
47
- /**
48
- * npm links a bin to the package's JS file: a symlink on POSIX, a `.cmd` shim
49
- * next to the package on Windows. Running that file on this Node avoids
50
- * spawning `.cmd` shims, which Node refuses without a shell.
51
- */
52
- function launcherScript(bin) {
53
- if (process.platform !== "win32") {
54
- const real = realpathSync(bin);
55
- return real.endsWith(".js") ? real : undefined;
56
- }
57
- const dir = dirname(bin);
58
- const main = join("@nylorun", "runtime", "dist", "launcher", "main.js");
59
- // Global prefix (`<prefix>/nylorun-runtime.cmd`) or project `.bin`.
60
- for (const candidate of [
61
- join(dir, "node_modules", main),
62
- join(dir, "..", main),
63
- ]) {
64
- if (existsSync(candidate))
65
- return candidate;
66
- }
67
- return undefined;
68
- }
69
- /**
70
- * Find the installed Runtime's launcher on PATH and check it speaks this CLI's
71
- * launcher and Host protocols. Never downloads or installs anything: a missing
72
- * Runtime is a prerequisite error that names the install command.
73
- */
74
- export async function launcher(home, options = {}) {
75
- const resolvedHome = resolve(home);
76
- const env = options.env ?? process.env;
77
- const bin = findOnPath(LAUNCHER_BIN, env);
78
- if (!bin) {
79
- throw new CliError(`The Nylorun Runtime is not installed (no "${LAUNCHER_BIN}" on PATH).\nInstall it, then retry:\n ${runtimeInstallCommand()}`, 1);
80
- }
81
- const probe = await invokeLauncher(bin, resolvedHome, ["version"], { env, renderProgress: false }, false);
82
- throwOnLauncherFailure(probe);
83
- const info = probe.result ?? {};
84
- const version = typeof info.runtimeVersion === "string" ? info.runtimeVersion : "unknown";
85
- const protocol = info.protocol;
86
- const hostCompatible = typeof protocol?.min === "number" &&
87
- typeof protocol.max === "number" &&
88
- protocol.min <= PROTOCOL_VERSION &&
89
- PROTOCOL_VERSION <= protocol.max;
90
- if (info.launcherProtocol !== LAUNCHER_PROTOCOL || !hostCompatible) {
91
- throw new CliError(`The installed Nylorun Runtime ${version} (${bin}) is not compatible with this CLI.\nInstall a compatible Runtime, then retry:\n ${runtimeInstallCommand()}`, 1);
92
- }
93
- return createHandle(resolvedHome, {
94
- bin,
95
- version,
96
- node: typeof info.node === "string" ? info.node : "unknown",
97
- }, env);
98
- }
99
- function createHandle(home, runtime, defaultEnv) {
100
- const run = (args, options = {}, streaming) => invokeLauncher(runtime.bin, home, args, {
101
- ...options,
102
- env: options.env ?? defaultEnv,
103
- }, streaming);
104
- return {
105
- home,
106
- runtime,
107
- invoke: (args, options) => run(args, options, false),
108
- invokeStreaming: (args, options) => run(args, options, true),
109
- };
110
- }
111
- /** Quote one argument for cmd.exe (only used for non-npm `.cmd` shims). */
112
- function quoteForCmd(value) {
113
- return `"${value.replace(/"/g, '""')}"`;
114
- }
115
- function spawnLauncher(bin, args, env) {
116
- const options = {
117
- env: { ...env },
118
- stdio: ["ignore", "pipe", "pipe"],
119
- };
120
- const script = launcherScript(bin);
121
- if (script)
122
- return spawn(process.execPath, [script, ...args], options);
123
- if (process.platform === "win32" && /\.(cmd|bat)$/i.test(bin)) {
124
- // Windows runs .cmd files only through cmd.exe, which needs quoting.
125
- return spawn(quoteForCmd(bin), args.map(quoteForCmd), {
126
- ...options,
127
- shell: true,
128
- });
129
- }
130
- return spawn(bin, args, options);
131
- }
132
- async function invokeLauncher(bin, home, args, options, _streaming) {
133
- const childArgs = ["--json", "--home", home, ...args];
134
- const child = spawnLauncher(bin, childArgs, options.env);
135
- const events = [];
136
- let result;
137
- let error;
138
- let stdout = "";
139
- let stderr = "";
140
- let lineBuffer = "";
141
- const handleLine = (line) => {
142
- const trimmed = line.trim();
143
- if (!trimmed)
144
- return;
145
- let event;
146
- try {
147
- event = JSON.parse(trimmed);
148
- }
149
- catch {
150
- return;
151
- }
152
- events.push(event);
153
- options.onEvent?.(event);
154
- if (event.type === "progress" && options.renderProgress !== false) {
155
- renderProgress(event);
156
- }
157
- if (event.type === "result") {
158
- const { type: _t, ...fields } = event;
159
- result = fields;
160
- }
161
- if (event.type === "error") {
162
- error = {
163
- code: event.code,
164
- message: event.message,
165
- remedy: event.remedy,
166
- ...(event.details !== undefined ? { details: event.details } : {}),
167
- };
168
- }
169
- if (event.type === "log") {
170
- const prefix = event.source === "tenant" && event.tenantId
171
- ? `[${event.tenantId}] `
172
- : "";
173
- process.stdout.write(`${prefix}${event.line}\n`);
174
- }
175
- };
176
- child.stdout?.on("data", (chunk) => {
177
- const text = chunk.toString("utf8");
178
- stdout += text;
179
- lineBuffer += text;
180
- const parts = lineBuffer.split("\n");
181
- lineBuffer = parts.pop() ?? "";
182
- for (const part of parts)
183
- handleLine(part);
184
- });
185
- child.stderr?.on("data", (chunk) => {
186
- stderr += chunk.toString("utf8");
187
- });
188
- const abort = () => {
189
- try {
190
- child.kill("SIGTERM");
191
- }
192
- catch {
193
- /* ignore */
194
- }
195
- };
196
- if (options.signal) {
197
- if (options.signal.aborted)
198
- abort();
199
- else
200
- options.signal.addEventListener("abort", abort, { once: true });
201
- }
202
- const exitCode = await waitForExit(child);
203
- if (lineBuffer.trim())
204
- handleLine(lineBuffer);
205
- if (options.signal) {
206
- options.signal.removeEventListener("abort", abort);
207
- }
208
- return {
209
- events,
210
- ...(result ? { result } : {}),
211
- ...(error ? { error } : {}),
212
- exitCode,
213
- stdout,
214
- stderr,
215
- };
216
- }
217
- function waitForExit(child) {
218
- return new Promise((resolvePromise, reject) => {
219
- child.once("error", reject);
220
- child.once("exit", (code, signal) => {
221
- if (code !== null)
222
- resolvePromise(code);
223
- else
224
- resolvePromise(signal === "SIGINT" ? 130 : signal === "SIGTERM" ? 143 : 1);
225
- });
226
- });
227
- }
228
- /**
229
- * Throw CliError with the Tenants-era exit code for a failed launcher invoke.
230
- */
231
- export function throwOnLauncherFailure(outcome) {
232
- if (outcome.exitCode === 0)
233
- return;
234
- if (outcome.exitCode === 2) {
235
- throw new CliError(outcome.error?.message ??
236
- (outcome.stderr.trim() || "Invalid runtime arguments."), 2);
237
- }
238
- const code = outcome.error?.code;
239
- const message = outcome.error
240
- ? `${outcome.error.message}${outcome.error.remedy ? `\n${outcome.error.remedy}` : ""}`
241
- : outcome.stderr.trim() || `Runtime launcher failed (exit ${outcome.exitCode}).`;
242
- throw new CliError(message, exitCodeForLauncherError(code));
243
- }
@@ -1,10 +0,0 @@
1
- /**
2
- * Render launcher progress the way the Tenants-era CLI did: phase name on
3
- * stderr.
4
- */
5
- export type ProgressEvent = {
6
- type: "progress";
7
- phase: "start" | "stop" | "wait";
8
- message?: string;
9
- };
10
- export declare function renderProgress(event: ProgressEvent, write?: (line: string) => void): void;
@@ -1,8 +0,0 @@
1
- export function renderProgress(event, write = (line) => {
2
- process.stderr.write(`${line}\n`);
3
- }) {
4
- const parts = [event.phase];
5
- if (event.message)
6
- parts.push(event.message);
7
- write(parts.join(" "));
8
- }
@@ -1,6 +0,0 @@
1
- /**
2
- * Recommended Runtime version from `cli/package.json` `nylorun.runtime` (D7):
3
- * the version named in install instructions. Compatibility itself is checked
4
- * by launcher and Host protocol, not by an exact match.
5
- */
6
- export declare function runtimeVersion(): string;
@@ -1,27 +0,0 @@
1
- import { readFileSync } from "node:fs";
2
- import { dirname, join } from "node:path";
3
- import { fileURLToPath } from "node:url";
4
- import { CliError } from "../errors.js";
5
- function cliPackageJsonPath() {
6
- // src/runtime/*.ts and dist/runtime/*.js both sit two levels below cli/.
7
- return join(dirname(fileURLToPath(import.meta.url)), "..", "..", "package.json");
8
- }
9
- /**
10
- * Recommended Runtime version from `cli/package.json` `nylorun.runtime` (D7):
11
- * the version named in install instructions. Compatibility itself is checked
12
- * by launcher and Host protocol, not by an exact match.
13
- */
14
- export function runtimeVersion() {
15
- let raw;
16
- try {
17
- raw = JSON.parse(readFileSync(cliPackageJsonPath(), "utf8"));
18
- }
19
- catch (error) {
20
- throw new CliError(`Cannot read CLI package.json: ${error instanceof Error ? error.message : String(error)}`, 1);
21
- }
22
- const version = raw?.nylorun?.runtime;
23
- if (typeof version !== "string" || version.trim() === "") {
24
- throw new CliError('cli/package.json is missing "nylorun.runtime" (the recommended Runtime version).', 1);
25
- }
26
- return version;
27
- }
File without changes