@intentic/machine 1.233.0
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 +72 -0
- package/dist/app.d.ts +2 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +12 -0
- package/dist/app.js.map +1 -0
- package/dist/autostart.d.ts +3 -0
- package/dist/autostart.d.ts.map +1 -0
- package/dist/autostart.js +13 -0
- package/dist/autostart.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +5 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands.d.ts +11 -0
- package/dist/commands.d.ts.map +1 -0
- package/dist/commands.js +91 -0
- package/dist/commands.js.map +1 -0
- package/dist/computer/audit.d.ts +6 -0
- package/dist/computer/audit.d.ts.map +1 -0
- package/dist/computer/audit.js +12 -0
- package/dist/computer/audit.js.map +1 -0
- package/dist/computer/commands.d.ts +8 -0
- package/dist/computer/commands.d.ts.map +1 -0
- package/dist/computer/commands.js +113 -0
- package/dist/computer/commands.js.map +1 -0
- package/dist/computer/config.d.ts +19 -0
- package/dist/computer/config.d.ts.map +1 -0
- package/dist/computer/config.js +31 -0
- package/dist/computer/config.js.map +1 -0
- package/dist/computer/connection.d.ts +8 -0
- package/dist/computer/connection.d.ts.map +1 -0
- package/dist/computer/connection.js +63 -0
- package/dist/computer/connection.js.map +1 -0
- package/dist/computer/mcp.d.ts +3 -0
- package/dist/computer/mcp.d.ts.map +1 -0
- package/dist/computer/mcp.js +312 -0
- package/dist/computer/mcp.js.map +1 -0
- package/dist/computer/policy.d.ts +8 -0
- package/dist/computer/policy.d.ts.map +1 -0
- package/dist/computer/policy.js +42 -0
- package/dist/computer/policy.js.map +1 -0
- package/dist/computer/router.d.ts +93 -0
- package/dist/computer/router.d.ts.map +1 -0
- package/dist/computer/router.js +79 -0
- package/dist/computer/router.js.map +1 -0
- package/dist/computer/tools/apps.d.ts +9 -0
- package/dist/computer/tools/apps.d.ts.map +1 -0
- package/dist/computer/tools/apps.js +41 -0
- package/dist/computer/tools/apps.js.map +1 -0
- package/dist/computer/tools/browser.d.ts +11 -0
- package/dist/computer/tools/browser.d.ts.map +1 -0
- package/dist/computer/tools/browser.js +63 -0
- package/dist/computer/tools/browser.js.map +1 -0
- package/dist/computer/tools/computer.d.ts +16 -0
- package/dist/computer/tools/computer.d.ts.map +1 -0
- package/dist/computer/tools/computer.js +80 -0
- package/dist/computer/tools/computer.js.map +1 -0
- package/dist/computer/tools/describe.d.ts +4 -0
- package/dist/computer/tools/describe.d.ts.map +1 -0
- package/dist/computer/tools/describe.js +37 -0
- package/dist/computer/tools/describe.js.map +1 -0
- package/dist/computer/tools/files.d.ts +12 -0
- package/dist/computer/tools/files.d.ts.map +1 -0
- package/dist/computer/tools/files.js +58 -0
- package/dist/computer/tools/files.js.map +1 -0
- package/dist/computer/tools/sandboxes.d.ts +45 -0
- package/dist/computer/tools/sandboxes.d.ts.map +1 -0
- package/dist/computer/tools/sandboxes.js +230 -0
- package/dist/computer/tools/sandboxes.js.map +1 -0
- package/dist/computer/tools/shell.d.ts +22 -0
- package/dist/computer/tools/shell.d.ts.map +1 -0
- package/dist/computer/tools/shell.js +78 -0
- package/dist/computer/tools/shell.js.map +1 -0
- package/dist/config.d.ts +4 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +7 -0
- package/dist/config.js.map +1 -0
- package/dist/resident.d.ts +8 -0
- package/dist/resident.d.ts.map +1 -0
- package/dist/resident.js +92 -0
- package/dist/resident.js.map +1 -0
- package/dist/status.d.ts +21 -0
- package/dist/status.d.ts.map +1 -0
- package/dist/status.js +123 -0
- package/dist/status.js.map +1 -0
- package/dist/sync/commands.d.ts +20 -0
- package/dist/sync/commands.d.ts.map +1 -0
- package/dist/sync/commands.js +244 -0
- package/dist/sync/commands.js.map +1 -0
- package/dist/sync/config.d.ts +41 -0
- package/dist/sync/config.d.ts.map +1 -0
- package/dist/sync/config.js +35 -0
- package/dist/sync/config.js.map +1 -0
- package/dist/sync/exec.d.ts +10 -0
- package/dist/sync/exec.d.ts.map +1 -0
- package/dist/sync/exec.js +26 -0
- package/dist/sync/exec.js.map +1 -0
- package/dist/sync/git-bridge.d.ts +11 -0
- package/dist/sync/git-bridge.d.ts.map +1 -0
- package/dist/sync/git-bridge.js +122 -0
- package/dist/sync/git-bridge.js.map +1 -0
- package/dist/sync/mirror.d.ts +19 -0
- package/dist/sync/mirror.d.ts.map +1 -0
- package/dist/sync/mirror.js +310 -0
- package/dist/sync/mirror.js.map +1 -0
- package/dist/sync/mutagen.d.ts +68 -0
- package/dist/sync/mutagen.d.ts.map +1 -0
- package/dist/sync/mutagen.js +289 -0
- package/dist/sync/mutagen.js.map +1 -0
- package/dist/sync/report.d.ts +6 -0
- package/dist/sync/report.d.ts.map +1 -0
- package/dist/sync/report.js +66 -0
- package/dist/sync/report.js.map +1 -0
- package/dist/sync/ssh.d.ts +29 -0
- package/dist/sync/ssh.d.ts.map +1 -0
- package/dist/sync/ssh.js +165 -0
- package/dist/sync/ssh.js.map +1 -0
- package/dist/sync/tunnel.d.ts +22 -0
- package/dist/sync/tunnel.d.ts.map +1 -0
- package/dist/sync/tunnel.js +160 -0
- package/dist/sync/tunnel.js.map +1 -0
- package/dist/upgrade.d.ts +36 -0
- package/dist/upgrade.d.ts.map +1 -0
- package/dist/upgrade.js +95 -0
- package/dist/upgrade.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +2 -0
- package/dist/version.js.map +1 -0
- package/package.json +49 -0
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import { execFile, spawn } from "node:child_process";
|
|
2
|
+
import { mkdtemp, rm, writeFile } from "node:fs/promises";
|
|
3
|
+
import { homedir, tmpdir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { promisify } from "node:util";
|
|
6
|
+
import { z } from "zod";
|
|
7
|
+
import { assertScope } from "../policy.js";
|
|
8
|
+
const exec = promisify(execFile);
|
|
9
|
+
const DOCKER_TIMEOUT_MS = 120_000;
|
|
10
|
+
const PREFIX = "intentic-sandbox-";
|
|
11
|
+
const TUNNEL_PREFIX = "intentic-sandbox-tunnel-";
|
|
12
|
+
export const rowsFrom = (stdout) => stdout
|
|
13
|
+
.split(/\r?\n/)
|
|
14
|
+
.map((line) => line.trim())
|
|
15
|
+
.filter((line) => line.startsWith("{"))
|
|
16
|
+
.flatMap((line) => {
|
|
17
|
+
try {
|
|
18
|
+
const parsed = JSON.parse(line);
|
|
19
|
+
return typeof parsed.Names === "string" ? [{ names: parsed.Names, state: String(parsed.State), image: String(parsed.Image) }] : [];
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return [];
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
export const sandboxesFrom = (rows) => {
|
|
26
|
+
const isSidecar = (name) => {
|
|
27
|
+
const slug = name.startsWith(TUNNEL_PREFIX) ? name.slice(TUNNEL_PREFIX.length) : undefined;
|
|
28
|
+
return slug !== undefined && rows.some((row) => row.names === `${PREFIX}${slug}`);
|
|
29
|
+
};
|
|
30
|
+
return rows
|
|
31
|
+
.filter((row) => !isSidecar(row.names))
|
|
32
|
+
.map((row) => {
|
|
33
|
+
const slug = row.names.slice(PREFIX.length);
|
|
34
|
+
const tunnel = rows.find((candidate) => candidate.names === `${TUNNEL_PREFIX}${slug}`);
|
|
35
|
+
const sandbox = { slug, container: row.names, running: row.state === "running", image: row.image };
|
|
36
|
+
if (tunnel !== undefined) {
|
|
37
|
+
sandbox.tunnelRunning = tunnel.state === "running";
|
|
38
|
+
}
|
|
39
|
+
return sandbox;
|
|
40
|
+
});
|
|
41
|
+
};
|
|
42
|
+
const docker = async (args) => {
|
|
43
|
+
const { stdout } = await exec("docker", [...args], { timeout: DOCKER_TIMEOUT_MS, windowsHide: true }).catch((error) => {
|
|
44
|
+
if (error.code === "ENOENT") {
|
|
45
|
+
throw new Error("This computer has no docker command, so no Intentic sandboxes can run here.");
|
|
46
|
+
}
|
|
47
|
+
throw error;
|
|
48
|
+
});
|
|
49
|
+
return stdout;
|
|
50
|
+
};
|
|
51
|
+
const fleet = async () => sandboxesFrom(rowsFrom(await docker(["ps", "-a", "--filter", `name=^${PREFIX}`, "--format", "{{json .}}"])));
|
|
52
|
+
export const listSandboxes = async (scopes) => {
|
|
53
|
+
if (scopes.shell !== "on") {
|
|
54
|
+
assertScope(scopes, "sandboxes");
|
|
55
|
+
}
|
|
56
|
+
return JSON.stringify(await fleet(), undefined, 2);
|
|
57
|
+
};
|
|
58
|
+
export const SandboxOpSchema = z.enum(["start", "stop", "restart"]);
|
|
59
|
+
const find = async (slug) => {
|
|
60
|
+
const boxes = await fleet();
|
|
61
|
+
const target = boxes.find((box) => box.slug === slug);
|
|
62
|
+
if (target !== undefined) {
|
|
63
|
+
return target;
|
|
64
|
+
}
|
|
65
|
+
const known = boxes.map((box) => box.slug).join(", ");
|
|
66
|
+
throw new Error(`No sandbox "${slug}" on this computer. ${known === "" ? "It runs none." : `It has: ${known}.`}`);
|
|
67
|
+
};
|
|
68
|
+
export const manageSandbox = async (op, slug, scopes) => {
|
|
69
|
+
assertScope(scopes, "sandboxes");
|
|
70
|
+
const target = await find(slug);
|
|
71
|
+
const sidecar = target.tunnelRunning === undefined ? [] : [`${TUNNEL_PREFIX}${slug}`];
|
|
72
|
+
await docker([op, ...(op === "stop" ? [...sidecar, target.container] : [target.container, ...sidecar])]);
|
|
73
|
+
const verb = { start: "Started", stop: "Stopped", restart: "Restarted" }[op];
|
|
74
|
+
return `${verb} sandbox "${slug}"${sidecar.length === 0 ? "" : " and its tunnel"}.`;
|
|
75
|
+
};
|
|
76
|
+
export const SandboxSwapSchema = z.enum(["prepare", "update", "rebuild", "rollback"]);
|
|
77
|
+
export const icCandidates = (platform, home) => {
|
|
78
|
+
if (platform === "win32") {
|
|
79
|
+
return [...(home === undefined ? [] : [`${home}\\.intentic\\ic\\bin\\ic.exe`]), "ic.exe"];
|
|
80
|
+
}
|
|
81
|
+
return [...(home === undefined ? [] : [`${home}/.intentic/ic/bin/ic`]), "/usr/local/bin/ic", "ic"];
|
|
82
|
+
};
|
|
83
|
+
export const icSwapArgs = (swap, slug, hash) => {
|
|
84
|
+
if (swap === "rebuild") {
|
|
85
|
+
if (hash === undefined || hash === "") {
|
|
86
|
+
throw new Error(`"hash" is required to rebuild: it is the digest of the overlay the owner approved.`);
|
|
87
|
+
}
|
|
88
|
+
return ["sandbox", "rebuild", slug, hash];
|
|
89
|
+
}
|
|
90
|
+
return ["sandbox", swap, slug];
|
|
91
|
+
};
|
|
92
|
+
export const icRemoveArgs = (slug) => ["sandbox", "remove", slug, "-y"];
|
|
93
|
+
export const icRunnerArgs = (op, name, parentUrl, pair, shape = {}) => {
|
|
94
|
+
if (op === "runner-remove") {
|
|
95
|
+
return ["runner", "remove", name, "-y"];
|
|
96
|
+
}
|
|
97
|
+
if (parentUrl === undefined || parentUrl === "" || pair === undefined || pair === "") {
|
|
98
|
+
throw new Error(`starting a runner needs the parent sandbox's address and a pairing, and this request carried ${parentUrl ? "no pairing" : "neither"}.`);
|
|
99
|
+
}
|
|
100
|
+
if ((shape.overlayFile === undefined) !== (shape.environmentHash === undefined)) {
|
|
101
|
+
throw new Error(`an overlay travels with the hash that pins it, and this request carried ${shape.overlayFile === undefined ? "only the hash" : "only the overlay"}.`);
|
|
102
|
+
}
|
|
103
|
+
return [
|
|
104
|
+
"runner",
|
|
105
|
+
"up",
|
|
106
|
+
parentUrl,
|
|
107
|
+
"--pair",
|
|
108
|
+
pair,
|
|
109
|
+
"--name",
|
|
110
|
+
name,
|
|
111
|
+
...(shape.definitionFile === undefined ? [] : ["--definition-file", shape.definitionFile]),
|
|
112
|
+
...(shape.overlayFile === undefined || shape.environmentHash === undefined ? [] : ["--overlay-file", shape.overlayFile, "--environment-hash", shape.environmentHash]),
|
|
113
|
+
];
|
|
114
|
+
};
|
|
115
|
+
export const runnerFlow = async (op, name, parentUrl, pair, shape, scopes, onLine) => {
|
|
116
|
+
assertScope(scopes, "sandboxes");
|
|
117
|
+
const dir = op === "runner-up" && (shape.definition !== undefined || shape.overlay !== undefined) ? await mkdtemp(join(tmpdir(), "intentic-runner-")) : undefined;
|
|
118
|
+
try {
|
|
119
|
+
const withDefinition = dir !== undefined && shape.definition !== undefined;
|
|
120
|
+
const withOverlay = dir !== undefined && shape.overlay !== undefined;
|
|
121
|
+
if (withDefinition) {
|
|
122
|
+
await writeFile(join(dir, "sandbox.toml"), shape.definition ?? "", "utf8");
|
|
123
|
+
}
|
|
124
|
+
if (withOverlay) {
|
|
125
|
+
await writeFile(join(dir, "overlay.Dockerfile"), shape.overlay ?? "", "utf8");
|
|
126
|
+
}
|
|
127
|
+
const files = {
|
|
128
|
+
...(withDefinition ? { definitionFile: join(dir, "sandbox.toml") } : {}),
|
|
129
|
+
...(withOverlay ? { overlayFile: join(dir, "overlay.Dockerfile") } : {}),
|
|
130
|
+
...(withOverlay && shape.overlayHash !== undefined ? { environmentHash: shape.overlayHash } : {}),
|
|
131
|
+
};
|
|
132
|
+
const args = icRunnerArgs(op, name, parentUrl, pair, files);
|
|
133
|
+
const { code, output } = await runIc(args, onLine);
|
|
134
|
+
if (code !== 0) {
|
|
135
|
+
throw new Error(`That runner ${op === "runner-up" ? "start" : "removal"} failed on this computer.\n\n${output}`);
|
|
136
|
+
}
|
|
137
|
+
return op === "runner-up"
|
|
138
|
+
? `Runner "${name}" is up on this computer and pairing with the sandbox that asked for it.`
|
|
139
|
+
: `Removed runner "${name}". Its work lives in the parent sandbox's git, so nothing was lost with it.`;
|
|
140
|
+
}
|
|
141
|
+
finally {
|
|
142
|
+
if (dir !== undefined) {
|
|
143
|
+
await rm(dir, { recursive: true, force: true });
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
const runIc = async (args, onLine) => {
|
|
148
|
+
const candidates = icCandidates(process.platform, homedir());
|
|
149
|
+
const lines = [];
|
|
150
|
+
const emit = (chunk) => {
|
|
151
|
+
for (const line of chunk.split(/\r?\n/)) {
|
|
152
|
+
if (line !== "") {
|
|
153
|
+
lines.push(line);
|
|
154
|
+
onLine(line);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
for (const [index, binary] of candidates.entries()) {
|
|
159
|
+
const attempt = await new Promise((resolve) => {
|
|
160
|
+
const child = spawn(binary, [...args], { windowsHide: true });
|
|
161
|
+
let missing = false;
|
|
162
|
+
child.stdout.setEncoding("utf8").on("data", emit);
|
|
163
|
+
child.stderr.setEncoding("utf8").on("data", emit);
|
|
164
|
+
child.on("error", (error) => {
|
|
165
|
+
missing = error.code === "ENOENT";
|
|
166
|
+
if (!missing) {
|
|
167
|
+
emit(String(error.message));
|
|
168
|
+
}
|
|
169
|
+
resolve(missing ? "missing" : { code: 1, output: lines.join("\n") });
|
|
170
|
+
});
|
|
171
|
+
child.on("close", (code) => resolve(missing ? "missing" : { code: code ?? 1, output: lines.join("\n") }));
|
|
172
|
+
});
|
|
173
|
+
if (attempt !== "missing") {
|
|
174
|
+
return attempt;
|
|
175
|
+
}
|
|
176
|
+
if (index === candidates.length - 1) {
|
|
177
|
+
throw new Error("This computer has no `ic` command, so its sandboxes can't be updated or removed from here. Re-run the sandbox's install command on it to get one.");
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
throw new Error("no ic candidate was tried");
|
|
181
|
+
};
|
|
182
|
+
export const swapSandbox = async (swap, slug, hash, scopes, onLine) => {
|
|
183
|
+
assertScope(scopes, "sandboxes");
|
|
184
|
+
const args = icSwapArgs(swap, slug, hash);
|
|
185
|
+
await find(slug);
|
|
186
|
+
const { code, output } = await runIc(args, onLine);
|
|
187
|
+
if (code !== 0) {
|
|
188
|
+
throw new Error(`That ${swap} failed on this computer.\n\n${output}`);
|
|
189
|
+
}
|
|
190
|
+
if (swap === "prepare") {
|
|
191
|
+
return `The next update for "${slug}" is downloaded and built. Applying it is now a short restart.`;
|
|
192
|
+
}
|
|
193
|
+
const verb = { update: "Updated", rebuild: "Rebuilt", rollback: "Rolled back" }[swap];
|
|
194
|
+
return `${verb} sandbox "${slug}". Its files and its history were kept.`;
|
|
195
|
+
};
|
|
196
|
+
export const removeSandbox = async (slug, scopes, onLine) => {
|
|
197
|
+
assertScope(scopes, "sandboxRemove");
|
|
198
|
+
await find(slug);
|
|
199
|
+
const { code, output } = await runIc(icRemoveArgs(slug), onLine);
|
|
200
|
+
if (code !== 0) {
|
|
201
|
+
throw new Error(`That removal failed on this computer.\n\n${output}`);
|
|
202
|
+
}
|
|
203
|
+
return `Removed sandbox "${slug}" and everything in it.`;
|
|
204
|
+
};
|
|
205
|
+
export const DEFAULT_LOG_LINES = 200;
|
|
206
|
+
export const MAX_LOG_LINES = 2_000;
|
|
207
|
+
const readLogs = async (slug, lines, scopes) => {
|
|
208
|
+
if (scopes.shell !== "on") {
|
|
209
|
+
assertScope(scopes, "sandboxes");
|
|
210
|
+
}
|
|
211
|
+
await find(slug);
|
|
212
|
+
const { stdout, stderr } = await exec("docker", ["logs", "--tail", String(lines), `${PREFIX}${slug}`], {
|
|
213
|
+
timeout: DOCKER_TIMEOUT_MS,
|
|
214
|
+
maxBuffer: 8 * 1024 * 1024,
|
|
215
|
+
windowsHide: true,
|
|
216
|
+
});
|
|
217
|
+
return [stdout, stderr].filter((part) => part !== "").join("\n");
|
|
218
|
+
};
|
|
219
|
+
export const sandboxLogs = async (slug, lines, scopes) => {
|
|
220
|
+
const text = await readLogs(slug, lines ?? DEFAULT_LOG_LINES, scopes);
|
|
221
|
+
return text === "" ? `Sandbox "${slug}" has logged nothing yet.` : text;
|
|
222
|
+
};
|
|
223
|
+
export const tailSandboxLogs = async (slug, scopes, onLine) => {
|
|
224
|
+
const lines = (await readLogs(slug, DEFAULT_LOG_LINES, scopes)).split(/\r?\n/).filter((line) => line !== "");
|
|
225
|
+
for (const line of lines) {
|
|
226
|
+
onLine(line);
|
|
227
|
+
}
|
|
228
|
+
return lines.length === 0 ? `"${slug}" has logged nothing yet.` : `The last ${lines.length} lines from "${slug}".`;
|
|
229
|
+
};
|
|
230
|
+
//# sourceMappingURL=sandboxes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandboxes.js","sourceRoot":"","sources":["../../../src/computer/tools/sandboxes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type CommandClass, type HostScopes } from "@intentic/sandbox-contract";
|
|
2
|
+
export declare const DEFAULT_TIMEOUT_MS = 120000;
|
|
3
|
+
export declare const MAX_TIMEOUT_MS: number;
|
|
4
|
+
export declare const shellFor: (platform: NodeJS.Platform) => {
|
|
5
|
+
readonly command: string;
|
|
6
|
+
readonly args: (script: string) => string[];
|
|
7
|
+
readonly label: string;
|
|
8
|
+
};
|
|
9
|
+
export interface CommandResult {
|
|
10
|
+
readonly exitCode: number | null;
|
|
11
|
+
readonly stdout: string;
|
|
12
|
+
readonly stderr: string;
|
|
13
|
+
readonly timedOut: boolean;
|
|
14
|
+
}
|
|
15
|
+
export declare const destructiveClasses: (command: string) => CommandClass[];
|
|
16
|
+
export declare const runCommand: (input: {
|
|
17
|
+
readonly command: string;
|
|
18
|
+
readonly cwd?: string;
|
|
19
|
+
readonly timeoutMs?: number;
|
|
20
|
+
}, scopes: HostScopes) => Promise<CommandResult>;
|
|
21
|
+
export declare const describeResult: (result: CommandResult, timeoutMs: number) => string;
|
|
22
|
+
//# sourceMappingURL=shell.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shell.d.ts","sourceRoot":"","sources":["../../../src/computer/tools/shell.ts"],"names":[],"mappings":"AAGA,OAAO,EAAyC,KAAK,YAAY,EAAE,KAAK,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAsCvH,eAAO,MAAM,kBAAkB,SAAU,CAAC;AAC1C,eAAO,MAAM,cAAc,QAAiB,CAAC;AAK7C,eAAO,MAAM,QAAQ,aACP,MAAM,CAAC,QAAQ,KAC1B;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,EAAE,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAiBjG,CAAC;AAOF,MAAM,WAAW,aAAa;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC9B;AAeD,eAAO,MAAM,kBAAkB,YAAa,MAAM,KAAG,YAAY,EACqB,CAAC;AAEvF,eAAO,MAAM,UAAU,UACZ;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,UAC/E,UAAU,KACnB,OAAO,CAAC,aAAa,CAgDvB,CAAC;AAKF,eAAO,MAAM,cAAc,WAAY,aAAa,aAAa,MAAM,KAAG,MASzD,CAAC"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { classifyCommand, COMMAND_CLASS_LABELS } from "@intentic/sandbox-contract";
|
|
5
|
+
import { assertPath, assertScope, rootsOf, ScopeError } from "../policy.js";
|
|
6
|
+
export const DEFAULT_TIMEOUT_MS = 120_000;
|
|
7
|
+
export const MAX_TIMEOUT_MS = 10 * 60 * 1000;
|
|
8
|
+
const MAX_OUTPUT = 100_000;
|
|
9
|
+
export const shellFor = (platform) => {
|
|
10
|
+
if (platform === "win32") {
|
|
11
|
+
const pwsh = ["C:\\Program Files\\PowerShell\\7\\pwsh.exe", "C:\\Program Files\\PowerShell\\7-preview\\pwsh.exe"].find((path) => existsSync(path));
|
|
12
|
+
const command = pwsh ?? "powershell.exe";
|
|
13
|
+
return {
|
|
14
|
+
command,
|
|
15
|
+
args: (script) => ["-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-Command", script],
|
|
16
|
+
label: pwsh === undefined ? "Windows PowerShell 5.1" : "PowerShell 7",
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
const shell = process.env["SHELL"] ?? "/bin/sh";
|
|
20
|
+
return { command: shell, args: (script) => ["-lc", script], label: shell };
|
|
21
|
+
};
|
|
22
|
+
const truncate = (text) => text.length <= MAX_OUTPUT
|
|
23
|
+
? text
|
|
24
|
+
: `${text.slice(0, MAX_OUTPUT / 2)}\n… [${text.length - MAX_OUTPUT} characters cut] …\n${text.slice(-MAX_OUTPUT / 2)}`;
|
|
25
|
+
const GATED_CLASSES = new Set(["files.destructive", "system.destructive"]);
|
|
26
|
+
const destructiveRefusal = (classes) => `Refused: this command would ${classes.map((commandClass) => COMMAND_CLASS_LABELS[commandClass]).join(" and ")} on this computer, ` +
|
|
27
|
+
`and "Run destructive commands" is switched off for it. Turn it on in its capability card to allow this, ` +
|
|
28
|
+
`or run a command that does not delete.`;
|
|
29
|
+
export const destructiveClasses = (command) => classifyCommand(command).filter((commandClass) => GATED_CLASSES.has(commandClass));
|
|
30
|
+
export const runCommand = async (input, scopes) => {
|
|
31
|
+
assertScope(scopes, "shell");
|
|
32
|
+
const destructive = destructiveClasses(input.command);
|
|
33
|
+
if (destructive.length > 0 && scopes.destructive !== "on") {
|
|
34
|
+
throw new ScopeError(destructiveRefusal(destructive));
|
|
35
|
+
}
|
|
36
|
+
const cwd = input.cwd === undefined ? (rootsOf(scopes)[0] ?? homedir()) : assertPath(input.cwd, scopes, "run a command in");
|
|
37
|
+
const timeout = Math.min(input.timeoutMs ?? DEFAULT_TIMEOUT_MS, MAX_TIMEOUT_MS);
|
|
38
|
+
const shell = shellFor(process.platform);
|
|
39
|
+
return await new Promise((resolvePromise, rejectPromise) => {
|
|
40
|
+
const child = spawn(shell.command, shell.args(input.command), {
|
|
41
|
+
cwd,
|
|
42
|
+
env: process.env,
|
|
43
|
+
windowsHide: true,
|
|
44
|
+
});
|
|
45
|
+
let stdout = "";
|
|
46
|
+
let stderr = "";
|
|
47
|
+
let timedOut = false;
|
|
48
|
+
const timer = setTimeout(() => {
|
|
49
|
+
timedOut = true;
|
|
50
|
+
child.kill("SIGKILL");
|
|
51
|
+
}, timeout);
|
|
52
|
+
child.stdout.on("data", (chunk) => {
|
|
53
|
+
stdout += chunk.toString("utf8");
|
|
54
|
+
});
|
|
55
|
+
child.stderr.on("data", (chunk) => {
|
|
56
|
+
stderr += chunk.toString("utf8");
|
|
57
|
+
});
|
|
58
|
+
child.stdin.end();
|
|
59
|
+
child.on("error", (error) => {
|
|
60
|
+
clearTimeout(timer);
|
|
61
|
+
rejectPromise(error);
|
|
62
|
+
});
|
|
63
|
+
child.on("close", (code) => {
|
|
64
|
+
clearTimeout(timer);
|
|
65
|
+
resolvePromise({ exitCode: code, stdout: truncate(stdout), stderr: truncate(stderr), timedOut });
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
};
|
|
69
|
+
export const describeResult = (result, timeoutMs) => [
|
|
70
|
+
result.timedOut
|
|
71
|
+
? `The command was killed after ${Math.round(timeoutMs / 1000)}s. It either takes longer than that, or it is waiting for input that nobody can type: there is no terminal on this end.`
|
|
72
|
+
: `Exit code ${result.exitCode ?? "unknown"}${result.exitCode === 0 ? " (success)" : " (failed)"}.`,
|
|
73
|
+
result.stdout.trim() === "" ? "" : `\n--- stdout ---\n${result.stdout.trimEnd()}`,
|
|
74
|
+
result.stderr.trim() === "" ? "" : `\n--- stderr ---\n${result.stderr.trimEnd()}`,
|
|
75
|
+
]
|
|
76
|
+
.filter((part) => part !== "")
|
|
77
|
+
.join("");
|
|
78
|
+
//# sourceMappingURL=shell.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shell.js","sourceRoot":"","sources":["../../../src/computer/tools/shell.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,OAAO,QAAW,CAAC;AAQhC,eAAO,MAAM,UAAU,QAA+B,CAAC;AACvD,eAAO,MAAM,UAAU,QAA+B,CAAC"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
import { agentHome } from "@intentic/local-agent";
|
|
3
|
+
const home = agentHome("machine");
|
|
4
|
+
export const baseDir = home.dir;
|
|
5
|
+
export const runPidPath = join(baseDir, "machine.pid");
|
|
6
|
+
export const runLogPath = join(baseDir, "machine.log");
|
|
7
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AASlD,MAAM,IAAI,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC;AAClC,MAAM,CAAC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC;AAQhC,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;AACvD,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type CliLauncher, type Log } from "@intentic/local-agent";
|
|
2
|
+
export declare const machineLauncher: () => CliLauncher;
|
|
3
|
+
export declare const readResidentPid: () => Promise<number | undefined>;
|
|
4
|
+
export declare const startResident: (log: Log) => Promise<void>;
|
|
5
|
+
export declare const stopResident: () => Promise<number | undefined>;
|
|
6
|
+
export declare const reconcileResidency: (log: Log) => Promise<void>;
|
|
7
|
+
export declare const runForeground: (log: Log) => Promise<void>;
|
|
8
|
+
//# sourceMappingURL=resident.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resident.d.ts","sourceRoot":"","sources":["../src/resident.ts"],"names":[],"mappings":"AAEA,OAAO,EACH,KAAK,WAAW,EAIhB,KAAK,GAAG,EAMX,MAAM,uBAAuB,CAAC;AAgC/B,eAAO,MAAM,eAAe,QAAO,WAA8C,CAAC;AAGlF,eAAO,MAAM,eAAe,QAAa,OAAO,CAAC,MAAM,GAAG,SAAS,CAA8B,CAAC;AAUlG,eAAO,MAAM,aAAa,QAAe,GAAG,KAAG,OAAO,CAAC,IAAI,CAQ1D,CAAC;AAMF,eAAO,MAAM,YAAY,QAAa,OAAO,CAAC,MAAM,GAAG,SAAS,CAiB/D,CAAC;AAiBF,eAAO,MAAM,kBAAkB,QAAe,GAAG,KAAG,OAAO,CAAC,IAAI,CAY/D,CAAC;AAeF,eAAO,MAAM,aAAa,QAAe,GAAG,KAAG,OAAO,CAAC,IAAI,CAqD1D,CAAC"}
|
package/dist/resident.js
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { rm } from "node:fs/promises";
|
|
2
|
+
import { setTimeout as sleep } from "node:timers/promises";
|
|
3
|
+
import { cliLauncher, isProcessAlive, livePid, pidFileBody, registerAutostart, spawnDetached, unregisterAutostart, writeSecretFile, } from "@intentic/local-agent";
|
|
4
|
+
import { MACHINE_AUTOSTART } from "./autostart.js";
|
|
5
|
+
import { readLinks } from "./computer/config.js";
|
|
6
|
+
import { connect } from "./computer/connection.js";
|
|
7
|
+
import { baseDir, runLogPath, runPidPath } from "./config.js";
|
|
8
|
+
import { mirrorHeartbeatPath, readState } from "./sync/config.js";
|
|
9
|
+
import { runMirrorWatch, signalExitCode } from "./sync/mirror.js";
|
|
10
|
+
import { MACHINE_VERSION } from "./version.js";
|
|
11
|
+
export const machineLauncher = () => cliLauncher("intentic-machine");
|
|
12
|
+
export const readResidentPid = async () => await livePid(runPidPath);
|
|
13
|
+
const RESIDENT_EXIT_TIMEOUT_MS = 2000;
|
|
14
|
+
const RESIDENT_EXIT_POLL_MS = 50;
|
|
15
|
+
export const startResident = async (log) => {
|
|
16
|
+
const existing = await readResidentPid();
|
|
17
|
+
if (existing !== undefined) {
|
|
18
|
+
log(`the machine agent is already running (pid ${existing}).`);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const pid = await spawnDetached(runLogPath, machineLauncher(), MACHINE_AUTOSTART.foregroundArgs);
|
|
22
|
+
log(`machine agent running in the background (pid ${pid}). Details: ${runLogPath}`);
|
|
23
|
+
};
|
|
24
|
+
export const stopResident = async () => {
|
|
25
|
+
const pid = await readResidentPid();
|
|
26
|
+
if (pid !== undefined) {
|
|
27
|
+
try {
|
|
28
|
+
process.kill(pid, "SIGTERM");
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
}
|
|
32
|
+
for (let waited = 0; waited < RESIDENT_EXIT_TIMEOUT_MS && isProcessAlive(pid); waited += RESIDENT_EXIT_POLL_MS) {
|
|
33
|
+
await sleep(RESIDENT_EXIT_POLL_MS);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
await cleanup();
|
|
37
|
+
return pid;
|
|
38
|
+
};
|
|
39
|
+
const cleanup = async () => {
|
|
40
|
+
await rm(runPidPath, { force: true });
|
|
41
|
+
await rm(mirrorHeartbeatPath, { force: true });
|
|
42
|
+
};
|
|
43
|
+
export const reconcileResidency = async (log) => {
|
|
44
|
+
await stopResident();
|
|
45
|
+
const [links, state] = await Promise.all([readLinks(), readState()]);
|
|
46
|
+
if (links.length === 0 && state.pairings.length === 0) {
|
|
47
|
+
await unregisterAutostart(MACHINE_AUTOSTART, log);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
if (!(await registerAutostart(MACHINE_AUTOSTART, machineLauncher(), log))) {
|
|
51
|
+
await startResident(log);
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
export const runForeground = async (log) => {
|
|
55
|
+
const holder = await readResidentPid();
|
|
56
|
+
if (holder !== undefined && holder !== process.pid) {
|
|
57
|
+
log(`a machine agent is already running (pid ${holder}): leaving it alone. Stop it with \`intentic-machine run --stop\` first.`);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
await writeSecretFile(runPidPath, baseDir, await pidFileBody());
|
|
61
|
+
const [links, state] = await Promise.all([readLinks(), readState()]);
|
|
62
|
+
if (links.length === 0 && state.pairings.length === 0) {
|
|
63
|
+
log("nothing to serve: no sandbox is linked to this computer and none is paired for sync. Connect one from a card in your sandbox.");
|
|
64
|
+
await unregisterAutostart(MACHINE_AUTOSTART, log);
|
|
65
|
+
await cleanup();
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const connections = links.map((link) => connect(link, MACHINE_VERSION, log));
|
|
69
|
+
const shutdown = (signal) => {
|
|
70
|
+
for (const connection of connections) {
|
|
71
|
+
connection.stop();
|
|
72
|
+
}
|
|
73
|
+
void cleanup().finally(() => process.exit(signalExitCode(signal)));
|
|
74
|
+
};
|
|
75
|
+
process.on("SIGTERM", shutdown);
|
|
76
|
+
process.on("SIGINT", shutdown);
|
|
77
|
+
if (links.length > 0) {
|
|
78
|
+
log(`serving ${links.length} linked sandbox(es)`);
|
|
79
|
+
}
|
|
80
|
+
const halves = connections.map((connection) => connection.done);
|
|
81
|
+
if (state.pairings.length > 0) {
|
|
82
|
+
halves.push(runMirrorWatch(log));
|
|
83
|
+
}
|
|
84
|
+
await Promise.all(halves);
|
|
85
|
+
const [linksNow, stateNow] = await Promise.all([readLinks(), readState()]);
|
|
86
|
+
if (linksNow.length === 0 && stateNow.pairings.length === 0) {
|
|
87
|
+
await unregisterAutostart(MACHINE_AUTOSTART, log);
|
|
88
|
+
log("nothing left to serve: agent exiting. Reconnect from a card in your sandbox.");
|
|
89
|
+
}
|
|
90
|
+
await cleanup();
|
|
91
|
+
};
|
|
92
|
+
//# sourceMappingURL=resident.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resident.js","sourceRoot":"","sources":["../src/resident.ts"],"names":[],"mappings":"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"}
|
package/dist/status.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { HostScopes, MachineReport } from "@intentic/sandbox-contract";
|
|
2
|
+
import { type CommandContext } from "@stricli/core";
|
|
3
|
+
export interface MachineStatus {
|
|
4
|
+
readonly version: string;
|
|
5
|
+
readonly running?: number;
|
|
6
|
+
readonly summary: string;
|
|
7
|
+
readonly computer: {
|
|
8
|
+
readonly links: readonly {
|
|
9
|
+
readonly sandboxUrl: string;
|
|
10
|
+
readonly id: string;
|
|
11
|
+
readonly scopes: HostScopes;
|
|
12
|
+
}[];
|
|
13
|
+
};
|
|
14
|
+
readonly sync: MachineReport;
|
|
15
|
+
}
|
|
16
|
+
export declare const statusSummary: (running: number | undefined, links: number, sync: MachineReport, now: number) => string;
|
|
17
|
+
export declare const machineStatus: (mutagen: string | undefined) => Promise<MachineStatus>;
|
|
18
|
+
export declare const pairingLine: (pairing: MachineReport["pairings"][number]) => string;
|
|
19
|
+
export declare const watcherLine: (watcher: MachineReport["watcher"], now: number) => string;
|
|
20
|
+
export declare const status: import("@stricli/core").Command<CommandContext>;
|
|
21
|
+
//# sourceMappingURL=status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../src/status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAe,aAAa,EAAE,MAAM,4BAA4B,CAAC;AACzF,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAoBlE,MAAM,WAAW,aAAa;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAK1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,SAAS;YAAE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAA;SAAE,EAAE,CAAA;KAAE,CAAC;IACpI,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;CAChC;AAMD,eAAO,MAAM,aAAa,YAAa,MAAM,GAAG,SAAS,SAAS,MAAM,QAAQ,aAAa,OAAO,MAAM,KAAG,MAgB5G,CAAC;AAEF,eAAO,MAAM,aAAa,YAAmB,MAAM,GAAG,SAAS,KAAG,OAAO,CAAC,aAAa,CAStF,CAAC;AA0BF,eAAO,MAAM,WAAW,YAAa,aAAa,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,KAAG,MAoBxE,CAAC;AAUF,eAAO,MAAM,WAAW,YAAa,aAAa,CAAC,SAAS,CAAC,OAAO,MAAM,KAAG,MAc5E,CAAC;AA2BF,eAAO,MAAM,MAAM,iDA+DjB,CAAC"}
|