@codetreker/daynight 0.21.8 → 0.21.11
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 +206 -28
- package/dist/api/client.d.ts +3 -1
- package/dist/api/client.js +12 -1
- package/dist/api/client.js.map +1 -1
- package/dist/api/parse.d.ts +2 -1
- package/dist/api/parse.js +8 -0
- package/dist/api/parse.js.map +1 -1
- package/dist/api/types.d.ts +7 -0
- package/dist/cli/commands.js +2 -0
- package/dist/cli/commands.js.map +1 -1
- package/dist/commands/worker/cleanup.d.ts +6 -0
- package/dist/commands/worker/cleanup.js +173 -0
- package/dist/commands/worker/cleanup.js.map +1 -0
- package/dist/commands/worker/config.d.ts +21 -0
- package/dist/commands/worker/config.js +144 -0
- package/dist/commands/worker/config.js.map +1 -0
- package/dist/commands/worker/coordinator.d.ts +34 -0
- package/dist/commands/worker/coordinator.js +508 -0
- package/dist/commands/worker/coordinator.js.map +1 -0
- package/dist/commands/worker/definition.d.ts +2 -0
- package/dist/commands/worker/definition.js +14 -0
- package/dist/commands/worker/definition.js.map +1 -0
- package/dist/commands/worker/diagnostics.d.ts +20 -0
- package/dist/commands/worker/diagnostics.js +56 -0
- package/dist/commands/worker/diagnostics.js.map +1 -0
- package/dist/commands/worker/execution.d.ts +41 -0
- package/dist/commands/worker/execution.js +255 -0
- package/dist/commands/worker/execution.js.map +1 -0
- package/dist/commands/worker/herdr/agents.d.ts +185 -0
- package/dist/commands/worker/herdr/agents.js +654 -0
- package/dist/commands/worker/herdr/agents.js.map +1 -0
- package/dist/commands/worker/herdr/arguments.d.ts +8 -0
- package/dist/commands/worker/herdr/arguments.js +58 -0
- package/dist/commands/worker/herdr/arguments.js.map +1 -0
- package/dist/commands/worker/herdr/command.d.ts +22 -0
- package/dist/commands/worker/herdr/command.js +115 -0
- package/dist/commands/worker/herdr/command.js.map +1 -0
- package/dist/commands/worker/herdr/instance.d.ts +56 -0
- package/dist/commands/worker/herdr/instance.js +322 -0
- package/dist/commands/worker/herdr/instance.js.map +1 -0
- package/dist/commands/worker/herdr/preflight.d.ts +40 -0
- package/dist/commands/worker/herdr/preflight.js +251 -0
- package/dist/commands/worker/herdr/preflight.js.map +1 -0
- package/dist/commands/worker/herdr/rpc.d.ts +29 -0
- package/dist/commands/worker/herdr/rpc.js +186 -0
- package/dist/commands/worker/herdr/rpc.js.map +1 -0
- package/dist/commands/worker/herdr.d.ts +95 -0
- package/dist/commands/worker/herdr.js +35 -0
- package/dist/commands/worker/herdr.js.map +1 -0
- package/dist/commands/worker/index.d.ts +10 -0
- package/dist/commands/worker/index.js +14 -0
- package/dist/commands/worker/index.js.map +1 -0
- package/dist/commands/worker/prompts.d.ts +4 -0
- package/dist/commands/worker/prompts.js +64 -0
- package/dist/commands/worker/prompts.js.map +1 -0
- package/dist/commands/worker/remote.d.ts +18 -0
- package/dist/commands/worker/remote.js +134 -0
- package/dist/commands/worker/remote.js.map +1 -0
- package/dist/commands/worker/runtime.d.ts +8 -0
- package/dist/commands/worker/runtime.js +246 -0
- package/dist/commands/worker/runtime.js.map +1 -0
- package/dist/commands/worker/store.d.ts +55 -5
- package/dist/commands/worker/store.js +381 -26
- package/dist/commands/worker/store.js.map +1 -1
- package/dist/commands/worker/types.d.ts +37 -1
- package/dist/commands/worker/worktrees.d.ts +1 -0
- package/dist/commands/worker/worktrees.js +9 -0
- package/dist/commands/worker/worktrees.js.map +1 -1
- package/dist/config/document.d.ts +1 -1
- package/dist/config/document.js +1 -0
- package/dist/config/document.js.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
import { closeSync, openSync } from "node:fs";
|
|
2
|
+
import { lstat, mkdir, readFile } from "node:fs/promises";
|
|
3
|
+
import { Socket } from "node:net";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { performance } from "node:perf_hooks";
|
|
6
|
+
import { gte, valid } from "semver";
|
|
7
|
+
import { replaceFileAtomically } from "../../../platform/files.js";
|
|
8
|
+
import { createHerdrRpcClient, herdrIpcAddress } from "./rpc.js";
|
|
9
|
+
import { runHerdrCommand, spawnHerdrProcess, terminateOwnedHerdrProcess } from "./command.js";
|
|
10
|
+
const session = "w";
|
|
11
|
+
const managedConfiguration = "onboarding = false\n\n[session]\nresume_agents_on_restore = false\n";
|
|
12
|
+
const missing = (error) => error instanceof Error && "code" in error && error.code === "ENOENT";
|
|
13
|
+
const absentConnection = (error) => error instanceof Error && "code" in error && (error.code === "ENOENT" || error.code === "ECONNREFUSED");
|
|
14
|
+
const inheritedIdentity = new Set([
|
|
15
|
+
"HERDR_SOCKET_PATH", "HERDR_CLIENT_SOCKET_PATH", "HERDR_SESSION", "HERDR_STARTUP_CWD", "HERDR_ENV",
|
|
16
|
+
"HERDR_PANE_ID", "HERDR_TAB_ID", "HERDR_WORKSPACE_ID", "HERDR_TERMINAL_ID",
|
|
17
|
+
"HERDR_ACTIVE_PANE_ID", "HERDR_ACTIVE_TAB_ID", "HERDR_ACTIVE_WORKSPACE_ID", "HERDR_ACTIVE_PANE_CWD", "HERDR_PANE_RUNTIME_ID",
|
|
18
|
+
"CODEX_THREAD_ID", "CODEX_SESSION_ID", "CODEX_TOOL_CALL_ID",
|
|
19
|
+
]);
|
|
20
|
+
export const resolveHerdrInstancePaths = (worker, platform = process.platform) => {
|
|
21
|
+
const paths = platform === "win32" ? path.win32 : path.posix;
|
|
22
|
+
if (!paths.isAbsolute(worker.herdrDirectory) || !paths.isAbsolute(worker.logsDirectory))
|
|
23
|
+
throw new Error("Worker Herdr and log directories must be absolute.");
|
|
24
|
+
const privateDirectory = worker.herdrDirectory;
|
|
25
|
+
const sessionDirectory = paths.join(privateDirectory, "c", "herdr", "sessions", session);
|
|
26
|
+
const apiEndpoint = paths.join(sessionDirectory, "herdr.sock");
|
|
27
|
+
const clientEndpoint = paths.join(sessionDirectory, "herdr-client.sock");
|
|
28
|
+
for (const endpoint of [apiEndpoint, clientEndpoint]) {
|
|
29
|
+
if (/[\r\n\0]/.test(endpoint))
|
|
30
|
+
throw new Error("The private Herdr endpoint contains a line break or NUL.");
|
|
31
|
+
if (platform === "win32") {
|
|
32
|
+
if (herdrIpcAddress(endpoint, platform).length > 256)
|
|
33
|
+
throw new Error(`The private Herdr pipe exceeds 256 characters: ${endpoint}.`);
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
const maximum = platform === "darwin" ? 103 : 107;
|
|
37
|
+
if (Buffer.byteLength(endpoint, "utf8") > maximum)
|
|
38
|
+
throw new Error(`The private Herdr socket exceeds ${maximum} UTF-8 bytes: ${endpoint}.`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return { privateDirectory, configurationFile: paths.join(privateDirectory, "config.toml"), configHome: paths.join(privateDirectory, "c"), stateHome: paths.join(privateDirectory, "s"), shellHistoryFile: paths.join(privateDirectory, "shell.history"), sessionDirectory, apiEndpoint, clientEndpoint,
|
|
42
|
+
stdoutLogFile: paths.join(worker.logsDirectory, "herdr.stdout.log"), stderrLogFile: paths.join(worker.logsDirectory, "herdr.stderr.log") };
|
|
43
|
+
};
|
|
44
|
+
export const createHerdrEnvironment = (paths, inherited) => ({
|
|
45
|
+
...Object.fromEntries(Object.entries(inherited).filter(([name]) => !inheritedIdentity.has(name.toUpperCase()))),
|
|
46
|
+
XDG_CONFIG_HOME: paths.configHome,
|
|
47
|
+
XDG_STATE_HOME: paths.stateHome,
|
|
48
|
+
HERDR_CONFIG_PATH: paths.configurationFile,
|
|
49
|
+
HISTFILE: paths.shellHistoryFile,
|
|
50
|
+
});
|
|
51
|
+
const bounded = (parent, maximumMs) => {
|
|
52
|
+
parent.check();
|
|
53
|
+
const milliseconds = Math.max(1, Math.ceil(Math.min(maximumMs, parent.remainingMs())));
|
|
54
|
+
const deadline = performance.now() + milliseconds;
|
|
55
|
+
const controller = new AbortController();
|
|
56
|
+
const abort = () => { controller.abort(parent.signal.reason); };
|
|
57
|
+
const timer = setTimeout(() => controller.abort(new Error("The private Herdr operation deadline elapsed.")), milliseconds);
|
|
58
|
+
parent.signal.addEventListener("abort", abort, { once: true });
|
|
59
|
+
if (parent.signal.aborted)
|
|
60
|
+
abort();
|
|
61
|
+
const check = () => {
|
|
62
|
+
parent.check();
|
|
63
|
+
if (controller.signal.aborted)
|
|
64
|
+
throw controller.signal.reason;
|
|
65
|
+
if (performance.now() >= deadline)
|
|
66
|
+
throw new Error("The private Herdr operation deadline elapsed.");
|
|
67
|
+
};
|
|
68
|
+
return {
|
|
69
|
+
signal: controller.signal,
|
|
70
|
+
limits: { ...parent.limits, totalMs: milliseconds, requestMs: Math.min(milliseconds, parent.limits.requestMs) },
|
|
71
|
+
check,
|
|
72
|
+
remainingMs: () => { check(); return Math.max(0, Math.min(parent.remainingMs(), deadline - performance.now())); },
|
|
73
|
+
consume: (bytes) => { check(); parent.consume(bytes); },
|
|
74
|
+
dispose: () => { clearTimeout(timer); parent.signal.removeEventListener("abort", abort); },
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
const pause = async (operation) => { operation.check(); await new Promise((resolve) => setTimeout(resolve, Math.min(25, operation.remainingMs()))); operation.check(); };
|
|
78
|
+
const observeStartup = (startup, operation) => new Promise((resolve, reject) => {
|
|
79
|
+
operation.check();
|
|
80
|
+
const done = (outcome) => {
|
|
81
|
+
clearTimeout(timer);
|
|
82
|
+
operation.signal.removeEventListener("abort", abort);
|
|
83
|
+
if ("error" in outcome)
|
|
84
|
+
reject(outcome.error);
|
|
85
|
+
else
|
|
86
|
+
resolve(outcome.result);
|
|
87
|
+
};
|
|
88
|
+
const abort = () => done({ error: operation.signal.reason });
|
|
89
|
+
const timer = setTimeout(() => done({ error: new Error("The Herdr startup observer deadline elapsed.") }), Math.max(1, Math.ceil(operation.remainingMs())));
|
|
90
|
+
operation.signal.addEventListener("abort", abort, { once: true });
|
|
91
|
+
if (operation.signal.aborted)
|
|
92
|
+
abort();
|
|
93
|
+
startup.then((result) => done({ result }), (error) => done({ error }));
|
|
94
|
+
});
|
|
95
|
+
const probeEndpoint = (endpoint, operation) => new Promise((resolve, reject) => {
|
|
96
|
+
operation.check();
|
|
97
|
+
const socket = new Socket();
|
|
98
|
+
let outcome;
|
|
99
|
+
const finish = (value) => { if (outcome !== undefined)
|
|
100
|
+
return; outcome = value; socket.destroy(); };
|
|
101
|
+
const abort = () => { finish(operation.signal.reason instanceof Error ? operation.signal.reason : new Error("Herdr endpoint probe cancelled.", { cause: operation.signal.reason })); };
|
|
102
|
+
const timer = setTimeout(() => finish(new Error(`Cannot determine whether private Herdr endpoint ${endpoint} is available: connection deadline elapsed.`)), Math.max(1, Math.ceil(Math.min(1_000, operation.remainingMs()))));
|
|
103
|
+
socket.once("connect", () => finish(true));
|
|
104
|
+
socket.once("error", (error) => finish(absentConnection(error) ? false : new Error(`Cannot inspect private Herdr endpoint ${endpoint}.`, { cause: error })));
|
|
105
|
+
socket.once("close", () => {
|
|
106
|
+
clearTimeout(timer);
|
|
107
|
+
operation.signal.removeEventListener("abort", abort);
|
|
108
|
+
if (outcome instanceof Error)
|
|
109
|
+
reject(outcome);
|
|
110
|
+
else if (outcome !== undefined)
|
|
111
|
+
resolve(outcome);
|
|
112
|
+
else
|
|
113
|
+
reject(new Error(`Private Herdr endpoint ${endpoint} closed without an observation.`));
|
|
114
|
+
});
|
|
115
|
+
operation.signal.addEventListener("abort", abort, { once: true });
|
|
116
|
+
if (operation.signal.aborted)
|
|
117
|
+
abort();
|
|
118
|
+
else
|
|
119
|
+
try {
|
|
120
|
+
socket.connect({ path: herdrIpcAddress(endpoint) });
|
|
121
|
+
}
|
|
122
|
+
catch (cause) {
|
|
123
|
+
finish(new Error(`Cannot connect to private Herdr endpoint ${endpoint}.`, { cause }));
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
const ordinaryDirectory = async (directory) => {
|
|
127
|
+
await mkdir(directory, { recursive: true, mode: 0o700 });
|
|
128
|
+
const entry = await lstat(directory);
|
|
129
|
+
if (!entry.isDirectory() || entry.isSymbolicLink())
|
|
130
|
+
throw new Error(`Private Herdr directory ${directory} must be an ordinary directory.`);
|
|
131
|
+
};
|
|
132
|
+
const ensureConfiguration = async (paths) => {
|
|
133
|
+
await ordinaryDirectory(paths.privateDirectory);
|
|
134
|
+
try {
|
|
135
|
+
const entry = await lstat(paths.configurationFile);
|
|
136
|
+
if (!entry.isFile() || entry.isSymbolicLink())
|
|
137
|
+
throw new Error(`Private Herdr configuration ${paths.configurationFile} must be an ordinary file.`);
|
|
138
|
+
if (await readFile(paths.configurationFile, "utf8") !== managedConfiguration)
|
|
139
|
+
throw new Error(`Private Herdr configuration ${paths.configurationFile} differs from the managed configuration; inspect it before starting the worker.`);
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
if (!missing(error))
|
|
143
|
+
throw error;
|
|
144
|
+
await replaceFileAtomically(paths.configurationFile, managedConfiguration, 0o600);
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
const record = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
148
|
+
const compatible = (pong) => {
|
|
149
|
+
if (pong.type !== "pong" || typeof pong.version !== "string" || valid(pong.version) === null || !gte(pong.version, "0.9.5") || pong.protocol !== 22 || !record(pong.capabilities)) {
|
|
150
|
+
throw new Error("The private Herdr instance must provide version 0.9.5 or newer, protocol 22 and server capabilities.");
|
|
151
|
+
}
|
|
152
|
+
return { version: pong.version, protocol: 22 };
|
|
153
|
+
};
|
|
154
|
+
const observeChild = (child) => {
|
|
155
|
+
const owned = { child, closed: false, code: null, signal: null, error: null };
|
|
156
|
+
child.once("error", (error) => { owned.error = error; });
|
|
157
|
+
child.once("close", (code, signal) => { owned.closed = true; owned.code = code; owned.signal = signal; });
|
|
158
|
+
return owned;
|
|
159
|
+
};
|
|
160
|
+
const killOwnedChild = (owned) => {
|
|
161
|
+
if (owned.closed || owned.child.pid === undefined)
|
|
162
|
+
return;
|
|
163
|
+
terminateOwnedHerdrProcess(owned.child);
|
|
164
|
+
};
|
|
165
|
+
export const createHerdrInstance = (options) => {
|
|
166
|
+
const paths = resolveHerdrInstancePaths(options.paths);
|
|
167
|
+
const executable = options.executable === undefined ? "herdr" : options.executable;
|
|
168
|
+
if (executable.trim() === "" || /[\r\n\0]/.test(executable))
|
|
169
|
+
throw new Error("The Herdr executable must be nonempty without line breaks or NUL.");
|
|
170
|
+
const environment = createHerdrEnvironment(paths, options.environment === undefined ? process.env : options.environment);
|
|
171
|
+
const attachmentEnvironment = { XDG_CONFIG_HOME: paths.configHome, XDG_STATE_HOME: paths.stateHome, HERDR_CONFIG_PATH: paths.configurationFile, HISTFILE: paths.shellHistoryFile };
|
|
172
|
+
for (const key of ["HOME", "USERPROFILE", "CODEX_HOME", "CODEX_SQLITE_HOME", "COPILOT_HOME"]) {
|
|
173
|
+
if (environment[key] !== undefined)
|
|
174
|
+
attachmentEnvironment[key] = environment[key];
|
|
175
|
+
}
|
|
176
|
+
const start = options.spawnProcess === undefined ? spawnHerdrProcess : options.spawnProcess;
|
|
177
|
+
const rpc = createHerdrRpcClient(paths.apiEndpoint);
|
|
178
|
+
let owned = null;
|
|
179
|
+
let starting = null;
|
|
180
|
+
const endpoints = async (operation) => {
|
|
181
|
+
const results = await Promise.allSettled([probeEndpoint(paths.apiEndpoint, operation), probeEndpoint(paths.clientEndpoint, operation)]);
|
|
182
|
+
const failures = results.filter((result) => result.status === "rejected").map((result) => result.reason);
|
|
183
|
+
if (failures.length === 1)
|
|
184
|
+
throw failures[0];
|
|
185
|
+
if (failures.length > 1)
|
|
186
|
+
throw new AggregateError(failures, "Both private Herdr endpoints could not be inspected.");
|
|
187
|
+
const [api, client] = results;
|
|
188
|
+
if (api?.status !== "fulfilled" || client?.status !== "fulfilled")
|
|
189
|
+
throw new Error("Private Herdr endpoint inspection was incomplete.");
|
|
190
|
+
return { api: api.value, client: client.value };
|
|
191
|
+
};
|
|
192
|
+
const ready = async (operation) => {
|
|
193
|
+
const version = compatible(await rpc.request("ping", {}, operation));
|
|
194
|
+
const result = await rpc.request("session.snapshot", {}, operation);
|
|
195
|
+
if (result.type !== "session_snapshot" || !record(result.snapshot))
|
|
196
|
+
throw new Error("The private Herdr instance did not return its restored session snapshot.");
|
|
197
|
+
return { ...version, snapshot: result.snapshot };
|
|
198
|
+
};
|
|
199
|
+
const version = async (operation) => {
|
|
200
|
+
const result = await runHerdrCommand({ file: executable, args: ["--version"], environment }, operation, start);
|
|
201
|
+
const match = /^herdr\s+(\S+)\s*$/.exec(result.stdout);
|
|
202
|
+
if (match === null || valid(match[1]) === null || !gte(match[1], "0.9.5"))
|
|
203
|
+
throw new Error("Herdr 0.9.5 or newer is required before starting the private instance.");
|
|
204
|
+
};
|
|
205
|
+
const ensure = async (operation) => {
|
|
206
|
+
operation.check();
|
|
207
|
+
if (starting !== null)
|
|
208
|
+
return observeStartup(starting, operation);
|
|
209
|
+
starting = (async () => {
|
|
210
|
+
const scope = bounded(operation, 30_000);
|
|
211
|
+
let startedHere = null;
|
|
212
|
+
try {
|
|
213
|
+
await ensureConfiguration(paths);
|
|
214
|
+
const before = await endpoints(scope);
|
|
215
|
+
if (before.api && before.client)
|
|
216
|
+
return { ...await ready(scope), reconnected: true };
|
|
217
|
+
if (before.api || before.client)
|
|
218
|
+
throw new Error("The private Herdr instance has only one reachable endpoint; its startup or shutdown remains unconfirmed.");
|
|
219
|
+
if (owned !== null && !owned.closed)
|
|
220
|
+
throw new Error("The owned private Herdr process is still running without both endpoints; its shutdown remains unconfirmed.");
|
|
221
|
+
await version(scope);
|
|
222
|
+
await ordinaryDirectory(path.dirname(paths.stdoutLogFile));
|
|
223
|
+
const stdout = openSync(paths.stdoutLogFile, "a", 0o600);
|
|
224
|
+
let stderr;
|
|
225
|
+
try {
|
|
226
|
+
stderr = openSync(paths.stderrLogFile, "a", 0o600);
|
|
227
|
+
owned = observeChild(start(executable, ["--session", session, "server"], { env: environment, detached: true, windowsHide: true, stdio: ["ignore", stdout, stderr] }));
|
|
228
|
+
startedHere = owned;
|
|
229
|
+
}
|
|
230
|
+
finally {
|
|
231
|
+
closeSync(stdout);
|
|
232
|
+
if (stderr !== undefined)
|
|
233
|
+
closeSync(stderr);
|
|
234
|
+
}
|
|
235
|
+
while (true) {
|
|
236
|
+
const observed = await endpoints(scope);
|
|
237
|
+
if (observed.api && observed.client) {
|
|
238
|
+
const result = await ready(scope);
|
|
239
|
+
owned.child.unref();
|
|
240
|
+
return { ...result, reconnected: owned.closed };
|
|
241
|
+
}
|
|
242
|
+
if (owned.error !== null || owned.closed)
|
|
243
|
+
throw new Error(`The private Herdr process exited before readiness: exit=${String(owned.code)}, signal=${String(owned.signal)}.`, { cause: owned.error });
|
|
244
|
+
await pause(scope);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
catch (error) {
|
|
248
|
+
if (startedHere !== null && !startedHere.closed) {
|
|
249
|
+
try {
|
|
250
|
+
killOwnedChild(startedHere);
|
|
251
|
+
}
|
|
252
|
+
catch (cause) {
|
|
253
|
+
throw new AggregateError([error, cause], "Private Herdr startup failed and its owned process could not be terminated.");
|
|
254
|
+
}
|
|
255
|
+
const deadline = performance.now() + 2_000;
|
|
256
|
+
while (!startedHere.closed && performance.now() < deadline)
|
|
257
|
+
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
258
|
+
if (!startedHere.closed)
|
|
259
|
+
throw new AggregateError([error, new Error("The owned Herdr process did not close after failed startup.")], "Private Herdr startup and process cleanup failed.");
|
|
260
|
+
}
|
|
261
|
+
throw error;
|
|
262
|
+
}
|
|
263
|
+
finally {
|
|
264
|
+
scope.dispose();
|
|
265
|
+
}
|
|
266
|
+
})();
|
|
267
|
+
try {
|
|
268
|
+
return await starting;
|
|
269
|
+
}
|
|
270
|
+
finally {
|
|
271
|
+
starting = null;
|
|
272
|
+
}
|
|
273
|
+
};
|
|
274
|
+
return {
|
|
275
|
+
paths, environment, rpc,
|
|
276
|
+
attachment: { executable, arguments: ["--session", session], environment: attachmentEnvironment, unsetEnvironment: [...inheritedIdentity] },
|
|
277
|
+
ensure,
|
|
278
|
+
stop: async (operation) => {
|
|
279
|
+
const scope = bounded(operation, 15_000);
|
|
280
|
+
let requestFailure;
|
|
281
|
+
let probeFailure;
|
|
282
|
+
let submitted = false;
|
|
283
|
+
try {
|
|
284
|
+
while (true) {
|
|
285
|
+
let current;
|
|
286
|
+
try {
|
|
287
|
+
current = await endpoints(scope);
|
|
288
|
+
}
|
|
289
|
+
catch (error) {
|
|
290
|
+
probeFailure = error;
|
|
291
|
+
await pause(scope);
|
|
292
|
+
continue;
|
|
293
|
+
}
|
|
294
|
+
if (!current.api && !current.client && (owned === null || owned.closed))
|
|
295
|
+
return { apiClosed: true, clientClosed: true, ownedChildClosed: owned === null ? null : true };
|
|
296
|
+
if (current.api && !submitted) {
|
|
297
|
+
submitted = true;
|
|
298
|
+
try {
|
|
299
|
+
const response = await rpc.request("server.stop", {}, scope);
|
|
300
|
+
if (response.type !== "ok")
|
|
301
|
+
throw new Error("Private Herdr returned an invalid stop acknowledgement.");
|
|
302
|
+
}
|
|
303
|
+
catch (error) {
|
|
304
|
+
requestFailure = error;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
await pause(scope);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
catch (error) {
|
|
311
|
+
const failures = [requestFailure, probeFailure].filter((failure) => failure !== undefined);
|
|
312
|
+
if (failures.length !== 0)
|
|
313
|
+
throw new AggregateError([...failures, error], "Private Herdr stop remained unconfirmed.");
|
|
314
|
+
throw error;
|
|
315
|
+
}
|
|
316
|
+
finally {
|
|
317
|
+
scope.dispose();
|
|
318
|
+
}
|
|
319
|
+
},
|
|
320
|
+
};
|
|
321
|
+
};
|
|
322
|
+
//# sourceMappingURL=instance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instance.js","sourceRoot":"","sources":["../../../../src/commands/worker/herdr/instance.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { Operation } from "../../../api/operation.js";
|
|
2
|
+
import type { HerdrCommand, HerdrCommandResult } from "./command.js";
|
|
3
|
+
import type { HerdrRpcClient } from "./rpc.js";
|
|
4
|
+
type NativeAgent = "codex" | "copilot";
|
|
5
|
+
export type HerdrNativeStart = {
|
|
6
|
+
context: {
|
|
7
|
+
cwd: string;
|
|
8
|
+
};
|
|
9
|
+
configuration: {
|
|
10
|
+
agent: NativeAgent;
|
|
11
|
+
model: string | null;
|
|
12
|
+
args: readonly string[];
|
|
13
|
+
};
|
|
14
|
+
resumeSessionId?: string;
|
|
15
|
+
};
|
|
16
|
+
export type NativeHistoryEvidence = {
|
|
17
|
+
path: string;
|
|
18
|
+
sessionId: string;
|
|
19
|
+
cwd: string;
|
|
20
|
+
};
|
|
21
|
+
export type HerdrNativePreflight = {
|
|
22
|
+
agent: NativeAgent;
|
|
23
|
+
version: string;
|
|
24
|
+
nativeHome: string;
|
|
25
|
+
sqliteHome: string | null;
|
|
26
|
+
integrationConfigured: true;
|
|
27
|
+
history: NativeHistoryEvidence | null;
|
|
28
|
+
};
|
|
29
|
+
type CommandRunner = (command: HerdrCommand, operation: Operation) => Promise<HerdrCommandResult>;
|
|
30
|
+
export declare const createHerdrPreflight: (options: {
|
|
31
|
+
rpc: Pick<HerdrRpcClient, "request">;
|
|
32
|
+
environment: NodeJS.ProcessEnv;
|
|
33
|
+
homeDirectory: string;
|
|
34
|
+
platform?: NodeJS.Platform;
|
|
35
|
+
runCommand?: CommandRunner;
|
|
36
|
+
}) => {
|
|
37
|
+
verifyStart: (input: HerdrNativeStart, operation: Operation) => Promise<HerdrNativePreflight>;
|
|
38
|
+
};
|
|
39
|
+
export type HerdrPreflight = ReturnType<typeof createHerdrPreflight>;
|
|
40
|
+
export {};
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { open, readdir, realpath } from "node:fs/promises";
|
|
3
|
+
import { parse as parseYaml } from "yaml";
|
|
4
|
+
import { canonicalId } from "../../../api/parse.js";
|
|
5
|
+
import { validateHerdrAgentArguments } from "./arguments.js";
|
|
6
|
+
import { runHerdrCommand } from "./command.js";
|
|
7
|
+
const metadataLimit = 1_048_576;
|
|
8
|
+
const mapping = (value, label) => {
|
|
9
|
+
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
10
|
+
throw new Error(`${label} must be an object.`);
|
|
11
|
+
return value;
|
|
12
|
+
};
|
|
13
|
+
const json = (source, label) => {
|
|
14
|
+
let decoded;
|
|
15
|
+
try {
|
|
16
|
+
decoded = JSON.parse(source);
|
|
17
|
+
}
|
|
18
|
+
// Parser exceptions can echo private configuration bytes; diagnostics retain the failing subject without that excerpt.
|
|
19
|
+
catch {
|
|
20
|
+
throw new Error(`${label} is not valid JSON; inspect the native configuration without exposing its contents.`);
|
|
21
|
+
}
|
|
22
|
+
return mapping(decoded, label);
|
|
23
|
+
};
|
|
24
|
+
const absolute = (value, label) => {
|
|
25
|
+
if (!path.isAbsolute(value) || /[\0\r\n]/.test(value))
|
|
26
|
+
throw new Error(`${label} must be an absolute path; expand native home overrides before starting the worker.`);
|
|
27
|
+
return path.normalize(value);
|
|
28
|
+
};
|
|
29
|
+
const nativeHome = (agent, environment, home) => {
|
|
30
|
+
const key = agent === "codex" ? "CODEX_HOME" : "COPILOT_HOME";
|
|
31
|
+
const value = environment[key];
|
|
32
|
+
return value === undefined ? path.join(home, `.${agent}`) : absolute(value, key);
|
|
33
|
+
};
|
|
34
|
+
const readMetadata = async (file, operation, firstLine = false) => {
|
|
35
|
+
operation.check();
|
|
36
|
+
const handle = await open(file, "r");
|
|
37
|
+
try {
|
|
38
|
+
const chunks = [];
|
|
39
|
+
let bytes = 0;
|
|
40
|
+
while (true) {
|
|
41
|
+
operation.check();
|
|
42
|
+
const buffer = Buffer.alloc(16_384);
|
|
43
|
+
const result = await handle.read(buffer, 0, buffer.length, null);
|
|
44
|
+
if (result.bytesRead === 0)
|
|
45
|
+
break;
|
|
46
|
+
operation.consume(result.bytesRead);
|
|
47
|
+
const chunk = buffer.subarray(0, result.bytesRead);
|
|
48
|
+
const newline = firstLine ? chunk.indexOf(0x0a) : -1;
|
|
49
|
+
const selected = newline < 0 ? chunk : chunk.subarray(0, newline);
|
|
50
|
+
bytes += selected.length;
|
|
51
|
+
if (bytes > metadataLimit)
|
|
52
|
+
throw new Error(`Native metadata ${file} exceeds the supported one MiB header/configuration limit.`);
|
|
53
|
+
chunks.push(selected);
|
|
54
|
+
if (newline >= 0)
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
operation.check();
|
|
58
|
+
return new TextDecoder("utf-8", { fatal: true }).decode(Buffer.concat(chunks));
|
|
59
|
+
}
|
|
60
|
+
finally {
|
|
61
|
+
await handle.close();
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
const sameCwd = async (actual, expected) => {
|
|
65
|
+
if (typeof actual !== "string" || !path.isAbsolute(actual))
|
|
66
|
+
throw new Error("The original native history has no absolute working directory.");
|
|
67
|
+
const [left, right] = await Promise.all([realpath(actual), realpath(expected)]);
|
|
68
|
+
if (left !== right)
|
|
69
|
+
throw new Error("The original native history belongs to a different working directory; it cannot resume this claim.");
|
|
70
|
+
return right;
|
|
71
|
+
};
|
|
72
|
+
const sessionId = (value) => {
|
|
73
|
+
const id = canonicalId(value);
|
|
74
|
+
if (id === null)
|
|
75
|
+
throw new Error("A native resume session must be an exact UUID.");
|
|
76
|
+
return id;
|
|
77
|
+
};
|
|
78
|
+
const codexHistory = async (root, id, cwd, operation) => {
|
|
79
|
+
const candidates = [];
|
|
80
|
+
let visited = 0;
|
|
81
|
+
const walk = async (directory, depth) => {
|
|
82
|
+
operation.check();
|
|
83
|
+
for (const entry of await readdir(directory, { withFileTypes: true })) {
|
|
84
|
+
operation.check();
|
|
85
|
+
if (++visited > 100_000)
|
|
86
|
+
throw new Error("The Codex history manifest scan exceeded its supported entry limit.");
|
|
87
|
+
const target = path.join(directory, entry.name);
|
|
88
|
+
if (entry.isDirectory() && depth < 3)
|
|
89
|
+
await walk(target, depth + 1);
|
|
90
|
+
else if (entry.isFile() && (entry.name.endsWith(`-${id}.jsonl`) || entry.name.endsWith(`-${id}.jsonl.gz`) || entry.name.endsWith(`-${id}.jsonl.zst`)))
|
|
91
|
+
candidates.push(target);
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
await walk(path.join(root, "sessions"), 0);
|
|
95
|
+
if (candidates.length !== 1)
|
|
96
|
+
throw new Error(`The original Codex session ${id} must have exactly one readable rollout manifest; found ${candidates.length}.`);
|
|
97
|
+
const file = candidates[0];
|
|
98
|
+
if (!file.endsWith(".jsonl"))
|
|
99
|
+
throw new Error("Compressed Codex rollout manifests are not supported by this adapter; retain the original native history and inspect its format.");
|
|
100
|
+
const event = json(await readMetadata(file, operation, true), "Codex session metadata");
|
|
101
|
+
const payload = mapping(event.payload, "Codex session metadata payload");
|
|
102
|
+
if (event.type !== "session_meta" || payload.id !== id)
|
|
103
|
+
throw new Error("The original Codex rollout manifest does not identify the requested session.");
|
|
104
|
+
return { path: file, sessionId: id, cwd: await sameCwd(payload.cwd, cwd) };
|
|
105
|
+
};
|
|
106
|
+
const copilotHistory = async (root, id, cwd, operation) => {
|
|
107
|
+
const directory = path.join(root, "session-state", id);
|
|
108
|
+
const workspaceFile = path.join(directory, "workspace.yaml");
|
|
109
|
+
const source = await readMetadata(workspaceFile, operation);
|
|
110
|
+
let decoded;
|
|
111
|
+
try {
|
|
112
|
+
decoded = parseYaml(source);
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
throw new Error("The original Copilot workspace metadata is invalid; inspect the native history without exposing its contents.");
|
|
116
|
+
}
|
|
117
|
+
const workspace = mapping(decoded, "Copilot workspace metadata");
|
|
118
|
+
if (workspace.id !== id)
|
|
119
|
+
throw new Error("The original Copilot workspace metadata does not identify the requested session.");
|
|
120
|
+
await sameCwd(workspace.cwd, cwd);
|
|
121
|
+
const file = path.join(directory, "events.jsonl");
|
|
122
|
+
const event = json(await readMetadata(file, operation, true), "Copilot session event");
|
|
123
|
+
const data = mapping(event.data, "Copilot session event data");
|
|
124
|
+
const context = mapping(data.context, "Copilot session event context");
|
|
125
|
+
if (event.type !== "session.start" || data.sessionId !== id)
|
|
126
|
+
throw new Error("The original Copilot event history does not identify the requested session.");
|
|
127
|
+
return { path: file, sessionId: id, cwd: await sameCwd(context.cwd, cwd) };
|
|
128
|
+
};
|
|
129
|
+
const hookCommand = (file, agent, platform) => {
|
|
130
|
+
const command = platform === "win32" ? `powershell -NoProfile -ExecutionPolicy Bypass -File "${file.replaceAll('"', '\\"')}"` : `bash '${file.replaceAll("'", "'\"'\"'")}'`;
|
|
131
|
+
return agent === "codex" ? `${command} session` : command;
|
|
132
|
+
};
|
|
133
|
+
const configuredHook = (hooks, expected, agent, platform) => {
|
|
134
|
+
const entries = hooks[agent === "codex" ? "SessionStart" : "sessionStart"];
|
|
135
|
+
if (!Array.isArray(entries))
|
|
136
|
+
return false;
|
|
137
|
+
return entries.some((value) => {
|
|
138
|
+
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
139
|
+
return false;
|
|
140
|
+
const entry = value;
|
|
141
|
+
if (entry.matcher !== undefined && entry.matcher !== "")
|
|
142
|
+
return false;
|
|
143
|
+
const commands = agent === "codex" ? entry.hooks : [entry];
|
|
144
|
+
return Array.isArray(commands) && commands.some((item) => {
|
|
145
|
+
if (typeof item !== "object" || item === null || Array.isArray(item))
|
|
146
|
+
return false;
|
|
147
|
+
const hook = item;
|
|
148
|
+
return hook.type === "command" && hook.enabled !== false && hook[agent === "codex" ? "command" : platform === "win32" ? "powershell" : "bash"] === expected;
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
};
|
|
152
|
+
const codexConfigurationArguments = (args) => {
|
|
153
|
+
const relevant = new Set(["-c", "--config", "--enable", "--disable", "-p", "--profile"]);
|
|
154
|
+
const selected = [];
|
|
155
|
+
let profile = false;
|
|
156
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
157
|
+
const argument = args[index];
|
|
158
|
+
const equals = argument.indexOf("=");
|
|
159
|
+
const option = equals < 0 ? argument : argument.slice(0, equals);
|
|
160
|
+
if (!relevant.has(option))
|
|
161
|
+
continue;
|
|
162
|
+
profile ||= option === "-p" || option === "--profile";
|
|
163
|
+
selected.push(argument);
|
|
164
|
+
if (equals < 0)
|
|
165
|
+
selected.push(args[++index]);
|
|
166
|
+
}
|
|
167
|
+
return { arguments: selected, profile };
|
|
168
|
+
};
|
|
169
|
+
export const createHerdrPreflight = (options) => {
|
|
170
|
+
const home = absolute(options.homeDirectory, "Native user home");
|
|
171
|
+
const platform = options.platform === undefined ? process.platform : options.platform;
|
|
172
|
+
const environment = { ...options.environment };
|
|
173
|
+
const runCommand = options.runCommand === undefined ? runHerdrCommand : options.runCommand;
|
|
174
|
+
return {
|
|
175
|
+
// Native manifests establish prerequisites; only the subsequent official hook report and actual resume establish runtime continuity.
|
|
176
|
+
verifyStart: async (input, operation) => {
|
|
177
|
+
operation.check();
|
|
178
|
+
const agent = input.configuration.agent;
|
|
179
|
+
if (agent !== "codex" && agent !== "copilot")
|
|
180
|
+
throw new Error("The native agent must be codex or copilot.");
|
|
181
|
+
const cwd = absolute(input.context.cwd, "Native working directory");
|
|
182
|
+
validateHerdrAgentArguments(agent, input.configuration.args);
|
|
183
|
+
const root = nativeHome(agent, environment, home);
|
|
184
|
+
const sqliteHome = agent === "codex" ? environment.CODEX_SQLITE_HOME === undefined ? root : absolute(environment.CODEX_SQLITE_HOME, "CODEX_SQLITE_HOME") : null;
|
|
185
|
+
const versionText = (await runCommand({ file: agent, args: ["--version"], environment, cwd }, operation)).stdout;
|
|
186
|
+
const versionMatch = agent === "codex" ? /^codex-cli (\d+\.\d+\.\d+)(?:\s|$)/m.exec(versionText) : /^GitHub Copilot CLI (\d+\.\d+\.\d+)(?:[.\s]|$)/m.exec(versionText);
|
|
187
|
+
if (versionMatch === null)
|
|
188
|
+
throw new Error(`Cannot identify the installed ${agent} executable version.`);
|
|
189
|
+
const integrations = await options.rpc.request("integration.list", {}, operation);
|
|
190
|
+
if (integrations.type !== "integration_list" || !Array.isArray(integrations.integrations))
|
|
191
|
+
throw new Error("Herdr returned invalid integration metadata.");
|
|
192
|
+
const installed = integrations.integrations.filter((value) => typeof value === "object" && value !== null && !Array.isArray(value) && value.target === agent);
|
|
193
|
+
if (installed.length !== 1 || installed[0].state !== "current")
|
|
194
|
+
throw new Error(`The official ${agent} Herdr integration is missing or outdated; inspect it with herdr integration list and configure it explicitly.`);
|
|
195
|
+
const runtimes = platform === "win32"
|
|
196
|
+
? [{ file: "powershell", args: ["-NoProfile", "-Command", "$PSVersionTable.PSVersion.ToString()"], version: /^\d+\.\d+/m }]
|
|
197
|
+
: [{ file: "bash", args: ["--version"], version: /^GNU bash, version /m }, { file: "python3", args: ["--version"], version: /^Python 3\./m }];
|
|
198
|
+
for (const runtime of runtimes) {
|
|
199
|
+
let output;
|
|
200
|
+
try {
|
|
201
|
+
output = (await runCommand({ file: runtime.file, args: runtime.args, environment, cwd }, operation)).stdout;
|
|
202
|
+
}
|
|
203
|
+
catch (cause) {
|
|
204
|
+
operation.check();
|
|
205
|
+
throw new Error(`The official ${agent} Herdr hook requires the ${runtime.file} runtime to be available.`, { cause });
|
|
206
|
+
}
|
|
207
|
+
if (!runtime.version.test(output))
|
|
208
|
+
throw new Error(`Cannot identify the ${runtime.file} runtime required by the official ${agent} Herdr hook.`);
|
|
209
|
+
}
|
|
210
|
+
const asset = path.join(root, ...(agent === "copilot" ? ["hooks"] : []), platform === "win32" ? "herdr-agent-state.ps1" : "herdr-agent-state.sh");
|
|
211
|
+
await readMetadata(asset, operation);
|
|
212
|
+
const expected = hookCommand(asset, agent, platform);
|
|
213
|
+
if (agent === "codex") {
|
|
214
|
+
const help = (await runCommand({ file: agent, args: ["--help"], environment, cwd }, operation)).stdout;
|
|
215
|
+
if (!help.includes("--no-daemon"))
|
|
216
|
+
throw new Error("This Codex executable lacks --no-daemon; a worker requires isolated native execution without a shared human daemon.");
|
|
217
|
+
const config = codexConfigurationArguments(input.configuration.args);
|
|
218
|
+
let features;
|
|
219
|
+
try {
|
|
220
|
+
features = (await runCommand({ file: agent, args: [...config.arguments, "features", "list"], environment, cwd }, operation)).stdout;
|
|
221
|
+
}
|
|
222
|
+
catch (cause) {
|
|
223
|
+
operation.check();
|
|
224
|
+
// Codex 0.164 rejects profile selection for this read-only command; checking its unrelated default configuration would be incorrect.
|
|
225
|
+
// https://github.com/openai/codex/blob/6aaac694803004a63c6f393d153c96d22521a6b9/codex-rs/cli/src/main.rs#L1977-L2003
|
|
226
|
+
if (config.profile)
|
|
227
|
+
throw new Error("Codex cannot verify effective hook configuration for the selected profile with its read-only features command; use supported explicit --config/--enable/--disable settings or a CLI with profile-aware feature inspection.", { cause });
|
|
228
|
+
throw cause;
|
|
229
|
+
}
|
|
230
|
+
if (!features.split(/\r?\n/).some((line) => /^hooks\s+\S+\s+true\s*$/.test(line)))
|
|
231
|
+
throw new Error("Codex hooks are disabled; enable the official SessionStart integration explicitly before running the worker.");
|
|
232
|
+
const file = json(await readMetadata(path.join(root, "hooks.json"), operation), "Codex hooks configuration");
|
|
233
|
+
if (!configuredHook(mapping(file.hooks, "Codex hooks configuration hooks"), expected, agent, platform))
|
|
234
|
+
throw new Error("Codex SessionStart does not invoke the installed official Herdr hook; configure and trust that hook explicitly.");
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
const effective = json((await runCommand({ file: agent, args: ["config", "hooks"], environment, cwd }, operation)).stdout, "Copilot effective hooks configuration");
|
|
238
|
+
if (!configuredHook(effective, expected, agent, platform))
|
|
239
|
+
throw new Error("Copilot SessionStart does not invoke the installed official Herdr hook; configure it explicitly.");
|
|
240
|
+
}
|
|
241
|
+
let history = null;
|
|
242
|
+
if (input.resumeSessionId !== undefined) {
|
|
243
|
+
const id = sessionId(input.resumeSessionId);
|
|
244
|
+
history = agent === "codex" ? await codexHistory(root, id, cwd, operation) : await copilotHistory(root, id, cwd, operation);
|
|
245
|
+
}
|
|
246
|
+
operation.check();
|
|
247
|
+
return { agent, version: versionMatch[1], nativeHome: root, sqliteHome, integrationConfigured: true, history };
|
|
248
|
+
},
|
|
249
|
+
};
|
|
250
|
+
};
|
|
251
|
+
//# sourceMappingURL=preflight.js.map
|