nylorun 0.14.0-beta → 0.15.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 +131 -0
- package/README.md +226 -144
- package/dist/cli.js +142 -47
- package/dist/client/agents.d.ts +6 -0
- package/dist/client/agents.js +148 -0
- package/dist/client/artifacts.d.ts +4 -0
- package/dist/client/artifacts.js +210 -0
- package/dist/client/doctor.d.ts +7 -2
- package/dist/client/doctor.js +14 -13
- package/dist/client/environment-manifests.d.ts +10 -0
- package/dist/client/environment-manifests.js +173 -0
- package/dist/client/environments.d.ts +4 -0
- package/dist/client/environments.js +295 -0
- package/dist/client/io.d.ts +31 -0
- package/dist/client/io.js +72 -0
- package/dist/{stack → client}/mcp.d.ts +2 -2
- package/dist/{stack → client}/mcp.js +14 -12
- package/dist/client/model/configure.d.ts +1 -1
- package/dist/client/model/configure.js +1 -1
- package/dist/client/model/pi-ai.d.ts +3 -3
- package/dist/client/model/pi-ai.js +4 -4
- package/dist/client/models.d.ts +13 -0
- package/dist/client/models.js +203 -0
- package/dist/client/runtime.d.ts +40 -0
- package/dist/client/runtime.js +134 -0
- package/dist/client/sessions.d.ts +4 -0
- package/dist/client/sessions.js +295 -0
- package/dist/client/settings.d.ts +12 -0
- package/dist/client/settings.js +103 -0
- package/dist/client/signing-keys.d.ts +3 -0
- package/dist/client/signing-keys.js +32 -0
- package/dist/client/target.d.ts +33 -0
- package/dist/client/target.js +65 -0
- package/dist/client/tenant.d.ts +22 -0
- package/dist/client/tenant.js +176 -0
- package/dist/doctor.js +3 -3
- package/dist/nylo.js +20 -4
- package/dist/sandbox/cluster-file.d.ts +1 -1
- package/dist/sandbox/commands.d.ts +1 -1
- package/dist/sandbox/commands.js +7 -7
- package/dist/sandbox/manifests.d.ts +1 -1
- package/dist/sandbox/manifests.js +1 -1
- package/dist/sandbox/probe.d.ts +1 -1
- package/dist/stack/commands.d.ts +9 -4
- package/dist/stack/commands.js +22 -26
- package/dist/stack/compose-file.d.ts +1 -1
- package/dist/stack/compose-file.js +12 -12
- package/dist/stack/env-file.d.ts +3 -3
- package/dist/stack/env-file.js +2 -2
- package/dist/stack/images.d.ts +1 -1
- package/dist/stack/images.js +1 -1
- package/dist/stack/index.d.ts +1 -10
- package/dist/stack/index.js +3 -19
- package/dist/stack/keys.d.ts +2 -2
- package/dist/stack/keys.js +14 -11
- package/dist/stack/paths.d.ts +1 -1
- package/dist/stack/prepare.d.ts +1 -1
- package/dist/stack/stacks.js +1 -1
- package/dist/telemetry.d.ts +2 -2
- package/dist/telemetry.js +4 -4
- package/package.json +7 -6
- package/dist/client/access/commands.d.ts +0 -8
- package/dist/client/access/commands.js +0 -33
- package/dist/client/cli.d.ts +0 -2
- package/dist/client/cli.js +0 -106
- package/dist/client/installation/commands.d.ts +0 -7
- package/dist/client/installation/commands.js +0 -82
- package/dist/client/project/connection.d.ts +0 -36
- package/dist/client/project/connection.js +0 -80
- package/dist/client/project/env.d.ts +0 -3
- package/dist/client/project/env.js +0 -19
- package/dist/stack/sandbox.d.ts +0 -4
- package/dist/stack/sandbox.js +0 -107
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { CliError } from "../errors.js";
|
|
2
|
+
import { parseStackFlags } from "../stack/commands.js";
|
|
3
|
+
import { keyCommand, keyUsage } from "../stack/keys.js";
|
|
4
|
+
import { printJson, printTable } from "./io.js";
|
|
5
|
+
import { mcpCommand, mcpUsage } from "./mcp.js";
|
|
6
|
+
import { callsCommand, modelsCommand, modelsUsage, usageCommand, usageUsage } from "./models.js";
|
|
7
|
+
import { budgetsCommand, coverageCommand, settingsCommand, settingsUsage, toolPolicyCommand, } from "./settings.js";
|
|
8
|
+
import { signingKeysCommand, signingKeysUsage } from "./signing-keys.js";
|
|
9
|
+
import { connect, managementClient, messageOf, remoteConnection } from "./target.js";
|
|
10
|
+
export const tenantUsage = `nylorun tenant <command>
|
|
11
|
+
|
|
12
|
+
The Management API of the installation's one Tenant, with a management key: the local Tenant
|
|
13
|
+
--tenant names (else the linked project's, else the default one), or the installation that
|
|
14
|
+
NYLORUN_RUNTIME_URL and NYLORUN_MANAGEMENT_KEY name.
|
|
15
|
+
|
|
16
|
+
reset [--sessions|--environments|--all] [--yes] [--tenant <name>]
|
|
17
|
+
clear the Tenant's sessions, Environments or all its data
|
|
18
|
+
(the Project link and keys stay)
|
|
19
|
+
${keyUsage}
|
|
20
|
+
${signingKeysUsage}
|
|
21
|
+
${modelsUsage}
|
|
22
|
+
${usageUsage}
|
|
23
|
+
${settingsUsage}
|
|
24
|
+
${mcpUsage}
|
|
25
|
+
|
|
26
|
+
A put reads a JSON body from a file, or from stdin for -, and replaces the whole document; what
|
|
27
|
+
budgets, tool-policy and settings artifacts get print, put takes back. An API key is read from
|
|
28
|
+
stdin, never from the arguments.`;
|
|
29
|
+
const usageError = (message) => new CliError(message, 2);
|
|
30
|
+
/** The Management API client of the installation `--tenant` (or the environment) names. */
|
|
31
|
+
export async function tenantClient(deps, tenant) {
|
|
32
|
+
const connection = await connect(deps, "management", tenant);
|
|
33
|
+
return { connection, admin: managementClient(deps, connection) };
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* `nylorun status` for an installation the environment names (`NYLORUN_RUNTIME_URL` and
|
|
37
|
+
* `NYLORUN_MANAGEMENT_KEY`): the Tenant, its checks and counts. A local Tenant's status is the
|
|
38
|
+
* stack's (`stack/commands.ts`).
|
|
39
|
+
*/
|
|
40
|
+
export async function remoteStatus(deps, args) {
|
|
41
|
+
const usage = "nylorun status [--tenant <name>] [--json]";
|
|
42
|
+
const flags = parseStackFlags(args, { booleans: ["--json"] }, usage);
|
|
43
|
+
if (flags.rest.length)
|
|
44
|
+
throw usageError(`Usage: ${usage}`);
|
|
45
|
+
const { connection, admin } = await tenantClient(deps, undefined);
|
|
46
|
+
let body;
|
|
47
|
+
try {
|
|
48
|
+
body = await admin.tenant.status();
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
throw new CliError(`${messageOf(error)} The installation at ${connection.url} did not answer.`, 1);
|
|
52
|
+
}
|
|
53
|
+
if (flags.booleans.has("--json")) {
|
|
54
|
+
deps.out(JSON.stringify(body, null, 2));
|
|
55
|
+
return 0;
|
|
56
|
+
}
|
|
57
|
+
deps.out(`${body.tenant.name} ${body.tenant.id}`);
|
|
58
|
+
deps.out(`runtime ${connection.url}`);
|
|
59
|
+
deps.out(`path ${body.path}`);
|
|
60
|
+
deps.out(`checks ${Object.entries(body.checks)
|
|
61
|
+
.map(([k, v]) => `${k}=${v ? "ok" : "fail"}`)
|
|
62
|
+
.join(" ")}`);
|
|
63
|
+
deps.out(`counts sessions=${body.counts.sessions} running=${body.counts.runningSessions} uncertain=${body.counts.uncertainEffects}`);
|
|
64
|
+
deps.out(`sandbox ${body.sandbox.backend ?? "none"}`);
|
|
65
|
+
return 0;
|
|
66
|
+
}
|
|
67
|
+
const RESET_USAGE = "nylorun tenant reset [--sessions|--environments|--all] [--yes] [--tenant <name>]";
|
|
68
|
+
const SCOPES = { "--sessions": "sessions", "--environments": "environments", "--all": "all" };
|
|
69
|
+
/** `nylorun tenant reset`; `--all` asks first. */
|
|
70
|
+
async function reset(deps, args) {
|
|
71
|
+
const flags = parseStackFlags(args, { booleans: ["--yes", ...Object.keys(SCOPES)], values: ["--tenant"], aliases: { "-y": "--yes" } }, RESET_USAGE);
|
|
72
|
+
if (flags.rest.length)
|
|
73
|
+
throw usageError(`Usage: ${RESET_USAGE}`);
|
|
74
|
+
const chosen = Object.keys(SCOPES).filter((flag) => flags.booleans.has(flag));
|
|
75
|
+
if (chosen.length > 1)
|
|
76
|
+
throw usageError("Pass only one of --sessions, --environments, --all.");
|
|
77
|
+
const scope = chosen.length ? SCOPES[chosen[0]] : "sessions";
|
|
78
|
+
const { connection, admin } = await tenantClient(deps, flags.values.get("--tenant"));
|
|
79
|
+
if (scope === "all" && !flags.booleans.has("--yes")) {
|
|
80
|
+
if (!deps.confirm)
|
|
81
|
+
throw usageError("Confirmation required; pass --yes for non-interactive use.");
|
|
82
|
+
if (!(await deps.confirm(`Reset ALL data of ${connection.label}? The Project link and keys are kept. [y/N] `))) {
|
|
83
|
+
deps.err("Cancelled.");
|
|
84
|
+
return 1;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
try {
|
|
88
|
+
await admin.tenant.reset({ scope, activeWork: "drain" });
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
throw new CliError(`Tenant reset failed: ${messageOf(error)}`, 1);
|
|
92
|
+
}
|
|
93
|
+
deps.out(`Reset ${connection.label} (${scope}).`);
|
|
94
|
+
return 0;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* `nylorun tenant keys`: through the Management API on an installation the environment names
|
|
98
|
+
* (application keys only), else on the local Tenant through `nylorun-operate`.
|
|
99
|
+
*/
|
|
100
|
+
async function keys(deps, args) {
|
|
101
|
+
if (args.includes("--tenant") || !remoteConnection(deps.env, "management"))
|
|
102
|
+
return keyCommand(deps, args);
|
|
103
|
+
const [verb, ...rest] = args;
|
|
104
|
+
const { admin, connection } = await tenantClient(deps, undefined);
|
|
105
|
+
if (verb === "put") {
|
|
106
|
+
const usage = "nylorun tenant keys put <id>";
|
|
107
|
+
const flags = parseStackFlags(rest, { booleans: ["--management"] }, usage);
|
|
108
|
+
if (flags.booleans.has("--management"))
|
|
109
|
+
throw new CliError("Management keys are issued only on the Runtime's machine: run nylorun tenant keys put <id> --management there.", 2);
|
|
110
|
+
if (flags.rest.length !== 1)
|
|
111
|
+
throw usageError(`Usage: ${usage}`);
|
|
112
|
+
const key = await admin.keys.put(flags.rest[0]);
|
|
113
|
+
deps.out(key.key);
|
|
114
|
+
deps.err(`${key.rotated ? "Rotated" : "Created"} application key ${key.id} on ${connection.label}${key.rotated ? " (the previous key no longer works)" : ""}. Store it now: it is not shown again.`);
|
|
115
|
+
return 0;
|
|
116
|
+
}
|
|
117
|
+
if (verb === "list" || verb === "ls") {
|
|
118
|
+
const usage = "nylorun tenant keys list [--json]";
|
|
119
|
+
const flags = parseStackFlags(rest, { booleans: ["--json"] }, usage);
|
|
120
|
+
if (flags.rest.length)
|
|
121
|
+
throw usageError(`Usage: ${usage}`);
|
|
122
|
+
const list = await admin.keys.list();
|
|
123
|
+
if (flags.booleans.has("--json"))
|
|
124
|
+
printJson(deps, list);
|
|
125
|
+
else
|
|
126
|
+
printTable(deps, [["ID", "ROLE", "CREATED"], ...list.map((key) => [key.id, key.role, key.createdAt])]);
|
|
127
|
+
return 0;
|
|
128
|
+
}
|
|
129
|
+
if (verb === "rm" || verb === "delete") {
|
|
130
|
+
const usage = "nylorun tenant keys rm <id>";
|
|
131
|
+
const flags = parseStackFlags(rest, {}, usage);
|
|
132
|
+
if (flags.rest.length !== 1)
|
|
133
|
+
throw usageError(`Usage: ${usage}`);
|
|
134
|
+
const id = flags.rest[0];
|
|
135
|
+
if (!(await admin.keys.delete(id))) {
|
|
136
|
+
deps.err(`No key ${id} on ${connection.label}.`);
|
|
137
|
+
return 1;
|
|
138
|
+
}
|
|
139
|
+
deps.out(`Deleted key ${id}: it no longer works.`);
|
|
140
|
+
return 0;
|
|
141
|
+
}
|
|
142
|
+
throw usageError(`Usage:\n${keyUsage}`);
|
|
143
|
+
}
|
|
144
|
+
/** `nylorun tenant <group> ...` */
|
|
145
|
+
export async function tenantCommand(deps, args) {
|
|
146
|
+
const [group, ...rest] = args;
|
|
147
|
+
if (group === "--help" || group === "-h") {
|
|
148
|
+
deps.out(tenantUsage);
|
|
149
|
+
return 0;
|
|
150
|
+
}
|
|
151
|
+
if (!group)
|
|
152
|
+
throw usageError(tenantUsage);
|
|
153
|
+
if (group === "reset")
|
|
154
|
+
return reset(deps, rest);
|
|
155
|
+
if (group === "keys" || group === "key")
|
|
156
|
+
return keys(deps, rest);
|
|
157
|
+
if (group === "signing-keys")
|
|
158
|
+
return signingKeysCommand(deps, rest);
|
|
159
|
+
if (group === "models" || group === "model")
|
|
160
|
+
return modelsCommand(deps, rest);
|
|
161
|
+
if (group === "usage")
|
|
162
|
+
return usageCommand(deps, rest);
|
|
163
|
+
if (group === "calls")
|
|
164
|
+
return callsCommand(deps, rest);
|
|
165
|
+
if (group === "budgets")
|
|
166
|
+
return budgetsCommand(deps, rest);
|
|
167
|
+
if (group === "tool-policy")
|
|
168
|
+
return toolPolicyCommand(deps, rest);
|
|
169
|
+
if (group === "settings")
|
|
170
|
+
return settingsCommand(deps, rest);
|
|
171
|
+
if (group === "coverage")
|
|
172
|
+
return coverageCommand(deps, rest);
|
|
173
|
+
if (group === "mcp")
|
|
174
|
+
return mcpCommand(deps, rest);
|
|
175
|
+
throw usageError(`Unknown tenant command ${group}.\n${tenantUsage}`);
|
|
176
|
+
}
|
package/dist/doctor.js
CHANGED
|
@@ -75,7 +75,7 @@ export async function doctorStack(options) {
|
|
|
75
75
|
? `- ${local.name} stopped (Compose project ${local.project}): run nylorun up`
|
|
76
76
|
: local.runtime.healthy
|
|
77
77
|
? `✓ ${local.name} running (Compose project ${local.project})`
|
|
78
|
-
: `✗ ${local.name} running, but the Runtime does not answer: see nylorun status and nylorun logs runtime`,
|
|
78
|
+
: `✗ ${local.name} running, but the Runtime does not answer: see nylorun status and nylorun local logs runtime`,
|
|
79
79
|
]);
|
|
80
80
|
if (local.state === "running") {
|
|
81
81
|
rows.push([
|
|
@@ -88,7 +88,7 @@ export async function doctorStack(options) {
|
|
|
88
88
|
"gateway",
|
|
89
89
|
local.gateway.healthy
|
|
90
90
|
? `✓ ${local.gateway.state} · combined packing (runtime: core,loop; gateway: gates)`
|
|
91
|
-
: `✗ ${local.gateway.state}: model calls fail; see nylorun logs gateway`,
|
|
91
|
+
: `✗ ${local.gateway.state}: model calls fail; see nylorun local logs gateway`,
|
|
92
92
|
]);
|
|
93
93
|
rows.push([
|
|
94
94
|
"harness",
|
|
@@ -96,7 +96,7 @@ export async function doctorStack(options) {
|
|
|
96
96
|
? "- in-process (NYLORUN_HARNESS=in-process in .env)"
|
|
97
97
|
: local.harness.healthy
|
|
98
98
|
? `✓ ${local.harness.state} · remote (agent turns, MCP servers, workspaces)`
|
|
99
|
-
: `✗ ${local.harness.state}: turns do not run; see nylorun logs harness`,
|
|
99
|
+
: `✗ ${local.harness.state}: turns do not run; see nylorun local logs harness`,
|
|
100
100
|
]);
|
|
101
101
|
if (local.tenant)
|
|
102
102
|
rows.push([
|
package/dist/nylo.js
CHANGED
|
@@ -1,9 +1,25 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import "./baseline.js";
|
|
3
3
|
import { runCommand } from "./command.js";
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
import { CliError } from "./errors.js";
|
|
5
|
+
/**
|
|
6
|
+
* `nylo` became part of `nylorun`. For one release this command names the `nylorun` command that
|
|
7
|
+
* replaces each of its own and exits 2; a later release removes it.
|
|
8
|
+
*/
|
|
9
|
+
const REPLACEMENTS = {
|
|
10
|
+
status: "nylorun status",
|
|
11
|
+
reset: "nylorun tenant reset",
|
|
12
|
+
access: "nylorun tenant signing-keys list|rotate|revoke",
|
|
13
|
+
configure: "nylorun tenant models set",
|
|
14
|
+
doctor: "nylorun doctor sandbox",
|
|
15
|
+
env: 'nothing: the SDKs read the Project link themselves; for a process outside the project, "nylorun tenant keys put <id>" and the Runtime URL "nylorun status" prints',
|
|
16
|
+
};
|
|
17
|
+
function nyloMessage(argv) {
|
|
18
|
+
const replacement = REPLACEMENTS[argv[0] ?? ""];
|
|
19
|
+
return replacement
|
|
20
|
+
? `nylo is part of nylorun now: nylo ${argv[0]} is ${replacement}.`
|
|
21
|
+
: "nylo is part of nylorun now: run nylorun --help.";
|
|
22
|
+
}
|
|
6
23
|
runCommand(async () => {
|
|
7
|
-
|
|
8
|
-
await main(process.argv.slice(2));
|
|
24
|
+
throw new CliError(nyloMessage(process.argv.slice(2)), 2);
|
|
9
25
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `<Host root>/sandboxes/`: what the sandboxes service mounts read-only. `cluster.json`
|
|
3
|
-
* records the cluster `nylorun sandbox enable` installed into; `token` is the
|
|
3
|
+
* records the cluster `nylorun local sandbox enable` installed into; `token` is the
|
|
4
4
|
* ServiceAccount token (0600). Only the sandboxes container reads them: the runtime
|
|
5
5
|
* container sees an empty mount there.
|
|
6
6
|
*/
|
|
@@ -37,5 +37,5 @@ export declare function installCluster(deps: SandboxDeps, input: {
|
|
|
37
37
|
egress: number;
|
|
38
38
|
};
|
|
39
39
|
}): Promise<InstallResult>;
|
|
40
|
-
/** `nylorun sandbox <enable|disable|status>`. */
|
|
40
|
+
/** `nylorun local sandbox <enable|disable|status>`. */
|
|
41
41
|
export declare function runSandboxCommand(args: readonly string[], deps: SandboxDeps): Promise<number>;
|
package/dist/sandbox/commands.js
CHANGED
|
@@ -16,7 +16,7 @@ export const sandboxUsage = ` sandbox enable --context <name> [--tenant <name>]
|
|
|
16
16
|
stop the sandboxes service and forget the cluster
|
|
17
17
|
sandbox status [--tenant <name>] [--json]
|
|
18
18
|
the cluster, the sandboxes service's readiness and what it reports`;
|
|
19
|
-
const ENABLE_USAGE = "nylorun sandbox enable --context <name> [--tenant <name>] [--host-address <ip>] [--bind-address <ip>] [--no-pull]";
|
|
19
|
+
const ENABLE_USAGE = "nylorun local sandbox enable --context <name> [--tenant <name>] [--host-address <ip>] [--bind-address <ip>] [--no-pull]";
|
|
20
20
|
/** The default workload image (D36), pre-pulled with the Runtime image. */
|
|
21
21
|
export const DEFAULT_SANDBOX_IMAGE = "python:3.13-slim";
|
|
22
22
|
/** Preferred host ports for the Harness API, gates and egress (pods reach them). */
|
|
@@ -141,7 +141,7 @@ async function enable(deps, args) {
|
|
|
141
141
|
throw usageError(`Usage: ${ENABLE_USAGE}`);
|
|
142
142
|
const context = flags.values.get("--context");
|
|
143
143
|
if (!context)
|
|
144
|
-
throw usageError(`nylorun sandbox enable needs --context <name>: the kubeconfig context to run pods in (never the current one implicitly). Usage: ${ENABLE_USAGE}`);
|
|
144
|
+
throw usageError(`nylorun local sandbox enable needs --context <name>: the kubeconfig context to run pods in (never the current one implicitly). Usage: ${ENABLE_USAGE}`);
|
|
145
145
|
const hostAddress = flags.values.get("--host-address");
|
|
146
146
|
const bindAddress = flags.values.get("--bind-address");
|
|
147
147
|
if (hostAddress)
|
|
@@ -191,7 +191,7 @@ async function enable(deps, args) {
|
|
|
191
191
|
await restartTenant(stack, { name: tenant.name, sandboxes: settings });
|
|
192
192
|
const ready = await stack.docker.stream(tenant.compose("up", "--detach", "--wait", "--wait-timeout", "120", "sandboxes"));
|
|
193
193
|
if (ready !== 0)
|
|
194
|
-
throw new CliError(`The sandboxes service did not become ready (image ${images.sandboxes}). See "nylorun logs sandboxes" and "nylorun sandbox status".`, 7);
|
|
194
|
+
throw new CliError(`The sandboxes service did not become ready (image ${images.sandboxes}). See "nylorun local logs sandboxes" and "nylorun local sandbox status".`, 7);
|
|
195
195
|
const c = installed.cluster;
|
|
196
196
|
stack.out(`Sandboxes ${tenant.name} enabled on ${c.context} (namespace ${c.namespace}, agent-sandbox ${c.controllerVersion})`);
|
|
197
197
|
stack.out(`Pods reach ${c.hostAddress} on ports ${c.ports.harness}, ${c.ports.gates}, ${c.ports.egress}; NetworkPolicy enforced (probed ${c.networkPolicy.probedAt})`);
|
|
@@ -199,7 +199,7 @@ async function enable(deps, args) {
|
|
|
199
199
|
}
|
|
200
200
|
async function disable(deps, args) {
|
|
201
201
|
const { stack } = deps;
|
|
202
|
-
const usage = "nylorun sandbox disable [--tenant <name>] [--delete-namespace]";
|
|
202
|
+
const usage = "nylorun local sandbox disable [--tenant <name>] [--delete-namespace]";
|
|
203
203
|
const flags = parseStackFlags(args, { booleans: ["--delete-namespace"], values: ["--tenant"] }, usage);
|
|
204
204
|
if (flags.rest.length)
|
|
205
205
|
throw usageError(`Usage: ${usage}`);
|
|
@@ -229,7 +229,7 @@ async function disable(deps, args) {
|
|
|
229
229
|
const INFO_SCRIPT = "fetch(process.env.NYLORUN_SANDBOXES_URL+'/v1/info',{headers:{authorization:'Bearer '+process.env.NYLORUN_SANDBOXES_TOKEN},signal:AbortSignal.timeout(5000)}).then(async r=>{process.stdout.write(await r.text());process.exit(r.ok?0:1)},()=>process.exit(1))";
|
|
230
230
|
async function status(deps, args) {
|
|
231
231
|
const { stack } = deps;
|
|
232
|
-
const usage = "nylorun sandbox status [--tenant <name>] [--json]";
|
|
232
|
+
const usage = "nylorun local sandbox status [--tenant <name>] [--json]";
|
|
233
233
|
const flags = parseStackFlags(args, { booleans: ["--json"], values: ["--tenant"] }, usage);
|
|
234
234
|
if (flags.rest.length)
|
|
235
235
|
throw usageError(`Usage: ${usage}`);
|
|
@@ -240,7 +240,7 @@ async function status(deps, args) {
|
|
|
240
240
|
if (flags.booleans.has("--json"))
|
|
241
241
|
stack.out(JSON.stringify({ enabled: false }, null, 2));
|
|
242
242
|
else
|
|
243
|
-
stack.out(`Sandboxes are not enabled for Tenant ${tenant.name}. Run "nylorun sandbox enable --context <name>".`);
|
|
243
|
+
stack.out(`Sandboxes are not enabled for Tenant ${tenant.name}. Run "nylorun local sandbox enable --context <name>".`);
|
|
244
244
|
return 3;
|
|
245
245
|
}
|
|
246
246
|
await dockerPreflight(stack.docker);
|
|
@@ -271,7 +271,7 @@ const COMMANDS = {
|
|
|
271
271
|
disable,
|
|
272
272
|
status,
|
|
273
273
|
};
|
|
274
|
-
/** `nylorun sandbox <enable|disable|status>`. */
|
|
274
|
+
/** `nylorun local sandbox <enable|disable|status>`. */
|
|
275
275
|
export async function runSandboxCommand(args, deps) {
|
|
276
276
|
const [name, ...rest] = args;
|
|
277
277
|
const command = name === undefined ? undefined : COMMANDS[name];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* What `nylorun sandbox enable` installs into a cluster. The agent-sandbox controller is
|
|
2
|
+
* What `nylorun local sandbox enable` installs into a cluster. The agent-sandbox controller is
|
|
3
3
|
* pinned (D32, Experiment 2): v1.0.5, API agents.x-k8s.io/v1beta1, its release manifest
|
|
4
4
|
* verified by sha256 before it is applied. It is never upgraded or uninstalled here.
|
|
5
5
|
*/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
/**
|
|
3
|
-
* What `nylorun sandbox enable` installs into a cluster. The agent-sandbox controller is
|
|
3
|
+
* What `nylorun local sandbox enable` installs into a cluster. The agent-sandbox controller is
|
|
4
4
|
* pinned (D32, Experiment 2): v1.0.5, API agents.x-k8s.io/v1beta1, its release manifest
|
|
5
5
|
* verified by sha256 before it is applied. It is never upgraded or uninstalled here.
|
|
6
6
|
*/
|
package/dist/sandbox/probe.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { DockerRunner } from "../stack/docker.js";
|
|
|
2
2
|
import type { PortProbe } from "../stack/ports.js";
|
|
3
3
|
import type { Kube } from "./kubectl.js";
|
|
4
4
|
/**
|
|
5
|
-
* The NetworkPolicy probe `nylorun sandbox enable` runs before it trusts a cluster (D32), in
|
|
5
|
+
* The NetworkPolicy probe `nylorun local sandbox enable` runs before it trusts a cluster (D32), in
|
|
6
6
|
* a throwaway namespace `nylorun-sbx-probe-<random>`:
|
|
7
7
|
*
|
|
8
8
|
* - a `control` pod (no policy) must reach a `peer` pod and the allowed host port, which
|
package/dist/stack/commands.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import type { PortProbe } from "./ports.js";
|
|
|
5
5
|
import { type FetchLike } from "./studio-login.js";
|
|
6
6
|
import { type OperateEndpoint } from "./operator-keys.js";
|
|
7
7
|
export declare const STACK_SERVICES: readonly ["postgres", "restate", "s2-lite", "rustfs", "gateway", "runtime", "harness", "studio"];
|
|
8
|
-
export declare const stackUsage:
|
|
8
|
+
export declare const stackUsage = " up|start [--tenant <name>] [--no-link] [--no-studio] [--allow-downgrade] [--studio-embed-origin <origin>]... [--studio-embed-origin-reset] [--restate-ui]\n start the project's Tenant, creating it and the Project link (.nylorun/link.json,\n credentials.json) on the first run; print the Runtime and Studio URLs (it opens no\n browser). --tenant attaches to (or creates) a named Tenant; --no-link\n starts the default Tenant (or --tenant's) without linking the current directory;\n --restate-ui (or NYLORUN_RESTATE_UI=1) publishes Restate's UI on loopback for debugging\n down|stop [--tenant <name> | --all] stop the Tenant's containers (--all: every Tenant's); keep volumes\n status [--tenant <name>] [--json] the Tenant, its id, services, endpoints and Runtime health\n studio [--tenant <name>] [--no-open]\n sign a browser in to Studio on the Tenant; --no-open prints the login URL; start the Tenant if it is stopped";
|
|
9
9
|
export interface StackDeps {
|
|
10
10
|
/** Environment snapshot (NYLORUN_HOME, NYLORUN_TENANT, image overrides, NYLORUN_COMPOSE_PROJECT). */
|
|
11
11
|
env: Readonly<Record<string, string | undefined>>;
|
|
@@ -22,6 +22,11 @@ export interface StackDeps {
|
|
|
22
22
|
confirm?(question: string): Promise<boolean>;
|
|
23
23
|
/** A developer is at a terminal. */
|
|
24
24
|
interactive?: boolean;
|
|
25
|
+
/** Standard input, for a body or a secret piped in; undefined when there is none. */
|
|
26
|
+
stdin?: {
|
|
27
|
+
isTTY: boolean;
|
|
28
|
+
text(): Promise<string>;
|
|
29
|
+
};
|
|
25
30
|
/** Open `url` in a browser; false when no browser could be started. */
|
|
26
31
|
openBrowser(url: string): Promise<boolean>;
|
|
27
32
|
/** Is this process id alive? (launcher-managed Runtime detection) */
|
|
@@ -137,7 +142,7 @@ export interface StackEndpoints {
|
|
|
137
142
|
/** This call started the Runtime (it was not running before). */
|
|
138
143
|
started: boolean;
|
|
139
144
|
}
|
|
140
|
-
/** The running Tenant's APIs and their keys (`nylorun sandbox`). */
|
|
145
|
+
/** The running Tenant's APIs and their keys (`nylorun local sandbox`). */
|
|
141
146
|
export interface TenantApi {
|
|
142
147
|
/** The Tenant's name. */
|
|
143
148
|
name: string;
|
|
@@ -179,7 +184,7 @@ export declare function ensureStack(deps: StackDeps, options: {
|
|
|
179
184
|
studio: boolean;
|
|
180
185
|
name?: string;
|
|
181
186
|
}): Promise<StackEndpoints>;
|
|
182
|
-
/** A started Tenant as `nylorun sandbox` sees it. */
|
|
187
|
+
/** A started Tenant as `nylorun local sandbox` sees it. */
|
|
183
188
|
export interface SelectedTenant {
|
|
184
189
|
name: string;
|
|
185
190
|
paths: StackPaths;
|
|
@@ -187,7 +192,7 @@ export interface SelectedTenant {
|
|
|
187
192
|
/** `docker compose` arguments for this Tenant's project and files. */
|
|
188
193
|
compose(...args: string[]): string[];
|
|
189
194
|
}
|
|
190
|
-
/** The Tenant `nylorun sandbox` acts on; it must have been started once. */
|
|
195
|
+
/** The Tenant `nylorun local sandbox` acts on; it must have been started once. */
|
|
191
196
|
export declare function selectTenant(deps: StackDeps, options?: {
|
|
192
197
|
name?: string;
|
|
193
198
|
}): Promise<SelectedTenant>;
|
package/dist/stack/commands.js
CHANGED
|
@@ -38,13 +38,8 @@ export const stackUsage = ` up|start [--tenant <name>] [--no-link] [--no-studio
|
|
|
38
38
|
--restate-ui (or NYLORUN_RESTATE_UI=1) publishes Restate's UI on loopback for debugging
|
|
39
39
|
down|stop [--tenant <name> | --all] stop the Tenant's containers (--all: every Tenant's); keep volumes
|
|
40
40
|
status [--tenant <name>] [--json] the Tenant, its id, services, endpoints and Runtime health
|
|
41
|
-
logs [service] [--tenant <name>] [-f] [--tail <n>]
|
|
42
|
-
container logs (${STACK_SERVICES.join(", ")})
|
|
43
41
|
studio [--tenant <name>] [--no-open]
|
|
44
|
-
sign a browser in to Studio on the Tenant; --no-open prints the login URL; start the Tenant if it is stopped
|
|
45
|
-
reset [--tenant <name>] [--yes] delete the Tenant's data (volumes, tenant/ and vault key); the next start creates it anew
|
|
46
|
-
ls [--json] the Tenants on this machine, with their memory in use
|
|
47
|
-
delete <tenant> --yes remove a Tenant: containers, volumes and its Host root, with the vault key (KEK)`;
|
|
42
|
+
sign a browser in to Studio on the Tenant; --no-open prints the login URL; start the Tenant if it is stopped`;
|
|
48
43
|
const usageError = (message) => new CliError(message, 2);
|
|
49
44
|
/** The Compose project of Tenant `name`: `nylorun-<name>`, or `NYLORUN_COMPOSE_PROJECT`. */
|
|
50
45
|
export function stackProject(env, name) {
|
|
@@ -166,7 +161,8 @@ export function parseStackFlags(args, allowed, usage) {
|
|
|
166
161
|
for (let index = 0; index < args.length; index += 1) {
|
|
167
162
|
const raw = args[index];
|
|
168
163
|
const arg = allowed.aliases?.[raw] ?? raw;
|
|
169
|
-
|
|
164
|
+
// `-` alone is an argument: standard input.
|
|
165
|
+
if (arg === "-" || !arg.startsWith("-")) {
|
|
170
166
|
rest.push(arg);
|
|
171
167
|
continue;
|
|
172
168
|
}
|
|
@@ -224,7 +220,7 @@ async function waitForHealth(ctx, runtimeUrl, hostId) {
|
|
|
224
220
|
return health;
|
|
225
221
|
}
|
|
226
222
|
if (Date.now() > deadline)
|
|
227
|
-
throw new CliError(`The Runtime did not answer ${runtimeUrl}/health. See "nylorun logs runtime".`, 7);
|
|
223
|
+
throw new CliError(`The Runtime did not answer ${runtimeUrl}/health. See "nylorun local logs runtime".`, 7);
|
|
228
224
|
await sleep(ctx.deps.pollMs ?? 500);
|
|
229
225
|
}
|
|
230
226
|
}
|
|
@@ -284,7 +280,7 @@ function tenantCauseMessage(ctx, tenant) {
|
|
|
284
280
|
? ` This nylorun pins Runtime ${ctx.deps.runtimeVersion}, older than the Tenant's database: update nylorun (npx nylorun@latest start).`
|
|
285
281
|
: "";
|
|
286
282
|
const message = tenant.message ? `: ${tenant.message.replace(/\.?$/, ".")}` : ".";
|
|
287
|
-
return `Tenant ${ctx.name} is unavailable (${tenant.cause})${message}${hint} See "nylorun logs runtime".`;
|
|
283
|
+
return `Tenant ${ctx.name} is unavailable (${tenant.cause})${message}${hint} See "nylorun local logs runtime".`;
|
|
288
284
|
}
|
|
289
285
|
/**
|
|
290
286
|
* Wait until the Tenant is open (`/ready`'s `tenant` check): the Runtime creates it on the
|
|
@@ -304,7 +300,7 @@ async function waitForTenant(ctx, runtimeUrl) {
|
|
|
304
300
|
if (!open && tenant?.cause)
|
|
305
301
|
throw new CliError(tenantCauseMessage(ctx, tenant), 7);
|
|
306
302
|
if (late)
|
|
307
|
-
throw new CliError(`Tenant ${ctx.name} did not open (${runtimeUrl}/ready: ${open ? "open, but nylorun-operate status did not answer" : "not open"})${tenant?.message ? `: ${tenant.message.replace(/\.$/, "")}` : ""}. See "nylorun status" and "nylorun logs runtime".`, 7);
|
|
303
|
+
throw new CliError(`Tenant ${ctx.name} did not open (${runtimeUrl}/ready: ${open ? "open, but nylorun-operate status did not answer" : "not open"})${tenant?.message ? `: ${tenant.message.replace(/\.$/, "")}` : ""}. See "nylorun status" and "nylorun local logs runtime".`, 7);
|
|
308
304
|
}
|
|
309
305
|
await sleep(ctx.deps.pollMs ?? 500);
|
|
310
306
|
}
|
|
@@ -394,7 +390,7 @@ async function bringUp(ctx, options) {
|
|
|
394
390
|
await refuseDowngrade(ctx, options.allowDowngrade ?? false);
|
|
395
391
|
const legacy = await oldVolumes(deps.docker, ctx.project);
|
|
396
392
|
if (legacy.old.length && !legacy.current)
|
|
397
|
-
throw new CliError(`Tenant ${ctx.name} was created by nylorun 0.5; its data is in the old volumes ${legacy.old.join(", ")}. Run "nylorun reset --tenant ${ctx.name}" to start it fresh; that also removes the old volumes (or drop them yourself with "docker volume rm ${legacy.old.join(" ")}").`, 3);
|
|
393
|
+
throw new CliError(`Tenant ${ctx.name} was created by nylorun 0.5; its data is in the old volumes ${legacy.old.join(", ")}. Run "nylorun local reset --tenant ${ctx.name}" to start it fresh; that also removes the old volumes (or drop them yourself with "docker volume rm ${legacy.old.join(" ")}").`, 3);
|
|
398
394
|
const base = nylorunRoot(deps);
|
|
399
395
|
const telemetry = await readTelemetry(base);
|
|
400
396
|
const analytics = telemetryDecision(deps.env, telemetry).enabled;
|
|
@@ -437,21 +433,21 @@ async function bringUp(ctx, options) {
|
|
|
437
433
|
const tenant = await operateStatus(ctx);
|
|
438
434
|
if (tenant?.cause)
|
|
439
435
|
throw new CliError(tenantCauseMessage(ctx, tenant), 7);
|
|
440
|
-
throw new CliError(`docker compose up failed (exit ${up}). See "nylorun logs runtime", "nylorun logs gateway", "nylorun logs harness" and "nylorun status".`, 7);
|
|
436
|
+
throw new CliError(`docker compose up failed (exit ${up}). See "nylorun local logs runtime", "nylorun local logs gateway", "nylorun local logs harness" and "nylorun status".`, 7);
|
|
441
437
|
}
|
|
442
438
|
await waitForHealth(ctx, runtimeUrl, prepared.host.hostId);
|
|
443
439
|
// Without --wait: a cluster that is down must not fail the start; sessions refuse pods.
|
|
444
440
|
if (prepared.env.sandboxes) {
|
|
445
441
|
const sandboxes = await deps.docker.stream(composeArgs(ctx, "up", "--detach", "sandboxes"));
|
|
446
442
|
if (sandboxes !== 0)
|
|
447
|
-
deps.err(`Warning: the sandboxes service did not start. See "nylorun logs sandboxes".`);
|
|
443
|
+
deps.err(`Warning: the sandboxes service did not start. See "nylorun local logs sandboxes".`);
|
|
448
444
|
}
|
|
449
445
|
let studioStarted = false;
|
|
450
446
|
if (options.studio) {
|
|
451
447
|
const studio = await deps.docker.stream(composeArgs(ctx, "up", "--detach", "--wait", "--wait-timeout", "120", "studio"));
|
|
452
448
|
studioStarted = studio === 0;
|
|
453
449
|
if (!studioStarted)
|
|
454
|
-
deps.err(`Warning: Studio did not start (image ${prepared.env.studioImage}). The Runtime is up; see "nylorun logs studio".`);
|
|
450
|
+
deps.err(`Warning: Studio did not start (image ${prepared.env.studioImage}). The Runtime is up; see "nylorun local logs studio".`);
|
|
455
451
|
}
|
|
456
452
|
return {
|
|
457
453
|
runtimeUrl,
|
|
@@ -561,7 +557,7 @@ async function linkProject(ctx, started, tenantId) {
|
|
|
561
557
|
deps.err(`Seeded the Tenant from .env: ${set.join(", ")}.`);
|
|
562
558
|
}
|
|
563
559
|
catch (error) {
|
|
564
|
-
deps.err(`Warning: could not seed the Tenant from .env (${error instanceof Error ? error.message : String(error)}). Set the model in Studio or with "npx
|
|
560
|
+
deps.err(`Warning: could not seed the Tenant from .env (${error instanceof Error ? error.message : String(error)}). Set the model in Studio or with "npx nylorun tenant models set".`);
|
|
565
561
|
}
|
|
566
562
|
}
|
|
567
563
|
const START_USAGE = "nylorun start [--tenant <name>] [--no-link] [--no-studio] [--allow-downgrade] [--studio-embed-origin <origin>]... [--studio-embed-origin-reset] [--restate-ui]";
|
|
@@ -777,14 +773,14 @@ async function status(deps, args) {
|
|
|
777
773
|
out(`Embeds ${result.studio.embedOrigins.join(" ")} (may show Studio in a frame)`);
|
|
778
774
|
out(`Gateway ${result.gateway.state} (the Model Gate; model calls fail while it is down)`);
|
|
779
775
|
out(result.harness.mode === "remote"
|
|
780
|
-
? `Harness ${result.harness.state}, remote${result.harness.connected === undefined ? "" : `, ${result.harness.connected} connected`} (agent turns, MCP servers and workspaces; "nylorun logs harness")`
|
|
776
|
+
? `Harness ${result.harness.state}, remote${result.harness.connected === undefined ? "" : `, ${result.harness.connected} connected`} (agent turns, MCP servers and workspaces; "nylorun local logs harness")`
|
|
781
777
|
: `Harness in-process (NYLORUN_HARNESS=in-process in .env: turns run in the runtime container)`);
|
|
782
778
|
out(result.restate.url
|
|
783
779
|
? `Restate UI ${result.restate.url} (unauthenticated; published by --restate-ui)`
|
|
784
780
|
: `Restate UI not published (nylorun start --restate-ui)`);
|
|
785
781
|
const sandboxes = result.services.find((s) => s.service === "sandboxes");
|
|
786
782
|
if (sandboxes)
|
|
787
|
-
out(`Sandboxes ${[sandboxes.state, sandboxes.health].filter(Boolean).join(", ")} (see "nylorun sandbox status")`);
|
|
783
|
+
out(`Sandboxes ${[sandboxes.state, sandboxes.health].filter(Boolean).join(", ")} (see "nylorun local sandbox status")`);
|
|
788
784
|
out(`Services ${STACK_SERVICES.map((name) => {
|
|
789
785
|
const service = result.services.find((s) => s.service === name);
|
|
790
786
|
const state = service
|
|
@@ -796,7 +792,7 @@ async function status(deps, args) {
|
|
|
796
792
|
return result.runtime.healthy ? 0 : 3;
|
|
797
793
|
}
|
|
798
794
|
async function logs(deps, args) {
|
|
799
|
-
const usage = `nylorun logs [${STACK_SERVICES.join("|")}] [--tenant <name>] [-f] [--tail <n>]`;
|
|
795
|
+
const usage = `nylorun local logs [${STACK_SERVICES.join("|")}] [--tenant <name>] [-f] [--tail <n>]`;
|
|
800
796
|
const flags = parseStackFlags(args, { booleans: ["--follow"], values: ["--tail", "--tenant"], aliases: { "-f": "--follow" } }, usage);
|
|
801
797
|
if (flags.rest.length > 1)
|
|
802
798
|
throw usageError(`Usage: ${usage}`);
|
|
@@ -812,7 +808,7 @@ async function logs(deps, args) {
|
|
|
812
808
|
return await deps.docker.stream(composeArgs(ctx, "logs", ...(flags.booleans.has("--follow") ? ["--follow"] : []), ...(tail !== undefined ? ["--tail", tail] : []), ...(service ? [service] : [])));
|
|
813
809
|
}
|
|
814
810
|
async function reset(deps, args) {
|
|
815
|
-
const usage = "nylorun reset [--tenant <name>] [--yes]";
|
|
811
|
+
const usage = "nylorun local reset [--tenant <name>] [--yes]";
|
|
816
812
|
const flags = parseStackFlags(args, { booleans: ["--yes"], values: ["--tenant"], aliases: { "-y": "--yes" } }, usage);
|
|
817
813
|
if (flags.rest.length)
|
|
818
814
|
throw usageError(`Usage: ${usage}`);
|
|
@@ -821,7 +817,7 @@ async function reset(deps, args) {
|
|
|
821
817
|
if (!flags.booleans.has("--yes")) {
|
|
822
818
|
const question = `Delete Tenant ${ctx.name}'s volumes (Compose project ${ctx.project}), its Tenant directory ${paths.tenant} and its vault key ${paths.vaultKey}? Its data is lost, and the next start creates the Tenant anew, with a new id. [y/N] `;
|
|
823
819
|
if (!deps.confirm)
|
|
824
|
-
throw usageError(`nylorun reset deletes all of Tenant ${ctx.name}'s data; pass --yes to confirm when not in a terminal.`);
|
|
820
|
+
throw usageError(`nylorun local reset deletes all of Tenant ${ctx.name}'s data; pass --yes to confirm when not in a terminal.`);
|
|
825
821
|
if (!(await deps.confirm(question))) {
|
|
826
822
|
deps.err("Reset cancelled.");
|
|
827
823
|
return 1;
|
|
@@ -856,7 +852,7 @@ async function composeProjects(docker) {
|
|
|
856
852
|
}
|
|
857
853
|
}
|
|
858
854
|
async function ls(deps, args) {
|
|
859
|
-
const usage = "nylorun ls [--json]";
|
|
855
|
+
const usage = "nylorun local ls [--json]";
|
|
860
856
|
const flags = parseStackFlags(args, { booleans: ["--json"] }, usage);
|
|
861
857
|
if (flags.rest.length)
|
|
862
858
|
throw usageError(`Usage: ${usage}`);
|
|
@@ -912,7 +908,7 @@ async function ls(deps, args) {
|
|
|
912
908
|
return 0;
|
|
913
909
|
}
|
|
914
910
|
async function deleteStack(deps, args) {
|
|
915
|
-
const usage = "nylorun delete <tenant> --yes";
|
|
911
|
+
const usage = "nylorun local delete <tenant> --yes";
|
|
916
912
|
const flags = parseStackFlags(args, { booleans: ["--yes"], aliases: { "-y": "--yes" } }, usage);
|
|
917
913
|
const [name, ...extra] = flags.rest;
|
|
918
914
|
if (name === undefined || extra.length)
|
|
@@ -921,9 +917,9 @@ async function deleteStack(deps, args) {
|
|
|
921
917
|
const base = nylorunRoot(deps);
|
|
922
918
|
const ctx = { deps, project: stackProject(deps.env, name), paths: stackPaths(tenantRoot(base, name)) };
|
|
923
919
|
if (!existsSync(ctx.paths.root))
|
|
924
|
-
throw new CliError(`No Tenant ${name} under ${tenantsDir(base)}. See "nylorun ls".`, 3);
|
|
920
|
+
throw new CliError(`No Tenant ${name} under ${tenantsDir(base)}. See "nylorun local ls".`, 3);
|
|
925
921
|
if (!flags.booleans.has("--yes"))
|
|
926
|
-
throw usageError(`nylorun delete removes Tenant ${name}: its containers, volumes and Host root ${ctx.paths.root}, with its vault key (KEK) and all its data. This cannot be undone; pass --yes to confirm.`);
|
|
922
|
+
throw usageError(`nylorun local delete removes Tenant ${name}: its containers, volumes and Host root ${ctx.paths.root}, with its vault key (KEK) and all its data. This cannot be undone; pass --yes to confirm.`);
|
|
927
923
|
await dockerPreflight(deps.docker);
|
|
928
924
|
const files = existsSync(ctx.paths.compose) && existsSync(ctx.paths.env);
|
|
929
925
|
await composeDown(ctx, files
|
|
@@ -1051,7 +1047,7 @@ export async function runningTenantApi(deps, options = {}) {
|
|
|
1051
1047
|
export async function ensureStack(deps, options) {
|
|
1052
1048
|
return await ensureSelected(await selectStack(deps, options.name === undefined ? {} : { name: options.name }), options);
|
|
1053
1049
|
}
|
|
1054
|
-
/** The Tenant `nylorun sandbox` acts on; it must have been started once. */
|
|
1050
|
+
/** The Tenant `nylorun local sandbox` acts on; it must have been started once. */
|
|
1055
1051
|
export async function selectTenant(deps, options = {}) {
|
|
1056
1052
|
await tidyMachine(deps);
|
|
1057
1053
|
const ctx = await selectStack(deps, options);
|
|
@@ -1115,7 +1111,7 @@ async function studio(deps, args, options = {}) {
|
|
|
1115
1111
|
if (running.started)
|
|
1116
1112
|
deps.out(`Runtime ${running.runtimeUrl}`);
|
|
1117
1113
|
if (!running.studioUp)
|
|
1118
|
-
throw new CliError(`Studio did not start. See "nylorun logs studio".`, 7);
|
|
1114
|
+
throw new CliError(`Studio did not start. See "nylorun local logs studio".`, 7);
|
|
1119
1115
|
// Studio serves the one Tenant; the link's Tenant id stands in while it is opening.
|
|
1120
1116
|
let next = options.next;
|
|
1121
1117
|
if (next === undefined) {
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
* gateway receive it (NYLORUN_OBJECT_STORE_*). The runtime creates the bucket at boot and
|
|
42
42
|
* reaches the store through its `s3` BlobStore.
|
|
43
43
|
*
|
|
44
|
-
* With `sandboxes` (after `nylorun sandbox enable`, F7.2) the `sandboxes` service runs the
|
|
44
|
+
* With `sandboxes` (after `nylorun local sandbox enable`, F7.2) the `sandboxes` service runs the
|
|
45
45
|
* agent-sandbox driver: the only container holding the cluster credentials
|
|
46
46
|
* (`<Host root>/sandboxes`, read-only), not published, reached by the runtime alone with
|
|
47
47
|
* NYLORUN_SANDBOXES_TOKEN. The runtime gets an empty read-only mount over that directory.
|