@nylorun/cli 0.1.2-beta → 0.2.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.
- package/CHANGELOG.md +48 -0
- package/README.md +45 -10
- package/dist/cli.js +268 -59
- package/dist/dev-entry.js +1 -0
- package/dist/dev.d.ts +5 -0
- package/dist/dev.js +11 -6
- package/dist/doctor.d.ts +7 -0
- package/dist/doctor.js +61 -0
- package/dist/errors.d.ts +5 -0
- package/dist/errors.js +9 -0
- package/dist/launcher.d.ts +5 -1
- package/dist/launcher.js +2 -2
- package/dist/model/configure.d.ts +8 -1
- package/dist/model/configure.js +33 -36
- package/dist/model/host-model.d.ts +20 -0
- package/dist/model/host-model.js +84 -0
- package/dist/project-runner.d.ts +16 -4
- package/dist/project-runner.js +67 -89
- package/dist/runtime-host.d.ts +39 -0
- package/dist/runtime-host.js +355 -0
- package/dist/scope.d.ts +65 -0
- package/dist/scope.js +191 -0
- package/package.json +3 -3
package/dist/model/configure.js
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import { join } from "node:path";
|
|
2
1
|
import { createInterface } from "node:readline/promises";
|
|
3
|
-
import { saveEnvironment } from "../environment.js";
|
|
4
|
-
import { ProjectCredentialStore } from "@nylorun/runtime/configuration";
|
|
5
2
|
import { modelsFor } from "@nylorun/runtime/configuration";
|
|
6
3
|
export class ConfigurationCancelled extends Error {
|
|
7
4
|
signal;
|
|
@@ -14,32 +11,32 @@ export class ConfigurationCancelled extends Error {
|
|
|
14
11
|
}
|
|
15
12
|
// Internal options also allow isolated prompt tests without changing process globals.
|
|
16
13
|
export async function configureProvider(options = {}) {
|
|
17
|
-
const root = options.root ?? process.cwd();
|
|
18
14
|
const output = options.output ?? process.stdout;
|
|
19
15
|
const controller = new AbortController();
|
|
20
16
|
const signal = controller.signal;
|
|
21
17
|
const forwardAbort = () => controller.abort(options.signal.reason);
|
|
22
18
|
options.signal?.throwIfAborted();
|
|
23
|
-
let
|
|
24
|
-
let enteredEnvironment = {};
|
|
25
|
-
const oauthStore = new ProjectCredentialStore(join(root, ".nylorun", "auth.json"), join(root, ".env", "auth.json"));
|
|
19
|
+
let captured;
|
|
26
20
|
const store = {
|
|
27
|
-
read
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
async
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
21
|
+
async read() {
|
|
22
|
+
return undefined;
|
|
23
|
+
},
|
|
24
|
+
async list() {
|
|
25
|
+
return [];
|
|
26
|
+
},
|
|
27
|
+
async delete() { },
|
|
28
|
+
async modify(_id, fn) {
|
|
29
|
+
const next = await fn(captured);
|
|
30
|
+
if (next?.type === "api_key" && !next.key)
|
|
31
|
+
throw new Error("An API key is required.");
|
|
32
|
+
if (next)
|
|
33
|
+
captured = next;
|
|
34
|
+
return next ?? captured;
|
|
40
35
|
},
|
|
41
36
|
};
|
|
42
|
-
const models = modelsFor({ provider: "", model: "" }, store
|
|
37
|
+
const models = modelsFor({ provider: "", model: "" }, store, {
|
|
38
|
+
environment: false,
|
|
39
|
+
});
|
|
43
40
|
const providers = models.getProviders();
|
|
44
41
|
const prompt = createInterface({
|
|
45
42
|
input: options.input ?? process.stdin,
|
|
@@ -75,10 +72,10 @@ export async function configureProvider(options = {}) {
|
|
|
75
72
|
model,
|
|
76
73
|
custom: { baseUrl },
|
|
77
74
|
};
|
|
78
|
-
const customModels = modelsFor(selection, store);
|
|
75
|
+
const customModels = modelsFor(selection, store, { environment: false });
|
|
79
76
|
if (!(await customModels.checkAuth("custom", { signal })))
|
|
80
77
|
await customModels.login("custom", "api_key", interaction());
|
|
81
|
-
|
|
78
|
+
return prompted(selection);
|
|
82
79
|
}
|
|
83
80
|
else {
|
|
84
81
|
const chosen = providers[choice - 1];
|
|
@@ -102,10 +99,8 @@ export async function configureProvider(options = {}) {
|
|
|
102
99
|
}
|
|
103
100
|
await models.login(chosen.id, method, interaction());
|
|
104
101
|
}
|
|
105
|
-
|
|
102
|
+
return prompted({ provider: chosen.id, model: model.id });
|
|
106
103
|
}
|
|
107
|
-
signal.throwIfAborted();
|
|
108
|
-
output.write("Provider configuration saved.\n");
|
|
109
104
|
}
|
|
110
105
|
catch (error) {
|
|
111
106
|
throw signal.aborted ? signal.reason : error;
|
|
@@ -140,16 +135,18 @@ export async function configureProvider(options = {}) {
|
|
|
140
135
|
},
|
|
141
136
|
};
|
|
142
137
|
}
|
|
143
|
-
|
|
138
|
+
function prompted(selection) {
|
|
144
139
|
signal.throwIfAborted();
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
140
|
+
if (!captured)
|
|
141
|
+
throw new Error("An API key or OAuth credential is required.");
|
|
142
|
+
output.write("Provider configuration saved.\n");
|
|
143
|
+
return {
|
|
144
|
+
provider: selection.provider,
|
|
145
|
+
model: selection.model,
|
|
146
|
+
...(selection.custom?.baseUrl
|
|
147
|
+
? { baseUrl: selection.custom.baseUrl }
|
|
148
|
+
: {}),
|
|
149
|
+
auth: captured,
|
|
150
|
+
};
|
|
154
151
|
}
|
|
155
152
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type PromptedModel } from "./configure.js";
|
|
2
|
+
/** Wire shape of GET/PUT `/v1/host/model` — local copy so CLI stays off `@nylorun/core`. */
|
|
3
|
+
type HostModelView = {
|
|
4
|
+
readonly configured: false;
|
|
5
|
+
} | {
|
|
6
|
+
readonly configured: true;
|
|
7
|
+
readonly provider: string;
|
|
8
|
+
readonly model: string;
|
|
9
|
+
readonly authType: "api_key" | "oauth";
|
|
10
|
+
readonly baseUrl?: string;
|
|
11
|
+
};
|
|
12
|
+
export declare function getHostModel(runtimeUrl: string, serverKey: string): Promise<HostModelView>;
|
|
13
|
+
export declare function putHostModel(runtimeUrl: string, serverKey: string, model: PromptedModel): Promise<HostModelView>;
|
|
14
|
+
export declare function ensureHostModel(options: {
|
|
15
|
+
runtimeUrl: string;
|
|
16
|
+
serverKey: string;
|
|
17
|
+
root?: string;
|
|
18
|
+
signal?: AbortSignal;
|
|
19
|
+
}): Promise<void>;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { configureProvider } from "./configure.js";
|
|
5
|
+
export async function getHostModel(runtimeUrl, serverKey) {
|
|
6
|
+
const response = await fetch(`${runtimeUrl}/v1/host/model`, {
|
|
7
|
+
headers: { authorization: `Bearer ${serverKey}` },
|
|
8
|
+
});
|
|
9
|
+
if (!response.ok)
|
|
10
|
+
throw new Error(`Runtime model status returned ${response.status}`);
|
|
11
|
+
return response.json();
|
|
12
|
+
}
|
|
13
|
+
export async function putHostModel(runtimeUrl, serverKey, model) {
|
|
14
|
+
const response = await fetch(`${runtimeUrl}/v1/host/model`, {
|
|
15
|
+
method: "PUT",
|
|
16
|
+
headers: {
|
|
17
|
+
authorization: `Bearer ${serverKey}`,
|
|
18
|
+
"content-type": "application/json",
|
|
19
|
+
},
|
|
20
|
+
body: JSON.stringify({
|
|
21
|
+
requestId: randomUUID(),
|
|
22
|
+
idempotencyKey: randomUUID(),
|
|
23
|
+
provider: model.provider,
|
|
24
|
+
model: model.model,
|
|
25
|
+
...(model.baseUrl ? { baseUrl: model.baseUrl } : {}),
|
|
26
|
+
auth: model.auth,
|
|
27
|
+
}),
|
|
28
|
+
});
|
|
29
|
+
const body = (await response.json().catch(() => ({})));
|
|
30
|
+
if (!response.ok)
|
|
31
|
+
throw new Error(body.message ?? `Runtime rejected the model provider (${response.status})`);
|
|
32
|
+
return body;
|
|
33
|
+
}
|
|
34
|
+
export async function ensureHostModel(options) {
|
|
35
|
+
const current = await getHostModel(options.runtimeUrl, options.serverKey);
|
|
36
|
+
if (current.configured)
|
|
37
|
+
return;
|
|
38
|
+
const seeded = seedFromProject(options.root ?? process.cwd());
|
|
39
|
+
if (seeded) {
|
|
40
|
+
await putHostModel(options.runtimeUrl, options.serverKey, seeded);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
if (process.stdin.isTTY && process.stdout.isTTY) {
|
|
44
|
+
const prompted = await configureProvider({
|
|
45
|
+
root: options.root,
|
|
46
|
+
signal: options.signal,
|
|
47
|
+
});
|
|
48
|
+
await putHostModel(options.runtimeUrl, options.serverKey, prompted);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
throw new Error("Model provider is not configured. Run nylorun dev in a terminal to set it up, or open Studio.");
|
|
52
|
+
}
|
|
53
|
+
function seedFromProject(root) {
|
|
54
|
+
const provider = process.env.MODEL_PROVIDER?.trim();
|
|
55
|
+
const model = process.env.MODEL?.trim();
|
|
56
|
+
if (!provider || !model)
|
|
57
|
+
return undefined;
|
|
58
|
+
const baseUrl = process.env.MODEL_PROVIDER_BASE_URL?.trim();
|
|
59
|
+
const key = process.env.MODEL_PROVIDER_API_KEY;
|
|
60
|
+
const auth = key
|
|
61
|
+
? { type: "api_key", key }
|
|
62
|
+
: legacyCredential(root, provider);
|
|
63
|
+
if (!auth)
|
|
64
|
+
return undefined;
|
|
65
|
+
return {
|
|
66
|
+
provider,
|
|
67
|
+
model,
|
|
68
|
+
...(baseUrl ? { baseUrl } : {}),
|
|
69
|
+
auth,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function legacyCredential(root, provider) {
|
|
73
|
+
for (const relative of [".nylorun/auth.json", ".env/auth.json"]) {
|
|
74
|
+
try {
|
|
75
|
+
const all = JSON.parse(readFileSync(join(root, relative), "utf8"));
|
|
76
|
+
const credential = all[provider];
|
|
77
|
+
if (credential?.type === "api_key" || credential?.type === "oauth")
|
|
78
|
+
return credential;
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
/* A project without a legacy credential file is set up interactively. */
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
package/dist/project-runner.d.ts
CHANGED
|
@@ -1,8 +1,20 @@
|
|
|
1
|
-
|
|
1
|
+
import { type Scope } from "./scope.js";
|
|
2
|
+
export interface LocalCredentials {
|
|
2
3
|
serverKey: string;
|
|
3
4
|
executors: Record<string, string>;
|
|
4
|
-
}
|
|
5
|
-
export declare function
|
|
5
|
+
}
|
|
6
|
+
export declare function localCredentials(path: string): Promise<LocalCredentials>;
|
|
7
|
+
export interface ExecutorScopeToken {
|
|
8
|
+
token: string;
|
|
9
|
+
agentId: string;
|
|
10
|
+
implementationVersion: string;
|
|
11
|
+
}
|
|
12
|
+
/** Registers or rotates this project's executor credentials on the running host. */
|
|
13
|
+
export declare function putExecutors(url: string, serverKey: string, executors: readonly ExecutorScopeToken[]): Promise<void>;
|
|
14
|
+
export interface RunProjectOptions {
|
|
6
15
|
studio?: boolean;
|
|
7
16
|
open?: boolean;
|
|
8
|
-
|
|
17
|
+
autostart?: boolean;
|
|
18
|
+
scope?: Scope;
|
|
19
|
+
}
|
|
20
|
+
export declare function runProject(entry: string, options?: RunProjectOptions): Promise<void>;
|
package/dist/project-runner.js
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
import { fork } from "node:child_process";
|
|
2
1
|
import { createRequire } from "node:module";
|
|
3
2
|
import { randomBytes } from "node:crypto";
|
|
4
3
|
import { mkdir, readFile, writeFile, chmod } from "node:fs/promises";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
4
|
+
import { dirname, join, resolve } from "node:path";
|
|
5
|
+
import { pathToFileURL } from "node:url";
|
|
7
6
|
import { createClient, connectAgents, } from "@nylorun/agents";
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
7
|
+
import { ensureHostModel } from "./model/host-model.js";
|
|
8
|
+
import { CliError } from "./errors.js";
|
|
9
|
+
import { ensureDataDir, loadScopeEnvironment, probeHealth, resolveScope, } from "./scope.js";
|
|
10
|
+
import { ensureRuntime } from "./runtime-host.js";
|
|
11
|
+
export async function localCredentials(path) {
|
|
12
|
+
await mkdir(dirname(path), { recursive: true, mode: 0o700 });
|
|
14
13
|
try {
|
|
15
14
|
const value = JSON.parse(await readFile(path, "utf8"));
|
|
16
15
|
if (typeof value.serverKey !== "string" || !value.executors)
|
|
@@ -26,100 +25,61 @@ export async function localCredentials(root = process.cwd()) {
|
|
|
26
25
|
return value;
|
|
27
26
|
}
|
|
28
27
|
}
|
|
28
|
+
/** Registers or rotates this project's executor credentials on the running host. */
|
|
29
|
+
export async function putExecutors(url, serverKey, executors) {
|
|
30
|
+
const response = await fetch(`${url}/v1/executors`, {
|
|
31
|
+
method: "PUT",
|
|
32
|
+
headers: {
|
|
33
|
+
authorization: `Bearer ${serverKey}`,
|
|
34
|
+
"content-type": "application/json",
|
|
35
|
+
},
|
|
36
|
+
body: JSON.stringify({ executors }),
|
|
37
|
+
});
|
|
38
|
+
if (!response.ok)
|
|
39
|
+
throw new CliError(`The Runtime at ${url} rejected this project's executors (${response.status}): ${await response
|
|
40
|
+
.text()
|
|
41
|
+
.catch(() => "")}`);
|
|
42
|
+
}
|
|
29
43
|
export async function runProject(entry, options = {}) {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
modelSelection();
|
|
44
|
+
const scope = options.scope ?? resolveScope();
|
|
45
|
+
loadScopeEnvironment(scope);
|
|
33
46
|
const registry = await import(pathToFileURL(resolve(entry)).href);
|
|
34
47
|
if (!Array.isArray(registry.agents) || !registry.agents.length)
|
|
35
48
|
throw new Error(`${entry} must export a non-empty agents array`);
|
|
36
49
|
const agents = registry.agents;
|
|
37
|
-
|
|
50
|
+
await ensureDataDir(scope);
|
|
51
|
+
const credentials = await localCredentials(scope.credentialsPath);
|
|
38
52
|
const version = process.env.NYLORUN_IMPLEMENTATION_VERSION ?? "dev";
|
|
39
53
|
const scopes = agents.map((agent) => {
|
|
40
54
|
const token = (credentials.executors[agent.id] ??=
|
|
41
55
|
randomBytes(32).toString("hex"));
|
|
42
|
-
return {
|
|
43
|
-
token,
|
|
44
|
-
agentId: agent.id,
|
|
45
|
-
implementationVersion: version,
|
|
46
|
-
};
|
|
56
|
+
return { token, agentId: agent.id, implementationVersion: version };
|
|
47
57
|
});
|
|
48
|
-
await writeFile(
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
const url = `http://127.0.0.1:${port}`;
|
|
53
|
-
let child;
|
|
58
|
+
await writeFile(scope.credentialsPath, JSON.stringify(credentials), {
|
|
59
|
+
mode: 0o600,
|
|
60
|
+
});
|
|
61
|
+
const url = scope.url;
|
|
54
62
|
let studio;
|
|
55
63
|
const connections = [];
|
|
64
|
+
let watchdog;
|
|
56
65
|
let stopping;
|
|
57
|
-
let intentionalStop = false;
|
|
58
66
|
const close = () => (stopping ??= (async () => {
|
|
67
|
+
if (watchdog)
|
|
68
|
+
clearInterval(watchdog);
|
|
59
69
|
await Promise.allSettled(connections.map((c) => c.close()));
|
|
60
70
|
await studio?.close().catch(() => { });
|
|
61
|
-
if (child?.exitCode === null && child.signalCode === null) {
|
|
62
|
-
child.kill("SIGTERM");
|
|
63
|
-
await new Promise((resolve) => {
|
|
64
|
-
const timer = setTimeout(() => child?.kill("SIGKILL"), 5000);
|
|
65
|
-
child.once("exit", () => {
|
|
66
|
-
clearTimeout(timer);
|
|
67
|
-
resolve();
|
|
68
|
-
});
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
71
|
for (const agent of agents)
|
|
72
72
|
await agent.close?.();
|
|
73
73
|
})());
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
void close().finally(() => {
|
|
77
|
-
process.exitCode = 0;
|
|
78
|
-
});
|
|
79
|
-
};
|
|
74
|
+
// The Runtime is a separate, persistent process now, so shutting this one down leaves it up.
|
|
75
|
+
const stop = () => void close().finally(() => (process.exitCode = 0));
|
|
80
76
|
process.on("SIGINT", stop);
|
|
81
77
|
process.on("SIGTERM", stop);
|
|
82
78
|
try {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
HOST: "127.0.0.1",
|
|
88
|
-
PORT: String(port),
|
|
89
|
-
NYLORUN_PROJECT_PROVIDER: "1",
|
|
90
|
-
NYLORUN_SERVER_KEY: credentials.serverKey,
|
|
91
|
-
NYLORUN_EXECUTORS_JSON: JSON.stringify(scopes),
|
|
92
|
-
NYLORUN_SQLITE_PATH: process.env.NYLORUN_SQLITE_PATH ??
|
|
93
|
-
join(process.cwd(), ".nylorun/runtime.sqlite"),
|
|
94
|
-
},
|
|
95
|
-
stdio: ["ignore", "inherit", "inherit", "ipc"],
|
|
96
|
-
});
|
|
97
|
-
await new Promise((resolve, reject) => {
|
|
98
|
-
const timer = setTimeout(() => reject(new Error("Local Runtime did not start within 20 seconds")), 20000);
|
|
99
|
-
const onReady = (message) => {
|
|
100
|
-
if (message?.type === "ready") {
|
|
101
|
-
cleanup();
|
|
102
|
-
resolve();
|
|
103
|
-
}
|
|
104
|
-
};
|
|
105
|
-
const onExit = (code) => {
|
|
106
|
-
cleanup();
|
|
107
|
-
reject(new Error(`Local Runtime exited (${code})`));
|
|
108
|
-
};
|
|
109
|
-
const onError = (error) => {
|
|
110
|
-
cleanup();
|
|
111
|
-
reject(error);
|
|
112
|
-
};
|
|
113
|
-
const cleanup = () => {
|
|
114
|
-
clearTimeout(timer);
|
|
115
|
-
child.off("message", onReady);
|
|
116
|
-
child.off("exit", onExit);
|
|
117
|
-
child.off("error", onError);
|
|
118
|
-
};
|
|
119
|
-
child.on("message", onReady);
|
|
120
|
-
child.once("exit", onExit);
|
|
121
|
-
child.once("error", onError);
|
|
122
|
-
});
|
|
79
|
+
await ensureRuntime(scope, { autostart: options.autostart !== false });
|
|
80
|
+
await putExecutors(url, credentials.serverKey, scopes);
|
|
81
|
+
if (process.env.NYLORUN_DEV_MODEL !== "fixture")
|
|
82
|
+
await ensureHostModel({ runtimeUrl: url, serverKey: credentials.serverKey });
|
|
123
83
|
const client = createClient({ url, key: credentials.serverKey });
|
|
124
84
|
for (let index = 0; index < agents.length; index++) {
|
|
125
85
|
await client.saveAgent(agents[index], {
|
|
@@ -145,14 +105,32 @@ export async function runProject(entry, options = {}) {
|
|
|
145
105
|
console.log(`Studio on ${studio.address}`);
|
|
146
106
|
}
|
|
147
107
|
console.log(`Local project ready at ${url}; ${agents.length} connected agent(s).`);
|
|
148
|
-
await
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
108
|
+
const sandbox = await (await import("./doctor.js")).sandboxBanner(url, credentials.serverKey, agents.map((agent) => agent.manifest));
|
|
109
|
+
if (sandbox)
|
|
110
|
+
console.log(sandbox);
|
|
111
|
+
await new Promise((settle) => {
|
|
112
|
+
const finish = () => {
|
|
113
|
+
if (!stopping)
|
|
114
|
+
void close();
|
|
115
|
+
settle();
|
|
116
|
+
};
|
|
117
|
+
process.once("SIGINT", finish);
|
|
118
|
+
process.once("SIGTERM", finish);
|
|
119
|
+
// Without a child to watch, a Runtime that dies would leave this process connected to
|
|
120
|
+
// nothing; three consecutive failed probes end the run with a pointer to the log.
|
|
121
|
+
let failures = 0;
|
|
122
|
+
watchdog = setInterval(async () => {
|
|
123
|
+
if (stopping)
|
|
124
|
+
return;
|
|
125
|
+
if ((await probeHealth(url, 2000)).health)
|
|
126
|
+
return void (failures = 0);
|
|
127
|
+
if (++failures < 3)
|
|
128
|
+
return;
|
|
129
|
+
console.error('Runtime stopped unexpectedly; see "nylorun logs".');
|
|
130
|
+
process.exitCode = 1;
|
|
131
|
+
finish();
|
|
132
|
+
}, 5000);
|
|
133
|
+
watchdog.unref();
|
|
156
134
|
});
|
|
157
135
|
}
|
|
158
136
|
finally {
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type RuntimeState, type Scope } from "./scope.js";
|
|
2
|
+
export type HostState = "running" | "stopped" | "stale" | "unhealthy" | "pid-recycled" | "port-conflict";
|
|
3
|
+
export interface Status {
|
|
4
|
+
state: HostState;
|
|
5
|
+
scope: Scope;
|
|
6
|
+
runtime?: RuntimeState;
|
|
7
|
+
version?: string;
|
|
8
|
+
scopeId?: string;
|
|
9
|
+
pid?: number;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Derived from the resolved server entry rather than a "./package.json" export, so the version
|
|
13
|
+
* is readable for every installed Runtime — including one too old to declare that export,
|
|
14
|
+
* which is exactly when skew detection matters.
|
|
15
|
+
*/
|
|
16
|
+
export declare const cliRuntimeVersion: () => string | undefined;
|
|
17
|
+
export declare function hostStatus(scope: Scope): Promise<Status>;
|
|
18
|
+
export declare function startHost(scope: Scope, options?: {
|
|
19
|
+
foreground?: boolean;
|
|
20
|
+
restart?: boolean;
|
|
21
|
+
}): Promise<Status>;
|
|
22
|
+
export declare function stopHost(scope: Scope, options?: {
|
|
23
|
+
timeoutMs?: number;
|
|
24
|
+
}): Promise<"stopped" | "not-running">;
|
|
25
|
+
export interface EnsureOptions {
|
|
26
|
+
autostart: boolean;
|
|
27
|
+
quiet?: boolean;
|
|
28
|
+
}
|
|
29
|
+
export declare function ensureRuntime(scope: Scope, options: EnsureOptions): Promise<Status>;
|
|
30
|
+
/**
|
|
31
|
+
* A daemon from an older install would reject executor registration with a bare 404, so the
|
|
32
|
+
* commands that depend on that route fail early with the remedy instead.
|
|
33
|
+
*/
|
|
34
|
+
export declare function assertCompatible(scope: Scope, status: Status): void;
|
|
35
|
+
export declare function warnIncompatible(scope: Scope, status: Status): void;
|
|
36
|
+
export declare function tailLog(scope: Scope, options: {
|
|
37
|
+
follow: boolean;
|
|
38
|
+
lines: number;
|
|
39
|
+
}): Promise<void>;
|