@nowcrew/daemon 0.6.89 → 0.6.90
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 +64 -3
- package/dist/agent-ability/materializer.js +21 -10
- package/dist/agent-environment-contract.js +55 -0
- package/dist/agent-environment-control.js +24 -0
- package/dist/agent-environment-execution.js +98 -0
- package/dist/agent-environments.js +275 -0
- package/dist/automatic-daemon-installer.js +49 -1
- package/dist/computer-main.js +18 -0
- package/dist/computer-profile.js +17 -4
- package/dist/computer-setup-client.js +318 -0
- package/dist/computer-setup-orchestration.js +203 -0
- package/dist/computer-setup.js +244 -0
- package/dist/config.js +30 -12
- package/dist/console-formatter.js +3 -3
- package/dist/console.js +15 -2
- package/dist/daemon-update-eligibility.js +1 -1
- package/dist/execution-journal.js +9 -6
- package/dist/execution-protocol.js +1 -0
- package/dist/execution-runner.js +13 -8
- package/dist/i18n.js +19 -0
- package/dist/list-models.js +12 -12
- package/dist/local-execution-lease.js +22 -0
- package/dist/local-executor.js +57 -84
- package/dist/local-memory/candidate.js +43 -0
- package/dist/local-memory/index-budget.js +8 -0
- package/dist/local-memory/inventory-cli.js +61 -0
- package/dist/local-memory/inventory-preview.js +159 -0
- package/dist/local-memory/inventory-source.js +159 -0
- package/dist/local-memory/pending-match.js +29 -0
- package/dist/local-memory/pending-query.js +100 -0
- package/dist/local-memory/pending-schema.js +29 -0
- package/dist/local-memory/pending-source.js +126 -0
- package/dist/local-memory/pending.js +34 -84
- package/dist/local-memory/prompt.js +19 -12
- package/dist/local-memory/read-cli.js +97 -12
- package/dist/local-memory/rollout.js +82 -0
- package/dist/local-memory/runtime.js +23 -17
- package/dist/local-memory/work-log-execution.js +31 -0
- package/dist/local-memory/work-log.js +58 -0
- package/dist/local-memory/write.js +27 -58
- package/dist/local-runtime-environment.js +50 -0
- package/dist/machine-environment-cache.js +147 -0
- package/dist/machine-environment-contract.js +10 -0
- package/dist/machine-environment-control.js +27 -0
- package/dist/machine-environment-policy.js +75 -0
- package/dist/machine-environment-process.js +110 -0
- package/dist/machine-info.js +70 -25
- package/dist/machine-runtime-environment.js +189 -0
- package/dist/machine-shell-environment-capture.js +135 -0
- package/dist/machine-windows-environment-capture.js +215 -0
- package/dist/machine-windows-environment-script.js +158 -0
- package/dist/main.js +4 -69
- package/dist/marketplace-command.js +21 -0
- package/dist/marketplace-controller.js +80 -0
- package/dist/marketplace-protocol.js +38 -0
- package/dist/marketplace-remote.js +48 -0
- package/dist/marketplace-runner.js +235 -0
- package/dist/marketplace-serve.js +17 -0
- package/dist/marketplace-source.js +103 -0
- package/dist/message-file-preview.js +246 -0
- package/dist/pre-admission-rejection.js +64 -0
- package/dist/project-skills/execution-adapter.js +3 -2
- package/dist/project-skills/runtime-launch.js +14 -0
- package/dist/provider-env.js +26 -15
- package/dist/runner.js +17 -4
- package/dist/runtime-environment-merge.js +16 -0
- package/dist/runtime-health-handler.js +10 -0
- package/dist/runtime-health.js +3 -1
- package/dist/runtime-path.js +22 -12
- package/dist/runtime-probe.js +35 -6
- package/dist/runtimes/acp-probe-transport.js +69 -0
- package/dist/runtimes/claude-models.js +20 -9
- package/dist/runtimes/deepseek-harness-launch.js +10 -0
- package/dist/runtimes/deepseek-harness-profile.js +92 -0
- package/dist/runtimes/deepseek-harness-runner.js +226 -0
- package/dist/runtimes/deepseek-harness.js +76 -15
- package/dist/runtimes/harness-probe-retry.js +42 -0
- package/dist/runtimes/hermes-models.js +2 -1
- package/dist/runtimes/kimi-acp-runner.js +78 -13
- package/dist/runtimes/opencode.js +2 -2
- package/dist/serve.js +88 -176
- package/dist/storage-identity.js +0 -3
- package/dist/storage-serve-adapter.js +6 -72
- package/dist/supervised-runtime.js +17 -2
- package/dist/token.js +0 -1
- package/dist/workspace-control-handler.js +27 -0
- package/dist/workspace-fs.js +66 -15
- package/dist/workspace.js +1 -1
- package/package.json +13 -12
- package/dist/codex-home-launch.js +0 -7
- package/dist/codex-home-mode-controller.js +0 -68
- package/dist/daemon-migration-controller.js +0 -211
- package/dist/daemon-migration-wiring.js +0 -22
- package/dist/runtimes/codex-home-migration-cli.js +0 -26
- package/dist/runtimes/codex-home-migration.js +0 -112
- package/dist/runtimes/codex-home.js +0 -236
- package/dist/storage-control.js +0 -212
- package/dist/storage-copy.js +0 -628
- package/dist/storage-credential-guard.js +0 -21
- package/dist/storage-doctor.js +0 -228
- package/dist/storage-manifest.js +0 -1027
- package/dist/storage-migration-controller.js +0 -440
- package/dist/storage-migration-manifest.js +0 -105
- package/dist/storage-migration-policy.js +0 -100
- package/dist/storage-runtime-controller.js +0 -381
- package/dist/storage-runtime-readiness.js +0 -241
- package/dist/storage-safe-fs.js +0 -302
- package/dist/storage-status-delivery.js +0 -224
- package/dist/storage-status-replay.js +0 -140
- package/dist/storage-target-confirmation.js +0 -129
- package/dist/storage-worker-command.js +0 -37
- package/dist/storage-worker-executor.js +0 -447
- package/dist/storage-worker-handoff.js +0 -151
- package/dist/storage-worker-operation.js +0 -294
- package/dist/storage-worker-status.js +0 -259
|
@@ -1,259 +0,0 @@
|
|
|
1
|
-
import { readFile, unlink } from "node:fs/promises";
|
|
2
|
-
import { basename, dirname, isAbsolute, join } from "node:path";
|
|
3
|
-
import { Worker } from "node:worker_threads";
|
|
4
|
-
import { z } from "zod";
|
|
5
|
-
import { atomicPrivateWrite } from "./atomic-private-write.js";
|
|
6
|
-
const WorkerFailureSchema = z.object({
|
|
7
|
-
version: z.literal(1),
|
|
8
|
-
migrationId: z.string().uuid(),
|
|
9
|
-
status: z.literal("failed"),
|
|
10
|
-
errorCode: z.string().regex(/^[a-z0-9._-]{1,128}$/u),
|
|
11
|
-
errorMessage: z.string().min(1).max(512),
|
|
12
|
-
at: z.string().datetime({ offset: true }),
|
|
13
|
-
}).strict();
|
|
14
|
-
const WorkerHeartbeatSchema = z.object({
|
|
15
|
-
version: z.literal(1),
|
|
16
|
-
migrationId: z.string().uuid(),
|
|
17
|
-
pid: z.number().int().positive(),
|
|
18
|
-
at: z.string().datetime({ offset: true }),
|
|
19
|
-
}).strict();
|
|
20
|
-
const TOKEN = /(?:\bsk_(?:machine|user|agent)_[A-Za-z0-9_-]{4,}\b|\bbearer\s+[^\s]+|(?:password|secret|token)\s*[:=]\s*[^\s]+)/giu;
|
|
21
|
-
const HEARTBEAT_WORKER_KIND = "nowwork-storage-worker-heartbeat-v1";
|
|
22
|
-
async function unlinkHeartbeat(path) {
|
|
23
|
-
await unlink(path).catch((error) => {
|
|
24
|
-
if (error.code !== "ENOENT")
|
|
25
|
-
throw error;
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Keep the liveness writer in a worker with its own event loop. The source is
|
|
30
|
-
* intentionally plain JavaScript because a worker module cannot resolve the
|
|
31
|
-
* source tree's `.js` specifiers under tsx/Vitest; production builds and tests
|
|
32
|
-
* therefore exercise the same isolated execution boundary.
|
|
33
|
-
*/
|
|
34
|
-
const HEARTBEAT_WORKER_SOURCE = String.raw `
|
|
35
|
-
const { parentPort, workerData } = require("node:worker_threads");
|
|
36
|
-
const { mkdir, chmod, rename, rm, unlink, writeFile } = require("node:fs/promises");
|
|
37
|
-
const { dirname } = require("node:path");
|
|
38
|
-
const { randomUUID } = require("node:crypto");
|
|
39
|
-
|
|
40
|
-
const atomicPrivateWrite = async (path, content) => {
|
|
41
|
-
const directory = dirname(path);
|
|
42
|
-
await mkdir(directory, { recursive: true, mode: 0o700 });
|
|
43
|
-
await chmod(directory, 0o700);
|
|
44
|
-
const temporary = path + "." + randomUUID() + ".tmp";
|
|
45
|
-
try {
|
|
46
|
-
await writeFile(temporary, content, { encoding: "utf8", mode: 0o600, flag: "wx" });
|
|
47
|
-
await rename(temporary, path);
|
|
48
|
-
await chmod(path, 0o600);
|
|
49
|
-
} finally {
|
|
50
|
-
await rm(temporary, { force: true });
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
const removeHeartbeat = async () => {
|
|
54
|
-
try { await unlink(workerData.path); } catch (error) {
|
|
55
|
-
if (error && error.code !== "ENOENT") throw error;
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
let pending = Promise.resolve();
|
|
59
|
-
let stopping = false;
|
|
60
|
-
let firstWrite = true;
|
|
61
|
-
const write = (requestedAt) => {
|
|
62
|
-
const initial = firstWrite;
|
|
63
|
-
firstWrite = false;
|
|
64
|
-
pending = pending.catch(() => undefined).then(() => atomicPrivateWrite(workerData.path, JSON.stringify({
|
|
65
|
-
version: 1,
|
|
66
|
-
migrationId: workerData.migrationId,
|
|
67
|
-
pid: process.pid,
|
|
68
|
-
at: initial && workerData.initialAt ? workerData.initialAt : requestedAt || new Date().toISOString(),
|
|
69
|
-
}, null, 2) + "\n"));
|
|
70
|
-
return pending;
|
|
71
|
-
};
|
|
72
|
-
const report = (message) => { try { parentPort.postMessage(message); } catch {} };
|
|
73
|
-
(async () => {
|
|
74
|
-
try { await write(); report({ type: "ready" }); }
|
|
75
|
-
catch (error) { report({ type: "error", message: error instanceof Error ? error.message : String(error) }); return; }
|
|
76
|
-
const timer = workerData.useParentClock ? null : setInterval(() => {
|
|
77
|
-
if (!stopping) void write().catch((error) => report({ type: "error", message: error instanceof Error ? error.message : String(error) }));
|
|
78
|
-
}, workerData.intervalMs);
|
|
79
|
-
timer?.unref?.();
|
|
80
|
-
parentPort.on("message", (message) => {
|
|
81
|
-
if (stopping || !message) return;
|
|
82
|
-
if (message.type === "tick") {
|
|
83
|
-
if (!workerData.useParentClock) return;
|
|
84
|
-
void write(message.at).catch((error) => report({ type: "error", message: error instanceof Error ? error.message : String(error) }));
|
|
85
|
-
return;
|
|
86
|
-
}
|
|
87
|
-
if (message.type !== "stop") return;
|
|
88
|
-
stopping = true;
|
|
89
|
-
if (timer !== null) clearInterval(timer);
|
|
90
|
-
void pending.then(async () => { await removeHeartbeat(); report({ type: "stopped" }); }, async () => {
|
|
91
|
-
await removeHeartbeat().catch(() => undefined); report({ type: "stopped" });
|
|
92
|
-
});
|
|
93
|
-
});
|
|
94
|
-
})();
|
|
95
|
-
`;
|
|
96
|
-
function identityFromHandoffPath(handoffPath) {
|
|
97
|
-
if (!isAbsolute(handoffPath) || basename(handoffPath) !== "handoff.json") {
|
|
98
|
-
throw new Error("storage worker handoff path is invalid");
|
|
99
|
-
}
|
|
100
|
-
const migrationDirectory = dirname(handoffPath);
|
|
101
|
-
const migrationsDirectory = dirname(migrationDirectory);
|
|
102
|
-
if (basename(migrationsDirectory) !== "migrations")
|
|
103
|
-
throw new Error("storage worker handoff path is invalid");
|
|
104
|
-
return {
|
|
105
|
-
stateRoot: dirname(migrationsDirectory),
|
|
106
|
-
migrationId: z.string().uuid().parse(basename(migrationDirectory)).toLowerCase(),
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
export function storageWorkerFailurePath(stateRoot, migrationId) {
|
|
110
|
-
if (!isAbsolute(stateRoot))
|
|
111
|
-
throw new Error("storage worker state root must be absolute");
|
|
112
|
-
return join(stateRoot, "migrations", z.string().uuid().parse(migrationId), "worker-status.json");
|
|
113
|
-
}
|
|
114
|
-
export function storageWorkerHeartbeatPath(stateRoot, migrationId) {
|
|
115
|
-
if (!isAbsolute(stateRoot))
|
|
116
|
-
throw new Error("storage worker state root must be absolute");
|
|
117
|
-
return join(stateRoot, "migrations", z.string().uuid().parse(migrationId), "worker-heartbeat.json");
|
|
118
|
-
}
|
|
119
|
-
export async function startStorageWorkerHeartbeat(handoffPath, input = {}) {
|
|
120
|
-
const identity = identityFromHandoffPath(handoffPath);
|
|
121
|
-
const intervalMs = z.number().int().min(100).max(15_000).parse(input.intervalMs ?? 5_000);
|
|
122
|
-
const path = storageWorkerHeartbeatPath(identity.stateRoot, identity.migrationId);
|
|
123
|
-
const initialAt = input.now?.().toISOString();
|
|
124
|
-
// The worker owns heartbeat I/O so a synchronous CPU-heavy scan in the
|
|
125
|
-
// migration process cannot delay the monitor's 30-second freshness window.
|
|
126
|
-
const worker = new Worker(HEARTBEAT_WORKER_SOURCE, {
|
|
127
|
-
eval: true,
|
|
128
|
-
// `--input-type=module` is inherited by workers launched from an eval
|
|
129
|
-
// smoke test; strip it so the plain CommonJS worker source can use require.
|
|
130
|
-
execArgv: process.execArgv.filter((arg) => !arg.startsWith("--input-type=")),
|
|
131
|
-
workerData: {
|
|
132
|
-
kind: HEARTBEAT_WORKER_KIND,
|
|
133
|
-
path,
|
|
134
|
-
migrationId: identity.migrationId,
|
|
135
|
-
intervalMs,
|
|
136
|
-
useParentClock: input.now !== undefined,
|
|
137
|
-
...(initialAt === undefined ? {} : { initialAt }),
|
|
138
|
-
},
|
|
139
|
-
});
|
|
140
|
-
worker.unref();
|
|
141
|
-
let startupSettled = false;
|
|
142
|
-
let heartbeatError = null;
|
|
143
|
-
let stopResolve = null;
|
|
144
|
-
const onWorkerMessage = (message) => {
|
|
145
|
-
if (message.type === "error") {
|
|
146
|
-
heartbeatError = new Error(`storage worker heartbeat failed: ${message.message}`);
|
|
147
|
-
if (!startupSettled)
|
|
148
|
-
startupReject?.(heartbeatError);
|
|
149
|
-
}
|
|
150
|
-
else if (message.type === "stopped") {
|
|
151
|
-
stopResolve?.();
|
|
152
|
-
stopResolve = null;
|
|
153
|
-
}
|
|
154
|
-
};
|
|
155
|
-
let startupReject = null;
|
|
156
|
-
worker.on("message", onWorkerMessage);
|
|
157
|
-
// Keep this listener for the entire worker lifetime. A heartbeat write may
|
|
158
|
-
// fail after startup; dropping the listener would turn that operational
|
|
159
|
-
// error into an unhandled Worker 'error' event and crash the parent.
|
|
160
|
-
const onWorkerError = (error) => {
|
|
161
|
-
heartbeatError = error;
|
|
162
|
-
if (!startupSettled)
|
|
163
|
-
startupReject?.(error);
|
|
164
|
-
};
|
|
165
|
-
worker.on("error", onWorkerError);
|
|
166
|
-
await new Promise((resolvePromise, reject) => {
|
|
167
|
-
startupReject = reject;
|
|
168
|
-
const onReady = (message) => {
|
|
169
|
-
if (message.type !== "ready")
|
|
170
|
-
return;
|
|
171
|
-
startupSettled = true;
|
|
172
|
-
worker.off("message", onReady);
|
|
173
|
-
resolvePromise();
|
|
174
|
-
};
|
|
175
|
-
worker.on("message", onReady);
|
|
176
|
-
}).catch(async (error) => {
|
|
177
|
-
startupSettled = true;
|
|
178
|
-
await worker.terminate().catch(() => undefined);
|
|
179
|
-
worker.off("message", onWorkerMessage);
|
|
180
|
-
worker.off("error", onWorkerError);
|
|
181
|
-
await unlinkHeartbeat(path).catch(() => undefined);
|
|
182
|
-
throw error;
|
|
183
|
-
});
|
|
184
|
-
const parentTimer = input.now === undefined ? null : setInterval(() => {
|
|
185
|
-
try {
|
|
186
|
-
worker.postMessage({ type: "tick", at: input.now().toISOString() });
|
|
187
|
-
}
|
|
188
|
-
catch (error) {
|
|
189
|
-
heartbeatError = error instanceof Error ? error : new Error(String(error));
|
|
190
|
-
}
|
|
191
|
-
}, intervalMs);
|
|
192
|
-
parentTimer?.unref?.();
|
|
193
|
-
let stopped = false;
|
|
194
|
-
const stop = async () => {
|
|
195
|
-
if (stopped)
|
|
196
|
-
return;
|
|
197
|
-
stopped = true;
|
|
198
|
-
if (parentTimer !== null)
|
|
199
|
-
clearInterval(parentTimer);
|
|
200
|
-
await new Promise((resolvePromise) => {
|
|
201
|
-
const onExit = () => {
|
|
202
|
-
worker.off("exit", onExit);
|
|
203
|
-
stopResolve = null;
|
|
204
|
-
resolvePromise();
|
|
205
|
-
};
|
|
206
|
-
stopResolve = resolvePromise;
|
|
207
|
-
worker.once("exit", onExit);
|
|
208
|
-
worker.postMessage({ type: "stop" });
|
|
209
|
-
});
|
|
210
|
-
await worker.terminate().catch(() => undefined);
|
|
211
|
-
worker.off("message", onWorkerMessage);
|
|
212
|
-
worker.off("error", onWorkerError);
|
|
213
|
-
await unlinkHeartbeat(path);
|
|
214
|
-
};
|
|
215
|
-
Object.defineProperty(stop, "assertHealthy", {
|
|
216
|
-
enumerable: false,
|
|
217
|
-
value: () => {
|
|
218
|
-
if (heartbeatError !== null)
|
|
219
|
-
throw heartbeatError;
|
|
220
|
-
},
|
|
221
|
-
});
|
|
222
|
-
return stop;
|
|
223
|
-
}
|
|
224
|
-
export async function writeStorageWorkerFailureStatus(handoffPath, error) {
|
|
225
|
-
const identity = identityFromHandoffPath(handoffPath);
|
|
226
|
-
const rawCode = error instanceof Error && "code" in error ? String(error.code) : "worker_failed";
|
|
227
|
-
const errorCode = /^[a-z0-9._-]{1,128}$/u.test(rawCode) ? rawCode : "worker_failed";
|
|
228
|
-
const rawMessage = error instanceof Error ? error.message : String(error);
|
|
229
|
-
const errorMessage = rawMessage.replaceAll(TOKEN, "<redacted>").slice(0, 512) || "storage worker failed";
|
|
230
|
-
const status = WorkerFailureSchema.parse({
|
|
231
|
-
version: 1,
|
|
232
|
-
migrationId: identity.migrationId,
|
|
233
|
-
status: "failed",
|
|
234
|
-
errorCode,
|
|
235
|
-
errorMessage,
|
|
236
|
-
at: new Date().toISOString(),
|
|
237
|
-
});
|
|
238
|
-
await atomicPrivateWrite(storageWorkerFailurePath(identity.stateRoot, identity.migrationId), `${JSON.stringify(status, null, 2)}\n`);
|
|
239
|
-
}
|
|
240
|
-
export async function readStorageWorkerFailureStatus(stateRoot, migrationId) {
|
|
241
|
-
try {
|
|
242
|
-
return WorkerFailureSchema.parse(JSON.parse(await readFile(storageWorkerFailurePath(stateRoot, migrationId), "utf8")));
|
|
243
|
-
}
|
|
244
|
-
catch (error) {
|
|
245
|
-
if (error.code === "ENOENT")
|
|
246
|
-
return null;
|
|
247
|
-
throw new Error("Invalid storage worker failure status", { cause: error });
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
export async function readStorageWorkerHeartbeat(stateRoot, migrationId) {
|
|
251
|
-
try {
|
|
252
|
-
return WorkerHeartbeatSchema.parse(JSON.parse(await readFile(storageWorkerHeartbeatPath(stateRoot, migrationId), "utf8")));
|
|
253
|
-
}
|
|
254
|
-
catch (error) {
|
|
255
|
-
if (error.code === "ENOENT")
|
|
256
|
-
return null;
|
|
257
|
-
throw new Error("Invalid storage worker heartbeat", { cause: error });
|
|
258
|
-
}
|
|
259
|
-
}
|