totemlayer 0.1.63 → 0.1.66
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/README.md +34 -4
- package/bin/automatic-runtime.mjs +11 -116
- package/bin/managed-mcp.mjs +68 -0
- package/bin/native/darwin-lifetime +0 -0
- package/bin/native/darwin-lifetime.json +1 -0
- package/bin/process-isolation.mjs +53 -9
- package/bin/runtime-archive.mjs +131 -0
- package/bin/runtime-installation.mjs +63 -4
- package/bin/runtime-lock.mjs +118 -0
- package/bin/runtime-update.mjs +345 -0
- package/bin/sdk/inspector.js +1 -1
- package/bin/totem.mjs +11 -5
- package/bin/update-health.mjs +10 -0
- package/bin/update-trust.mjs +7 -0
- package/bin/worker-core/adapters.mjs +27 -6
- package/bin/worker-core/errors.mjs +4 -0
- package/package.json +3 -2
- package/scripts/build-native.mjs +60 -0
- package/scripts/prepare.mjs +1 -0
|
@@ -63,6 +63,9 @@ export function createCommandAdapter(config) {
|
|
|
63
63
|
const maxOutputBytes = integer(config.maxOutputBytes, 1024 * 1024, 16 * 1024 * 1024);
|
|
64
64
|
const parseResult = config.parseResult ?? ((output) => ({ status: "completed", output }));
|
|
65
65
|
if (typeof parseResult !== "function") throw new WorkerError("INVALID_ADAPTER_CONFIG");
|
|
66
|
+
const supervised = config.managedLifecycle === "darwin-coalition";
|
|
67
|
+
if (config.managedLifecycle !== undefined && (!supervised || process.platform !== "darwin"))
|
|
68
|
+
throw new WorkerError("INVALID_ADAPTER_CONFIG");
|
|
66
69
|
|
|
67
70
|
return {
|
|
68
71
|
async run({ prompt, signal }) {
|
|
@@ -97,7 +100,8 @@ export function createCommandAdapter(config) {
|
|
|
97
100
|
// Also remove surviving descendants if the parent exits before escalation.
|
|
98
101
|
const kill = (kind) => {
|
|
99
102
|
try {
|
|
100
|
-
if (
|
|
103
|
+
if (supervised) child?.kill("SIGTERM");
|
|
104
|
+
else if (process.platform !== "win32" && child?.pid) process.kill(-child.pid, kind);
|
|
101
105
|
else if (child?.pid) {
|
|
102
106
|
// A Windows shim can outlive its parent and keep stdio open.
|
|
103
107
|
const killer = spawn("taskkill.exe", ["/pid", String(child.pid), "/t", "/f"], {
|
|
@@ -119,8 +123,10 @@ export function createCommandAdapter(config) {
|
|
|
119
123
|
failure = new WorkerError(code);
|
|
120
124
|
// Kill the complete child process group on POSIX, including spawned tools.
|
|
121
125
|
kill("SIGTERM");
|
|
122
|
-
|
|
123
|
-
|
|
126
|
+
if (!supervised) {
|
|
127
|
+
killTimer = setTimeout(() => kill("SIGKILL"), 1000);
|
|
128
|
+
killTimer.unref();
|
|
129
|
+
}
|
|
124
130
|
};
|
|
125
131
|
const cancel = () => stop("RUN_CANCELLED");
|
|
126
132
|
try {
|
|
@@ -130,7 +136,7 @@ export function createCommandAdapter(config) {
|
|
|
130
136
|
shell: false,
|
|
131
137
|
detached: process.platform !== "win32",
|
|
132
138
|
windowsHide: true,
|
|
133
|
-
stdio: ["pipe", "pipe", "pipe"],
|
|
139
|
+
stdio: supervised ? ["pipe", "pipe", "pipe", "pipe"] : ["pipe", "pipe", "pipe"],
|
|
134
140
|
});
|
|
135
141
|
} catch (error) {
|
|
136
142
|
reject(Object.assign(new WorkerError("AGENT_START_FAILED"), { cause: error }));
|
|
@@ -155,6 +161,21 @@ export function createCommandAdapter(config) {
|
|
|
155
161
|
child.stdin.on("error", () => {
|
|
156
162
|
/* A failed child can close stdin early. */
|
|
157
163
|
});
|
|
164
|
+
if (supervised) {
|
|
165
|
+
let reported = false;
|
|
166
|
+
child.stdio[3].on("data", (status) => {
|
|
167
|
+
if (!reported && status.includes(83)) {
|
|
168
|
+
reported = true;
|
|
169
|
+
process.emitWarning(
|
|
170
|
+
"Native process cleanup is delayed; Totem is retrying and has not completed the turn.",
|
|
171
|
+
{ code: "AGENT_CLEANUP_STALLED" },
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
child.stdio[3].on("error", () => {
|
|
176
|
+
/* Supervisor exit closes the private channel. */
|
|
177
|
+
});
|
|
178
|
+
}
|
|
158
179
|
child.on("error", (error) => {
|
|
159
180
|
failure ??= Object.assign(new WorkerError("AGENT_START_FAILED"), { cause: error });
|
|
160
181
|
});
|
|
@@ -163,9 +184,9 @@ export function createCommandAdapter(config) {
|
|
|
163
184
|
clearTimeout(killTimer);
|
|
164
185
|
signal?.removeEventListener("abort", cancel);
|
|
165
186
|
// A successful foreground turn cannot leave background tools behind.
|
|
166
|
-
if (config.inheritSystemEnvironment === false) kill("SIGKILL");
|
|
187
|
+
if (!supervised && config.inheritSystemEnvironment === false) kill("SIGKILL");
|
|
167
188
|
if (failure) {
|
|
168
|
-
kill("SIGKILL");
|
|
189
|
+
if (!supervised) kill("SIGKILL");
|
|
169
190
|
return reject(diagnosticFailure(failure, code));
|
|
170
191
|
}
|
|
171
192
|
if (code !== 0) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "totemlayer",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.66",
|
|
4
4
|
"description": "Cross-platform CLI for TotemLayer agent identity and authorization",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
"bin",
|
|
13
13
|
"LICENSE.md",
|
|
14
14
|
"README.md",
|
|
15
|
-
"scripts/prepare.mjs"
|
|
15
|
+
"scripts/prepare.mjs",
|
|
16
|
+
"scripts/build-native.mjs"
|
|
16
17
|
],
|
|
17
18
|
"engines": {
|
|
18
19
|
"node": ">=22.14.0"
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { execFileSync } from "node:child_process";
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
3
|
+
import { mkdir, readFile, rename, rm, writeFile } from "node:fs/promises";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
|
|
6
|
+
const source = new URL("../native/darwin-lifetime.c", import.meta.url);
|
|
7
|
+
const binary = new URL("../bin/native/darwin-lifetime", import.meta.url);
|
|
8
|
+
const manifest = new URL("../bin/native/darwin-lifetime.json", import.meta.url);
|
|
9
|
+
const digest = (bytes) => createHash("sha256").update(bytes).digest("hex");
|
|
10
|
+
const sourceSha256 = digest(await readFile(source));
|
|
11
|
+
|
|
12
|
+
if (process.platform === "win32")
|
|
13
|
+
throw new Error(
|
|
14
|
+
"Build the universal CLI tarball on macOS or Linux to preserve the native executable mode; Windows can install that tarball.",
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
if (process.platform === "darwin") {
|
|
18
|
+
await mkdir(new URL("../bin/native/", import.meta.url), { recursive: true });
|
|
19
|
+
const temporary = `${fileURLToPath(binary)}.${process.pid}.tmp`;
|
|
20
|
+
try {
|
|
21
|
+
execFileSync(
|
|
22
|
+
"/usr/bin/clang",
|
|
23
|
+
[
|
|
24
|
+
"-std=c11",
|
|
25
|
+
"-D_DARWIN_C_SOURCE",
|
|
26
|
+
"-Wall",
|
|
27
|
+
"-Wextra",
|
|
28
|
+
"-Werror",
|
|
29
|
+
"-O2",
|
|
30
|
+
"-arch",
|
|
31
|
+
"arm64",
|
|
32
|
+
"-arch",
|
|
33
|
+
"x86_64",
|
|
34
|
+
"-mmacosx-version-min=13.0",
|
|
35
|
+
fileURLToPath(source),
|
|
36
|
+
"-o",
|
|
37
|
+
temporary,
|
|
38
|
+
],
|
|
39
|
+
{ stdio: "inherit", timeout: 60_000 },
|
|
40
|
+
);
|
|
41
|
+
await rename(temporary, binary);
|
|
42
|
+
await writeFile(
|
|
43
|
+
manifest,
|
|
44
|
+
JSON.stringify({
|
|
45
|
+
sourceSha256,
|
|
46
|
+
binarySha256: digest(await readFile(binary)),
|
|
47
|
+
architectures: ["arm64", "x86_64"],
|
|
48
|
+
minimumMacOS: "13.0",
|
|
49
|
+
}) + "\n",
|
|
50
|
+
);
|
|
51
|
+
} finally {
|
|
52
|
+
await rm(temporary, { force: true });
|
|
53
|
+
}
|
|
54
|
+
} else {
|
|
55
|
+
// Every published tarball supports both Mac architectures. Build this small
|
|
56
|
+
// artifact on macOS before packing elsewhere; never ship a stale or missing one.
|
|
57
|
+
const built = JSON.parse(await readFile(manifest, "utf8"));
|
|
58
|
+
if (built.sourceSha256 !== sourceSha256 || built.binarySha256 !== digest(await readFile(binary)))
|
|
59
|
+
throw new Error("Build the current macOS lifetime supervisor on macOS before packing.");
|
|
60
|
+
}
|
package/scripts/prepare.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { access, readdir, readFile, writeFile } from "node:fs/promises";
|
|
2
2
|
import { transform } from "esbuild";
|
|
3
|
+
import "./build-native.mjs";
|
|
3
4
|
import { generateNetworkContract } from "../../../scripts/generate-network-contract.mjs";
|
|
4
5
|
await generateNetworkContract();
|
|
5
6
|
// This candidate rebases coordination on the immutable published 0.1.21 bundle.
|