@zixt/host 0.0.74 → 0.0.76
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/dist/index.js +321 -220
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -16,22 +16,22 @@ import { fstatSync } from "node:fs";
|
|
|
16
16
|
import {
|
|
17
17
|
access as access2,
|
|
18
18
|
lstat as lstat5,
|
|
19
|
-
mkdir as
|
|
19
|
+
mkdir as mkdir5,
|
|
20
20
|
open as open4,
|
|
21
21
|
readFile as readFile6,
|
|
22
22
|
readlink,
|
|
23
23
|
readdir as readdir3,
|
|
24
24
|
rename as rename3,
|
|
25
|
-
rm as
|
|
25
|
+
rm as rm5,
|
|
26
26
|
symlink
|
|
27
27
|
} from "node:fs/promises";
|
|
28
|
-
import { basename as
|
|
28
|
+
import { basename as basename4, dirname as dirname5, isAbsolute as isAbsolute8, join as join8, relative as relative4, resolve as resolve5, sep as sep4 } from "node:path";
|
|
29
29
|
import { homedir as homedir2 } from "node:os";
|
|
30
30
|
|
|
31
31
|
// package.json
|
|
32
32
|
var package_default = {
|
|
33
33
|
name: "@zixt/host",
|
|
34
|
-
version: "0.0.
|
|
34
|
+
version: "0.0.76",
|
|
35
35
|
type: "module",
|
|
36
36
|
exports: {
|
|
37
37
|
".": "./src/client.ts",
|
|
@@ -21663,7 +21663,6 @@ var HostClient = class _HostClient {
|
|
|
21663
21663
|
this.runnerRuntimeFeatureActive = false;
|
|
21664
21664
|
this.hostConsoleFeatureActive = false;
|
|
21665
21665
|
this.opts.browser?.attach(null);
|
|
21666
|
-
void this.opts.browser?.closeAll("machine_offline");
|
|
21667
21666
|
if (code === CLOSE_CODES.revoked) {
|
|
21668
21667
|
this.opts.onStatus?.("revoked");
|
|
21669
21668
|
this.stopped = true;
|
|
@@ -24038,22 +24037,107 @@ function createReleaseStateStore(root) {
|
|
|
24038
24037
|
};
|
|
24039
24038
|
}
|
|
24040
24039
|
|
|
24040
|
+
// src/launcher-claim.ts
|
|
24041
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
24042
|
+
import { mkdir as mkdir3, rm as rm3 } from "node:fs/promises";
|
|
24043
|
+
import { createConnection, createServer } from "node:net";
|
|
24044
|
+
import { basename as basename3, dirname as dirname3, join as join6 } from "node:path";
|
|
24045
|
+
var PEER_PROBE_TIMEOUT_MS = 2e3;
|
|
24046
|
+
function machineLauncherClaimAddress(ownershipRoot, platform = process.platform) {
|
|
24047
|
+
if (platform !== "win32") {
|
|
24048
|
+
return join6(dirname3(ownershipRoot), `.${basename3(ownershipRoot)}-claim.sock`);
|
|
24049
|
+
}
|
|
24050
|
+
const digest = createHash2("sha256").update(ownershipRoot.toLowerCase()).digest("hex").slice(0, 32);
|
|
24051
|
+
return `\\\\.\\pipe\\zixt-host-launcher-${digest}`;
|
|
24052
|
+
}
|
|
24053
|
+
function describe4(error52) {
|
|
24054
|
+
const code = error52?.code;
|
|
24055
|
+
if (typeof code === "string" && code.length > 0) return code;
|
|
24056
|
+
return error52 instanceof Error ? error52.message : "unknown error";
|
|
24057
|
+
}
|
|
24058
|
+
function peerAnswers(address) {
|
|
24059
|
+
return new Promise((resolve17) => {
|
|
24060
|
+
const socket = createConnection(address);
|
|
24061
|
+
let settled = false;
|
|
24062
|
+
const finish = (answered) => {
|
|
24063
|
+
if (settled) return;
|
|
24064
|
+
settled = true;
|
|
24065
|
+
socket.destroy();
|
|
24066
|
+
resolve17(answered);
|
|
24067
|
+
};
|
|
24068
|
+
socket.setTimeout(PEER_PROBE_TIMEOUT_MS, () => finish(true));
|
|
24069
|
+
socket.once("connect", () => finish(true));
|
|
24070
|
+
socket.once("error", () => finish(false));
|
|
24071
|
+
});
|
|
24072
|
+
}
|
|
24073
|
+
function listen(address) {
|
|
24074
|
+
return new Promise((resolve17) => {
|
|
24075
|
+
const server = createServer((socket) => socket.destroy());
|
|
24076
|
+
const fail = (error52) => {
|
|
24077
|
+
server.close();
|
|
24078
|
+
resolve17({ error: error52 });
|
|
24079
|
+
};
|
|
24080
|
+
server.once("error", fail);
|
|
24081
|
+
server.listen(address, () => {
|
|
24082
|
+
server.off("error", fail);
|
|
24083
|
+
server.on("error", () => {
|
|
24084
|
+
});
|
|
24085
|
+
server.unref();
|
|
24086
|
+
resolve17({ server });
|
|
24087
|
+
});
|
|
24088
|
+
});
|
|
24089
|
+
}
|
|
24090
|
+
async function claimMachineLauncher(ownershipRoot, platform = process.platform) {
|
|
24091
|
+
const address = machineLauncherClaimAddress(ownershipRoot, platform);
|
|
24092
|
+
if (platform !== "win32") {
|
|
24093
|
+
try {
|
|
24094
|
+
await mkdir3(dirname3(address), { recursive: true, mode: 448 });
|
|
24095
|
+
} catch (error52) {
|
|
24096
|
+
return { kind: "unavailable", reason: describe4(error52) };
|
|
24097
|
+
}
|
|
24098
|
+
}
|
|
24099
|
+
for (let attempt = 0; attempt < 2; attempt++) {
|
|
24100
|
+
const outcome = await listen(address);
|
|
24101
|
+
if ("server" in outcome) {
|
|
24102
|
+
const { server } = outcome;
|
|
24103
|
+
return {
|
|
24104
|
+
kind: "held",
|
|
24105
|
+
release: async () => {
|
|
24106
|
+
await new Promise((resolve17) => server.close(() => resolve17()));
|
|
24107
|
+
if (platform !== "win32") await rm3(address, { force: true }).catch(() => {
|
|
24108
|
+
});
|
|
24109
|
+
}
|
|
24110
|
+
};
|
|
24111
|
+
}
|
|
24112
|
+
if (outcome.error.code !== "EADDRINUSE") {
|
|
24113
|
+
return { kind: "unavailable", reason: describe4(outcome.error) };
|
|
24114
|
+
}
|
|
24115
|
+
if (platform === "win32" || await peerAnswers(address)) return { kind: "busy" };
|
|
24116
|
+
try {
|
|
24117
|
+
await rm3(address, { force: true });
|
|
24118
|
+
} catch (error52) {
|
|
24119
|
+
return { kind: "unavailable", reason: describe4(error52) };
|
|
24120
|
+
}
|
|
24121
|
+
}
|
|
24122
|
+
return { kind: "busy" };
|
|
24123
|
+
}
|
|
24124
|
+
|
|
24041
24125
|
// src/runners/run-artifacts.ts
|
|
24042
24126
|
import { spawn as spawn4 } from "node:child_process";
|
|
24043
24127
|
import {
|
|
24044
24128
|
chmod as chmod2,
|
|
24045
24129
|
lstat as lstat4,
|
|
24046
|
-
mkdir as
|
|
24130
|
+
mkdir as mkdir4,
|
|
24047
24131
|
open as open3,
|
|
24048
24132
|
readdir as readdir2,
|
|
24049
24133
|
readFile as readFile5,
|
|
24050
24134
|
realpath as realpath3,
|
|
24051
24135
|
rename as rename2,
|
|
24052
|
-
rm as
|
|
24136
|
+
rm as rm4,
|
|
24053
24137
|
writeFile
|
|
24054
24138
|
} from "node:fs/promises";
|
|
24055
24139
|
import { homedir } from "node:os";
|
|
24056
|
-
import { dirname as
|
|
24140
|
+
import { dirname as dirname4, isAbsolute as isAbsolute7, join as join7, relative as relative3, resolve as resolve4, sep as sep3, win32 as win322 } from "node:path";
|
|
24057
24141
|
|
|
24058
24142
|
// src/windows-job.ts
|
|
24059
24143
|
import { spawn as spawn3 } from "node:child_process";
|
|
@@ -24792,7 +24876,7 @@ foreach ($path in $paths) {
|
|
|
24792
24876
|
}
|
|
24793
24877
|
`;
|
|
24794
24878
|
function defaultRunArtifactRoot() {
|
|
24795
|
-
return
|
|
24879
|
+
return join7(homedir(), ".zixt", "run-artifacts");
|
|
24796
24880
|
}
|
|
24797
24881
|
function requireSafeSegment(value, field) {
|
|
24798
24882
|
if (!SAFE_SEGMENT.test(value)) {
|
|
@@ -24848,7 +24932,7 @@ async function prepareRoot(root) {
|
|
|
24848
24932
|
await lstat4(absolute);
|
|
24849
24933
|
} catch (error52) {
|
|
24850
24934
|
if (!isMissing(error52)) throw error52;
|
|
24851
|
-
await
|
|
24935
|
+
await mkdir4(absolute, { recursive: true, mode: DIRECTORY_MODE });
|
|
24852
24936
|
}
|
|
24853
24937
|
const real = await requireRealDirectory(absolute, "run artifact root");
|
|
24854
24938
|
if (realProfile) assertWindowsProfileBoundary(realProfile, real);
|
|
@@ -24856,14 +24940,14 @@ async function prepareRoot(root) {
|
|
|
24856
24940
|
return real;
|
|
24857
24941
|
}
|
|
24858
24942
|
async function prepareAgentRoot(root, agentId) {
|
|
24859
|
-
const path =
|
|
24943
|
+
const path = join7(root, agentId);
|
|
24860
24944
|
assertBelow(root, path);
|
|
24861
24945
|
try {
|
|
24862
24946
|
await lstat4(path);
|
|
24863
24947
|
} catch (error52) {
|
|
24864
24948
|
if (!isMissing(error52)) throw error52;
|
|
24865
24949
|
try {
|
|
24866
|
-
await
|
|
24950
|
+
await mkdir4(path, { mode: DIRECTORY_MODE });
|
|
24867
24951
|
} catch (mkdirError) {
|
|
24868
24952
|
if (mkdirError.code !== "EEXIST") throw mkdirError;
|
|
24869
24953
|
}
|
|
@@ -24879,7 +24963,7 @@ async function lockDownWindowsDirectories(paths) {
|
|
|
24879
24963
|
if (!windowsRoot || !win322.isAbsolute(windowsRoot)) {
|
|
24880
24964
|
throw new Error("private Windows run-artifact ACL authority is unavailable");
|
|
24881
24965
|
}
|
|
24882
|
-
const powershell =
|
|
24966
|
+
const powershell = join7(windowsRoot, "System32", "WindowsPowerShell", "v1.0", "powershell.exe");
|
|
24883
24967
|
const encoded = Buffer.from(WINDOWS_PRIVATE_DACL_SCRIPT, "utf16le").toString("base64");
|
|
24884
24968
|
await new Promise((resolvePromise, reject3) => {
|
|
24885
24969
|
const helper = spawn4(
|
|
@@ -24921,9 +25005,9 @@ async function lockDownWindowsDirectories(paths) {
|
|
|
24921
25005
|
});
|
|
24922
25006
|
}
|
|
24923
25007
|
async function createPrivateDirectory(parent, name) {
|
|
24924
|
-
const path =
|
|
25008
|
+
const path = join7(parent, name);
|
|
24925
25009
|
assertBelow(parent, path);
|
|
24926
|
-
await
|
|
25010
|
+
await mkdir4(path, { mode: DIRECTORY_MODE });
|
|
24927
25011
|
await chmod2(path, DIRECTORY_MODE);
|
|
24928
25012
|
const real = await realpath3(path);
|
|
24929
25013
|
assertBelow(parent, real);
|
|
@@ -24950,24 +25034,24 @@ async function createRunArtifacts(input) {
|
|
|
24950
25034
|
requireSafeSegment(input.agentId, "agentId");
|
|
24951
25035
|
requireSafeSegment(input.runToken, "runToken");
|
|
24952
25036
|
const root = await prepareRoot(input.root);
|
|
24953
|
-
const removeTree = input.removeTree ?? ((path) =>
|
|
25037
|
+
const removeTree = input.removeTree ?? ((path) => rm4(path, { recursive: true, force: true }));
|
|
24954
25038
|
const cleanupRetryDelayMs = input.cleanupRetryDelayMs ?? CLEANUP_RETRY_DELAY_MS;
|
|
24955
25039
|
const agentRoot = await prepareAgentRoot(root, input.agentId);
|
|
24956
25040
|
await lockDownWindowsDirectories([root, agentRoot]);
|
|
24957
|
-
const runRoot =
|
|
25041
|
+
const runRoot = join7(agentRoot, input.runToken);
|
|
24958
25042
|
assertBelow(agentRoot, runRoot);
|
|
24959
25043
|
try {
|
|
24960
|
-
await
|
|
25044
|
+
await mkdir4(runRoot, { mode: DIRECTORY_MODE });
|
|
24961
25045
|
await chmod2(runRoot, DIRECTORY_MODE);
|
|
24962
25046
|
const realRunRoot = await realpath3(runRoot);
|
|
24963
25047
|
assertBelow(agentRoot, realRunRoot);
|
|
24964
25048
|
const emptyGithubConfigDirectory = await createPrivateDirectory(realRunRoot, "gh-config");
|
|
24965
25049
|
const emptyGitHooksDirectory = await createPrivateDirectory(realRunRoot, "git-hooks");
|
|
24966
25050
|
const gitBridgesDirectory = await createPrivateDirectory(realRunRoot, "git-bridges");
|
|
24967
|
-
const denySshScript =
|
|
24968
|
-
const runnerWrapperScript =
|
|
24969
|
-
const systemPromptPath =
|
|
24970
|
-
const mcpConfigPath =
|
|
25051
|
+
const denySshScript = join7(realRunRoot, "deny-ssh.cjs");
|
|
25052
|
+
const runnerWrapperScript = join7(realRunRoot, "runner-wrapper.cjs");
|
|
25053
|
+
const systemPromptPath = join7(realRunRoot, "system-prompt.txt");
|
|
25054
|
+
const mcpConfigPath = join7(realRunRoot, "mcp.json");
|
|
24971
25055
|
await writePrivateFile(denySshScript, "process.exitCode = 127;");
|
|
24972
25056
|
await writePrivateFile(runnerWrapperScript, RUNNER_GUARDIAN);
|
|
24973
25057
|
return {
|
|
@@ -25031,20 +25115,20 @@ async function sweepOrphanedRunArtifacts(root) {
|
|
|
25031
25115
|
let removed = 0;
|
|
25032
25116
|
for (const agent of agents) {
|
|
25033
25117
|
if (!SAFE_SEGMENT.test(agent.name) || !agent.isDirectory() || agent.isSymbolicLink()) continue;
|
|
25034
|
-
const agentPath =
|
|
25118
|
+
const agentPath = join7(realRoot, agent.name);
|
|
25035
25119
|
const runs = await readdir2(agentPath, { withFileTypes: true });
|
|
25036
25120
|
for (const run3 of runs) {
|
|
25037
25121
|
if (!SAFE_SEGMENT.test(run3.name) || !run3.isDirectory() || run3.isSymbolicLink()) continue;
|
|
25038
|
-
const runPath =
|
|
25122
|
+
const runPath = join7(agentPath, run3.name);
|
|
25039
25123
|
assertBelow(agentPath, runPath);
|
|
25040
|
-
await
|
|
25124
|
+
await rm4(runPath, { recursive: true, force: true });
|
|
25041
25125
|
removed++;
|
|
25042
25126
|
}
|
|
25043
25127
|
}
|
|
25044
25128
|
return removed;
|
|
25045
25129
|
}
|
|
25046
25130
|
function defaultRunRegistryRoot() {
|
|
25047
|
-
return
|
|
25131
|
+
return join7(homedir(), ".zixt", "run-registry");
|
|
25048
25132
|
}
|
|
25049
25133
|
async function terminateRecordedRunProcesses(registryRoot = defaultRunRegistryRoot(), terminate = terminateRecordedProcessTree) {
|
|
25050
25134
|
const entries = await readRecordedRunAssignmentEntriesStrict(registryRoot);
|
|
@@ -25070,23 +25154,23 @@ async function syncRunRegistryDirectory(path) {
|
|
|
25070
25154
|
}
|
|
25071
25155
|
}
|
|
25072
25156
|
async function ensureDurableRunRegistryRoot(registryRoot, syncDirectory7) {
|
|
25073
|
-
const firstCreated = await
|
|
25157
|
+
const firstCreated = await mkdir4(registryRoot, { recursive: true, mode: DIRECTORY_MODE });
|
|
25074
25158
|
if (firstCreated && process.platform !== "win32") {
|
|
25075
25159
|
const first = resolve4(firstCreated);
|
|
25076
25160
|
const target = resolve4(registryRoot);
|
|
25077
|
-
await syncDirectory7(
|
|
25161
|
+
await syncDirectory7(dirname4(first));
|
|
25078
25162
|
let current = first;
|
|
25079
25163
|
for (const part of relative3(first, target).split(sep3).filter(Boolean)) {
|
|
25080
25164
|
await syncDirectory7(current);
|
|
25081
|
-
current =
|
|
25165
|
+
current = join7(current, part);
|
|
25082
25166
|
}
|
|
25083
25167
|
}
|
|
25084
25168
|
await chmod2(registryRoot, DIRECTORY_MODE);
|
|
25085
25169
|
}
|
|
25086
25170
|
async function recordRunAssignment(runToken, record2, registryRoot = defaultRunRegistryRoot(), options = {}) {
|
|
25087
25171
|
if (!SAFE_SEGMENT.test(runToken)) return false;
|
|
25088
|
-
const destination =
|
|
25089
|
-
const temporary =
|
|
25172
|
+
const destination = join7(registryRoot, `${runToken}.json`);
|
|
25173
|
+
const temporary = join7(registryRoot, `.${runToken}.${process.pid}.${Date.now()}.tmp`);
|
|
25090
25174
|
let handle;
|
|
25091
25175
|
try {
|
|
25092
25176
|
const syncDirectory7 = options.syncDirectory ?? syncRunRegistryDirectory;
|
|
@@ -25106,7 +25190,7 @@ async function recordRunAssignment(runToken, record2, registryRoot = defaultRunR
|
|
|
25106
25190
|
} finally {
|
|
25107
25191
|
await handle?.close().catch(() => {
|
|
25108
25192
|
});
|
|
25109
|
-
await
|
|
25193
|
+
await rm4(temporary, { force: true }).catch(() => {
|
|
25110
25194
|
});
|
|
25111
25195
|
}
|
|
25112
25196
|
}
|
|
@@ -25118,7 +25202,7 @@ async function forgetRunAssignment(runToken, registryRoot = defaultRunRegistryRo
|
|
|
25118
25202
|
if (retainingAssignments) return;
|
|
25119
25203
|
if (!SAFE_SEGMENT.test(runToken)) return;
|
|
25120
25204
|
try {
|
|
25121
|
-
await
|
|
25205
|
+
await rm4(join7(registryRoot, `${runToken}.json`), { force: true });
|
|
25122
25206
|
} catch {
|
|
25123
25207
|
}
|
|
25124
25208
|
}
|
|
@@ -25163,7 +25247,7 @@ async function readRecordedRunAssignmentEntries(registryRoot = defaultRunRegistr
|
|
|
25163
25247
|
if (!SAFE_SEGMENT.test(runToken)) continue;
|
|
25164
25248
|
let text;
|
|
25165
25249
|
try {
|
|
25166
|
-
text = await readFile5(
|
|
25250
|
+
text = await readFile5(join7(registryRoot, entry.name), "utf8");
|
|
25167
25251
|
} catch {
|
|
25168
25252
|
continue;
|
|
25169
25253
|
}
|
|
@@ -25199,7 +25283,7 @@ async function readRecordedRunAssignmentEntriesStrict(registryRoot = defaultRunR
|
|
|
25199
25283
|
}
|
|
25200
25284
|
let text;
|
|
25201
25285
|
try {
|
|
25202
|
-
text = await readFile5(
|
|
25286
|
+
text = await readFile5(join7(registryRoot, entry.name), "utf8");
|
|
25203
25287
|
} catch {
|
|
25204
25288
|
throw new Error("committed run registry witness could not be read");
|
|
25205
25289
|
}
|
|
@@ -25216,13 +25300,13 @@ async function forgetAcknowledgedRunAssignments(assignments, registryRoot = defa
|
|
|
25216
25300
|
);
|
|
25217
25301
|
const entries = await readRecordedRunAssignmentEntries(registryRoot);
|
|
25218
25302
|
await Promise.all(
|
|
25219
|
-
entries.filter(({ record: record2 }) => acknowledged.has(`${record2.taskId}:${record2.epoch}`)).map(({ runToken }) =>
|
|
25303
|
+
entries.filter(({ record: record2 }) => acknowledged.has(`${record2.taskId}:${record2.epoch}`)).map(({ runToken }) => rm4(join7(registryRoot, `${runToken}.json`), { force: true }))
|
|
25220
25304
|
);
|
|
25221
25305
|
}
|
|
25222
25306
|
async function forgetSupersededRunAssignments(taskId, epoch, registryRoot = defaultRunRegistryRoot()) {
|
|
25223
25307
|
const entries = await readRecordedRunAssignmentEntries(registryRoot);
|
|
25224
25308
|
await Promise.all(
|
|
25225
|
-
entries.filter(({ record: record2 }) => record2.taskId === taskId && record2.epoch < epoch).map(({ runToken }) =>
|
|
25309
|
+
entries.filter(({ record: record2 }) => record2.taskId === taskId && record2.epoch < epoch).map(({ runToken }) => rm4(join7(registryRoot, `${runToken}.json`), { force: true }))
|
|
25226
25310
|
);
|
|
25227
25311
|
}
|
|
25228
25312
|
|
|
@@ -25264,7 +25348,7 @@ function signalWorkerGroup(child, signal) {
|
|
|
25264
25348
|
}
|
|
25265
25349
|
}
|
|
25266
25350
|
function versionsRoot() {
|
|
25267
|
-
return process.env.ZIXT_HOST_VERSIONS_DIR ??
|
|
25351
|
+
return process.env.ZIXT_HOST_VERSIONS_DIR ?? join8(homedir2(), ".zixt", "host-versions");
|
|
25268
25352
|
}
|
|
25269
25353
|
function npmCommand(platform = process.platform) {
|
|
25270
25354
|
return platform === "win32" ? "npm.cmd" : "npm";
|
|
@@ -25273,13 +25357,13 @@ function windowsInstallerCommandLine(command, args) {
|
|
|
25273
25357
|
return [command, ...args].map(quoteForCmd).join(" ");
|
|
25274
25358
|
}
|
|
25275
25359
|
function installedReleaseEntry(version2, root = versionsRoot()) {
|
|
25276
|
-
return
|
|
25360
|
+
return join8(root, version2, "node_modules", PACKAGE_NAME, "dist", "index.js");
|
|
25277
25361
|
}
|
|
25278
25362
|
function releaseEntryAtPrefix(prefix) {
|
|
25279
|
-
return
|
|
25363
|
+
return join8(prefix, "node_modules", PACKAGE_NAME, "dist", "index.js");
|
|
25280
25364
|
}
|
|
25281
25365
|
function releaseManifestAtPrefix(prefix) {
|
|
25282
|
-
return
|
|
25366
|
+
return join8(prefix, "node_modules", PACKAGE_NAME, "package.json");
|
|
25283
25367
|
}
|
|
25284
25368
|
async function validReleaseAtPrefix(prefix, version2) {
|
|
25285
25369
|
try {
|
|
@@ -25314,10 +25398,10 @@ function installedReleaseVersion(entry, root = versionsRoot()) {
|
|
|
25314
25398
|
return resolve5(entry) === resolve5(installedReleaseEntry(version2, root)) ? version2 : null;
|
|
25315
25399
|
}
|
|
25316
25400
|
function currentReleaseEntry(root = versionsRoot(), platform = process.platform) {
|
|
25317
|
-
return
|
|
25401
|
+
return join8(root, platform === "win32" ? "current-launcher.cjs" : CURRENT_RELEASE_ENTRY);
|
|
25318
25402
|
}
|
|
25319
25403
|
function windowsReleasePointer(root = versionsRoot()) {
|
|
25320
|
-
return
|
|
25404
|
+
return join8(root, WINDOWS_RELEASE_POINTER);
|
|
25321
25405
|
}
|
|
25322
25406
|
var WINDOWS_STABLE_LAUNCHER = `${WINDOWS_LAUNCHER_MARKER}
|
|
25323
25407
|
'use strict';
|
|
@@ -25352,9 +25436,9 @@ child.once('error', () => process.exit(1));
|
|
|
25352
25436
|
child.once('exit', (code) => process.exit(code == null ? 1 : code));
|
|
25353
25437
|
`;
|
|
25354
25438
|
async function replaceDurableFile(path, contents, sync = syncDirectory3) {
|
|
25355
|
-
const parent =
|
|
25356
|
-
await
|
|
25357
|
-
const temporary =
|
|
25439
|
+
const parent = dirname5(path);
|
|
25440
|
+
await mkdir5(parent, { recursive: true, mode: 448 });
|
|
25441
|
+
const temporary = join8(parent, `.${CURRENT_RELEASE_ENTRY}.${process.pid}.${crypto.randomUUID()}`);
|
|
25358
25442
|
const handle = await open4(temporary, "wx", 384);
|
|
25359
25443
|
try {
|
|
25360
25444
|
await handle.writeFile(contents, "utf8");
|
|
@@ -25364,7 +25448,7 @@ async function replaceDurableFile(path, contents, sync = syncDirectory3) {
|
|
|
25364
25448
|
await sync(parent);
|
|
25365
25449
|
} catch (error52) {
|
|
25366
25450
|
await handle.close().catch(() => void 0);
|
|
25367
|
-
await
|
|
25451
|
+
await rm5(temporary, { force: true }).catch(() => void 0);
|
|
25368
25452
|
throw error52;
|
|
25369
25453
|
}
|
|
25370
25454
|
}
|
|
@@ -25374,7 +25458,7 @@ async function activateInstalledRelease(entry, root = versionsRoot(), platform =
|
|
|
25374
25458
|
}
|
|
25375
25459
|
await access2(entry);
|
|
25376
25460
|
if (platform === "win32") {
|
|
25377
|
-
await
|
|
25461
|
+
await mkdir5(root, { recursive: true, mode: 448 });
|
|
25378
25462
|
const launcher = currentReleaseEntry(root, platform);
|
|
25379
25463
|
const existingLauncher = await lstat5(launcher).catch((error52) => {
|
|
25380
25464
|
if (error52.code === "ENOENT") return null;
|
|
@@ -25423,7 +25507,7 @@ async function activateInstalledRelease(entry, root = versionsRoot(), platform =
|
|
|
25423
25507
|
return launcher;
|
|
25424
25508
|
}
|
|
25425
25509
|
if (platform !== "linux" && platform !== "darwin") return entry;
|
|
25426
|
-
await
|
|
25510
|
+
await mkdir5(root, { recursive: true, mode: 448 });
|
|
25427
25511
|
const current = currentReleaseEntry(root, platform);
|
|
25428
25512
|
const existing = await lstat5(current).catch((error52) => {
|
|
25429
25513
|
if (error52.code === "ENOENT") return null;
|
|
@@ -25432,13 +25516,13 @@ async function activateInstalledRelease(entry, root = versionsRoot(), platform =
|
|
|
25432
25516
|
if (existing && !existing.isSymbolicLink()) {
|
|
25433
25517
|
throw new Error("the Zixt Host current-release entry is not a symbolic link");
|
|
25434
25518
|
}
|
|
25435
|
-
const temporary =
|
|
25519
|
+
const temporary = join8(root, `.${CURRENT_RELEASE_ENTRY}.${process.pid}.${crypto.randomUUID()}`);
|
|
25436
25520
|
try {
|
|
25437
25521
|
await symlink(entry, temporary, "file");
|
|
25438
25522
|
await rename3(temporary, current);
|
|
25439
25523
|
await sync(root);
|
|
25440
25524
|
} catch (error52) {
|
|
25441
|
-
await
|
|
25525
|
+
await rm5(temporary, { force: true }).catch(() => void 0);
|
|
25442
25526
|
throw error52;
|
|
25443
25527
|
}
|
|
25444
25528
|
return current;
|
|
@@ -25459,7 +25543,7 @@ async function activatedReleaseVersion(root = versionsRoot(), platform = process
|
|
|
25459
25543
|
try {
|
|
25460
25544
|
const current = currentReleaseEntry(root, platform);
|
|
25461
25545
|
const target = await readlink(current);
|
|
25462
|
-
return installedReleaseVersion(resolve5(
|
|
25546
|
+
return installedReleaseVersion(resolve5(dirname5(current), target), root);
|
|
25463
25547
|
} catch {
|
|
25464
25548
|
return null;
|
|
25465
25549
|
}
|
|
@@ -25563,13 +25647,13 @@ async function installRelease(version2, options = {}) {
|
|
|
25563
25647
|
const platform = options.platform ?? process.platform;
|
|
25564
25648
|
const installerCommand = options.installerCommand ?? npmCommand(platform);
|
|
25565
25649
|
const root = options.root ?? versionsRoot();
|
|
25566
|
-
const prefix =
|
|
25650
|
+
const prefix = join8(root, version2);
|
|
25567
25651
|
const entry = installedReleaseEntry(version2, root);
|
|
25568
25652
|
if (await validReleaseAtPrefix(prefix, version2)) return entry;
|
|
25569
25653
|
if (options.signal?.aborted) return null;
|
|
25570
|
-
await
|
|
25571
|
-
const staging =
|
|
25572
|
-
const quarantine =
|
|
25654
|
+
await mkdir5(root, { recursive: true, mode: 448 });
|
|
25655
|
+
const staging = join8(root, `.install-${version2}-${process.pid}-${crypto.randomUUID()}`);
|
|
25656
|
+
const quarantine = join8(root, `.invalid-${version2}-${process.pid}-${crypto.randomUUID()}`);
|
|
25573
25657
|
const usesWindowsInstallerGuardian = platform === "win32" && options.spawnInstaller === void 0;
|
|
25574
25658
|
const installerGateNonce = usesWindowsInstallerGuardian ? crypto.randomUUID() : null;
|
|
25575
25659
|
const installerArguments = (installPrefix, installVersion) => [
|
|
@@ -25601,7 +25685,7 @@ async function installRelease(version2, options = {}) {
|
|
|
25601
25685
|
try {
|
|
25602
25686
|
child = spawnInstaller(staging, version2);
|
|
25603
25687
|
} catch {
|
|
25604
|
-
await
|
|
25688
|
+
await rm5(staging, { recursive: true, force: true }).catch(() => void 0);
|
|
25605
25689
|
return null;
|
|
25606
25690
|
}
|
|
25607
25691
|
let resolveChildExited;
|
|
@@ -25751,8 +25835,8 @@ async function installRelease(version2, options = {}) {
|
|
|
25751
25835
|
await syncDirectory3(root);
|
|
25752
25836
|
return await validReleaseAtPrefix(prefix, version2) ? entry : null;
|
|
25753
25837
|
} finally {
|
|
25754
|
-
await
|
|
25755
|
-
await
|
|
25838
|
+
await rm5(staging, { recursive: true, force: true }).catch(() => void 0);
|
|
25839
|
+
await rm5(quarantine, { recursive: true, force: true }).catch(() => void 0);
|
|
25756
25840
|
}
|
|
25757
25841
|
}
|
|
25758
25842
|
async function pruneInstalledVersions(keep, root = versionsRoot()) {
|
|
@@ -25767,10 +25851,10 @@ async function pruneInstalledVersions(keep, root = versionsRoot()) {
|
|
|
25767
25851
|
const removed = [];
|
|
25768
25852
|
for (const name of entries) {
|
|
25769
25853
|
if (protectedDirs.has(name) || !VERSION_DIR.test(name)) continue;
|
|
25770
|
-
const dir =
|
|
25854
|
+
const dir = join8(root, name);
|
|
25771
25855
|
if (running && running.startsWith(`${dir}${sep4}`)) continue;
|
|
25772
25856
|
try {
|
|
25773
|
-
await
|
|
25857
|
+
await rm5(dir, { recursive: true, force: true });
|
|
25774
25858
|
removed.push(name);
|
|
25775
25859
|
} catch {
|
|
25776
25860
|
}
|
|
@@ -25781,7 +25865,7 @@ function durableState(phase, candidateVersion, fallbackVersion) {
|
|
|
25781
25865
|
return { schema: 1, phase, candidateVersion, fallbackVersion };
|
|
25782
25866
|
}
|
|
25783
25867
|
async function validInstalledRelease(version2, root = versionsRoot()) {
|
|
25784
|
-
return validReleaseAtPrefix(
|
|
25868
|
+
return validReleaseAtPrefix(join8(root, version2), version2);
|
|
25785
25869
|
}
|
|
25786
25870
|
async function recoverDurableReleaseState(store, runningVersion, activeBootVersion, activate, log2) {
|
|
25787
25871
|
const state = await store.load();
|
|
@@ -25900,7 +25984,7 @@ function defaultSpawn(command, argv, supervisorVersion, watchdog, compatibilityO
|
|
|
25900
25984
|
stdio: watchdog ? ["pipe", "inherit", "inherit", "ipc"] : ["pipe", "inherit", "inherit"],
|
|
25901
25985
|
env,
|
|
25902
25986
|
...containmentGateNonce ? {
|
|
25903
|
-
cwd: ownership?.ownershipFile ?
|
|
25987
|
+
cwd: ownership?.ownershipFile ? dirname5(ownership.ownershipFile) : dirname5(entry)
|
|
25904
25988
|
} : {},
|
|
25905
25989
|
// The launch nonce is not a user-facing CLI argument. Keeping it as
|
|
25906
25990
|
// argv[0] gives the stable launcher an exact cross-platform process
|
|
@@ -25997,10 +26081,10 @@ async function launchHostSupervisor(options = {}) {
|
|
|
25997
26081
|
delete env[WORKER_WATCHDOG_FILE_ENV];
|
|
25998
26082
|
delete env[WORKER_OWNERSHIP_FILE_ENV];
|
|
25999
26083
|
delete env[SUPERVISOR_OWNERSHIP_FILE_ENV];
|
|
26000
|
-
const generationNonce = ownershipDirectory ?
|
|
26084
|
+
const generationNonce = ownershipDirectory ? basename4(ownershipDirectory) : null;
|
|
26001
26085
|
if (ownershipDirectory && generationNonce) {
|
|
26002
26086
|
env[LAUNCHER_OWNERSHIP_DIR_ENV] = ownershipDirectory;
|
|
26003
|
-
env[SUPERVISOR_OWNERSHIP_FILE_ENV] =
|
|
26087
|
+
env[SUPERVISOR_OWNERSHIP_FILE_ENV] = join8(ownershipDirectory, `${generationNonce}.json`);
|
|
26004
26088
|
} else {
|
|
26005
26089
|
delete env[LAUNCHER_OWNERSHIP_DIR_ENV];
|
|
26006
26090
|
}
|
|
@@ -26011,7 +26095,7 @@ async function launchHostSupervisor(options = {}) {
|
|
|
26011
26095
|
const child2 = spawn5(process.execPath, [supervisorEntry, ...argv], {
|
|
26012
26096
|
stdio: ["pipe", "inherit", "inherit"],
|
|
26013
26097
|
env,
|
|
26014
|
-
...containmentGateNonce ? { cwd: ownershipDirectory ??
|
|
26098
|
+
...containmentGateNonce ? { cwd: ownershipDirectory ?? dirname5(supervisorEntry) } : {},
|
|
26015
26099
|
detached: platform !== "win32",
|
|
26016
26100
|
// The new launcher can discover the durable PID record and still has
|
|
26017
26101
|
// to bind it to this exact process before signalling a recycled PID.
|
|
@@ -26023,8 +26107,8 @@ async function launchHostSupervisor(options = {}) {
|
|
|
26023
26107
|
});
|
|
26024
26108
|
const customDelay = options.delay;
|
|
26025
26109
|
const ownsWorkerBoundary = options.spawnSupervisor === void 0 || options.ownershipRoot !== void 0;
|
|
26026
|
-
const ownershipRoot = options.ownershipRoot ??
|
|
26027
|
-
const runRegistryRoot2 = options.runRegistryRoot ?? (options.ownershipRoot ?
|
|
26110
|
+
const ownershipRoot = options.ownershipRoot ?? join8(versionsRoot(), "launcher-ownership");
|
|
26111
|
+
const runRegistryRoot2 = options.runRegistryRoot ?? (options.ownershipRoot ? join8(dirname5(options.ownershipRoot), "run-registry") : defaultRunRegistryRoot());
|
|
26028
26112
|
const terminateRecordedOwnership = options.terminateRecordedOwnership ?? terminateRecordedProcessTree;
|
|
26029
26113
|
const createSupervisorContainment = options.createSupervisorContainment ?? (platform === "win32" && options.spawnSupervisor === void 0 ? async (target, identityNonce, signal) => {
|
|
26030
26114
|
if (!target.pid) throw new Error("supervisor process id is unavailable");
|
|
@@ -26079,7 +26163,7 @@ async function launchHostSupervisor(options = {}) {
|
|
|
26079
26163
|
return false;
|
|
26080
26164
|
};
|
|
26081
26165
|
const cleanupOwnershipGeneration = async (directory) => {
|
|
26082
|
-
const generationNonce =
|
|
26166
|
+
const generationNonce = basename4(directory);
|
|
26083
26167
|
const firstRecords = await readWorkerOwnershipRecords(directory);
|
|
26084
26168
|
const supervisorRecord = firstRecords.find((record2) => record2.nonce === generationNonce);
|
|
26085
26169
|
if (firstRecords.length > 0 && !supervisorRecord) {
|
|
@@ -26170,7 +26254,23 @@ async function launchHostSupervisor(options = {}) {
|
|
|
26170
26254
|
}
|
|
26171
26255
|
return false;
|
|
26172
26256
|
};
|
|
26257
|
+
let releaseMachineClaim = null;
|
|
26173
26258
|
try {
|
|
26259
|
+
if (ownsWorkerBoundary) {
|
|
26260
|
+
const claim = await claimMachineLauncher(ownershipRoot);
|
|
26261
|
+
if (claim.kind === "busy") {
|
|
26262
|
+
log2(
|
|
26263
|
+
"Zixt Host: another Zixt Host is already running on this Machine, so this one is stopping instead of taking that Host and its Tasks down. Stop the running Host first if you meant to replace it."
|
|
26264
|
+
);
|
|
26265
|
+
return DO_NOT_RESTART_EXIT_CODE;
|
|
26266
|
+
}
|
|
26267
|
+
if (claim.kind === "held") releaseMachineClaim = claim.release;
|
|
26268
|
+
else {
|
|
26269
|
+
log2(
|
|
26270
|
+
`Zixt Host launcher: this Machine cannot be claimed for a single Host (${claim.reason}); continuing without that protection`
|
|
26271
|
+
);
|
|
26272
|
+
}
|
|
26273
|
+
}
|
|
26174
26274
|
if (!await recoverPriorOwnership()) return 1;
|
|
26175
26275
|
for (; ; ) {
|
|
26176
26276
|
if (stopping) return 0;
|
|
@@ -26202,7 +26302,7 @@ async function launchHostSupervisor(options = {}) {
|
|
|
26202
26302
|
let supervisorContainment = null;
|
|
26203
26303
|
try {
|
|
26204
26304
|
if (containmentGateNonce) {
|
|
26205
|
-
const supervisorIdentity = ownershipDirectory ?
|
|
26305
|
+
const supervisorIdentity = ownershipDirectory ? basename4(ownershipDirectory) : null;
|
|
26206
26306
|
if (!supervisorIdentity) {
|
|
26207
26307
|
throw new Error("supervisor containment identity is unavailable");
|
|
26208
26308
|
}
|
|
@@ -26277,6 +26377,7 @@ async function launchHostSupervisor(options = {}) {
|
|
|
26277
26377
|
process.stdin.off("data", onStdinData);
|
|
26278
26378
|
process.stdin.pause();
|
|
26279
26379
|
}
|
|
26380
|
+
if (releaseMachineClaim) await releaseMachineClaim();
|
|
26280
26381
|
}
|
|
26281
26382
|
}
|
|
26282
26383
|
async function superviseHost(options = {}) {
|
|
@@ -26293,8 +26394,8 @@ async function superviseHost(options = {}) {
|
|
|
26293
26394
|
const inheritedOwnershipDirectory = process.env[LAUNCHER_OWNERSHIP_DIR_ENV];
|
|
26294
26395
|
const launcherOwnershipDirectory = productionLifecycle && typeof inheritedOwnershipDirectory === "string" && isAbsolute8(inheritedOwnershipDirectory) ? inheritedOwnershipDirectory : null;
|
|
26295
26396
|
if (productionLifecycle && isSupervisorRole() && launcherOwnershipDirectory) {
|
|
26296
|
-
const generationNonce =
|
|
26297
|
-
const expectedOwnershipFile =
|
|
26397
|
+
const generationNonce = basename4(launcherOwnershipDirectory);
|
|
26398
|
+
const expectedOwnershipFile = join8(launcherOwnershipDirectory, `${generationNonce}.json`);
|
|
26298
26399
|
const configuredOwnershipFile = process.env[SUPERVISOR_OWNERSHIP_FILE_ENV];
|
|
26299
26400
|
if (process.argv0 !== generationNonce || configuredOwnershipFile !== expectedOwnershipFile || !recordWorkerOwnership(expectedOwnershipFile, generationNonce)) {
|
|
26300
26401
|
log2("Zixt Host: supervisor ownership could not be committed; refusing to start a worker");
|
|
@@ -26822,7 +26923,7 @@ import { homedir as homedir12, hostname as hostname3 } from "node:os";
|
|
|
26822
26923
|
import { existsSync } from "node:fs";
|
|
26823
26924
|
import { statfs } from "node:fs/promises";
|
|
26824
26925
|
import { cpus, freemem, homedir as homedir3, totalmem } from "node:os";
|
|
26825
|
-
import { dirname as
|
|
26926
|
+
import { dirname as dirname6, resolve as resolve6 } from "node:path";
|
|
26826
26927
|
async function machineHardware(workRoot = homedir3()) {
|
|
26827
26928
|
return {
|
|
26828
26929
|
// A container or cgroup can hide processors from this count; it is what
|
|
@@ -26851,7 +26952,7 @@ function nearestExistingPath(start) {
|
|
|
26851
26952
|
let candidate = resolve6(start);
|
|
26852
26953
|
for (let depth = 0; depth < 16; depth++) {
|
|
26853
26954
|
if (existsSync(candidate)) return candidate;
|
|
26854
|
-
const parent =
|
|
26955
|
+
const parent = dirname6(candidate);
|
|
26855
26956
|
if (parent === candidate) return null;
|
|
26856
26957
|
candidate = parent;
|
|
26857
26958
|
}
|
|
@@ -27045,17 +27146,17 @@ function createDemoBrowserAdapterFactory() {
|
|
|
27045
27146
|
}
|
|
27046
27147
|
|
|
27047
27148
|
// src/browser/manager.ts
|
|
27048
|
-
import { lstat as lstat6, mkdir as
|
|
27149
|
+
import { lstat as lstat6, mkdir as mkdir6, open as open5, opendir, readFile as readFile7, rename as rename4, rm as rm6 } from "node:fs/promises";
|
|
27049
27150
|
import { homedir as homedir4 } from "node:os";
|
|
27050
|
-
import { dirname as
|
|
27151
|
+
import { dirname as dirname7, join as join9, resolve as resolve7 } from "node:path";
|
|
27051
27152
|
var SAFE_SEGMENT2 = /^[A-Za-z0-9_-]{1,200}$/;
|
|
27052
27153
|
var FRAME_MIN_INTERVAL_MS = 100;
|
|
27053
27154
|
var IDLE_TIMEOUT_MS = 15 * 6e4;
|
|
27054
27155
|
var BrowserManager = class {
|
|
27055
27156
|
constructor(opts) {
|
|
27056
27157
|
this.opts = opts;
|
|
27057
|
-
this.profileRoot = opts.profileRoot ??
|
|
27058
|
-
this.profileStateRoot =
|
|
27158
|
+
this.profileRoot = opts.profileRoot ?? join9(homedir4(), ".zixt", "browser-profiles");
|
|
27159
|
+
this.profileStateRoot = join9(this.profileRoot, ".profile-state");
|
|
27059
27160
|
this.viewport = opts.viewport ?? BROWSER_DEFAULT_VIEWPORT;
|
|
27060
27161
|
this.idleTimeoutMs = opts.idleTimeoutMs ?? IDLE_TIMEOUT_MS;
|
|
27061
27162
|
this.frameMinIntervalMs = opts.frameMinIntervalMs ?? FRAME_MIN_INTERVAL_MS;
|
|
@@ -27147,13 +27248,13 @@ var BrowserManager = class {
|
|
|
27147
27248
|
exactChild(root, child) {
|
|
27148
27249
|
const canonicalRoot = resolve7(root);
|
|
27149
27250
|
const target = resolve7(canonicalRoot, child);
|
|
27150
|
-
if (
|
|
27251
|
+
if (dirname7(target) !== canonicalRoot) {
|
|
27151
27252
|
throw new Error("browser profile path escaped its owned root");
|
|
27152
27253
|
}
|
|
27153
27254
|
return target;
|
|
27154
27255
|
}
|
|
27155
27256
|
async ensureOwnedDirectory(path) {
|
|
27156
|
-
await
|
|
27257
|
+
await mkdir6(path, { recursive: true, mode: 448 });
|
|
27157
27258
|
const stat3 = await lstat6(path);
|
|
27158
27259
|
if (!stat3.isDirectory() || stat3.isSymbolicLink()) {
|
|
27159
27260
|
throw new Error("browser profile root must be an owned directory, not a symbolic link");
|
|
@@ -27219,7 +27320,7 @@ var BrowserManager = class {
|
|
|
27219
27320
|
await this.syncDirectory(this.profileStateRoot);
|
|
27220
27321
|
await this.syncDirectory(this.profileRoot);
|
|
27221
27322
|
} catch (error52) {
|
|
27222
|
-
await
|
|
27323
|
+
await rm6(temporary, { force: true }).catch(() => {
|
|
27223
27324
|
});
|
|
27224
27325
|
throw error52;
|
|
27225
27326
|
}
|
|
@@ -27295,7 +27396,7 @@ var BrowserManager = class {
|
|
|
27295
27396
|
} catch (error52) {
|
|
27296
27397
|
if (error52.code !== "ENOENT") throw error52;
|
|
27297
27398
|
}
|
|
27298
|
-
await
|
|
27399
|
+
await mkdir6(profileDir, { recursive: true, mode: 448 });
|
|
27299
27400
|
const adapter = await this.opts.factory.open({
|
|
27300
27401
|
agentId,
|
|
27301
27402
|
profileDir,
|
|
@@ -27374,7 +27475,7 @@ var BrowserManager = class {
|
|
|
27374
27475
|
purgeId
|
|
27375
27476
|
});
|
|
27376
27477
|
await this.closeLocked(agentId, "stopped");
|
|
27377
|
-
await
|
|
27478
|
+
await rm6(this.profilePath(agentId), { recursive: true, force: true, maxRetries: 3 });
|
|
27378
27479
|
await this.syncDirectory(this.profileRoot);
|
|
27379
27480
|
});
|
|
27380
27481
|
}
|
|
@@ -28065,9 +28166,9 @@ function createPlaywrightBrowserAdapterFactory(dependencies = {}) {
|
|
|
28065
28166
|
// src/runners/cli-runner.ts
|
|
28066
28167
|
import { spawn as spawn8 } from "node:child_process";
|
|
28067
28168
|
import { randomUUID as randomUUID10 } from "node:crypto";
|
|
28068
|
-
import { lstat as lstat11, mkdir as
|
|
28169
|
+
import { lstat as lstat11, mkdir as mkdir11, realpath as realpath8 } from "node:fs/promises";
|
|
28069
28170
|
import { homedir as homedir5 } from "node:os";
|
|
28070
|
-
import { dirname as
|
|
28171
|
+
import { dirname as dirname9, isAbsolute as isAbsolute14, join as join15, resolve as resolve10 } from "node:path";
|
|
28071
28172
|
|
|
28072
28173
|
// src/tool-packs/browser/authentication-wall.ts
|
|
28073
28174
|
var AUTH_PATH_SEGMENT = /(?:^|\/)(?:log[-_]?in|sign[-_]?in|sso|saml|auth|authorize|authenticate|oauth2?|session\/new|checkpoint)(?:\/|$)/i;
|
|
@@ -28354,7 +28455,7 @@ function createBrowserToolPack(deps) {
|
|
|
28354
28455
|
}
|
|
28355
28456
|
|
|
28356
28457
|
// src/tool-packs/provider-intents.ts
|
|
28357
|
-
import { createHash as
|
|
28458
|
+
import { createHash as createHash3, randomUUID as randomUUID3 } from "node:crypto";
|
|
28358
28459
|
|
|
28359
28460
|
// src/tool-packs/github/rest-transport.ts
|
|
28360
28461
|
var MAX_RESPONSE_BYTES = 2 * 1024 * 1024;
|
|
@@ -28600,7 +28701,7 @@ function canonicalJson(value) {
|
|
|
28600
28701
|
return `{${Object.entries(value).sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0).map(([key, child]) => `${JSON.stringify(key)}:${canonicalJson(child)}`).join(",")}}`;
|
|
28601
28702
|
}
|
|
28602
28703
|
function payloadFingerprint(value) {
|
|
28603
|
-
return
|
|
28704
|
+
return createHash3("sha256").update(canonicalJson(value)).digest("hex");
|
|
28604
28705
|
}
|
|
28605
28706
|
function claimResult(result) {
|
|
28606
28707
|
if (!result.ok || !result.result || typeof result.result !== "object") return null;
|
|
@@ -30792,14 +30893,14 @@ function createGithubPushOrchestrator(input) {
|
|
|
30792
30893
|
// src/tool-packs/github/git-bridge.ts
|
|
30793
30894
|
import { spawn as spawn6 } from "node:child_process";
|
|
30794
30895
|
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
30795
|
-
import { chmod as chmod4, lstat as lstat8, mkdir as
|
|
30796
|
-
import { dirname as
|
|
30896
|
+
import { chmod as chmod4, lstat as lstat8, mkdir as mkdir7, realpath as realpath5, rm as rm7 } from "node:fs/promises";
|
|
30897
|
+
import { dirname as dirname8, isAbsolute as isAbsolute10, join as join11, relative as relative6 } from "node:path";
|
|
30797
30898
|
|
|
30798
30899
|
// src/tool-packs/github/git-credential-broker.ts
|
|
30799
|
-
import { createServer } from "node:http";
|
|
30900
|
+
import { createServer as createServer2 } from "node:http";
|
|
30800
30901
|
import { randomBytes, randomUUID as randomUUID6, timingSafeEqual } from "node:crypto";
|
|
30801
30902
|
import { chmod as chmod3, lstat as lstat7, realpath as realpath4, writeFile as writeFile2 } from "node:fs/promises";
|
|
30802
|
-
import { isAbsolute as isAbsolute9, join as
|
|
30903
|
+
import { isAbsolute as isAbsolute9, join as join10, relative as relative5 } from "node:path";
|
|
30803
30904
|
var MAX_REQUEST_BYTES = 16 * 1024;
|
|
30804
30905
|
var FILE_MODE2 = 384;
|
|
30805
30906
|
var HELPER_SOURCE = String.raw`'use strict';
|
|
@@ -30928,14 +31029,14 @@ async function createGithubGitCredentialBroker(input) {
|
|
|
30928
31029
|
throw new Error("Git credential broker requires a private real run directory");
|
|
30929
31030
|
}
|
|
30930
31031
|
const runRoot = await realpath4(input.runArtifactsRoot);
|
|
30931
|
-
const helperPath =
|
|
31032
|
+
const helperPath = join10(runRoot, `git-credential-${randomUUID6()}.cjs`);
|
|
30932
31033
|
assertChildPath(runRoot, helperPath);
|
|
30933
31034
|
await writeFile2(helperPath, HELPER_SOURCE, { flag: "wx", mode: FILE_MODE2 });
|
|
30934
31035
|
await chmod3(helperPath, FILE_MODE2);
|
|
30935
31036
|
const capability2 = randomBytes(32).toString("base64url");
|
|
30936
31037
|
const expectedPath = `${input.repositoryFullName}.git`;
|
|
30937
31038
|
let closed = false;
|
|
30938
|
-
const server =
|
|
31039
|
+
const server = createServer2(async (request, response) => {
|
|
30939
31040
|
try {
|
|
30940
31041
|
if (closed || input.authoritySignal.aborted || input.expiresAt !== null && input.expiresAt.getTime() <= Date.now()) {
|
|
30941
31042
|
reject(response, 410);
|
|
@@ -31044,7 +31145,7 @@ async function requireRealDirectory2(path, label) {
|
|
|
31044
31145
|
async function validateTokenlessPaths(command) {
|
|
31045
31146
|
if (command.kind === "clone-from-bridge") {
|
|
31046
31147
|
if (!isAbsolute10(command.destination)) throw new GithubGitProcessError("invalid_input");
|
|
31047
|
-
const parent = await requireRealDirectory2(
|
|
31148
|
+
const parent = await requireRealDirectory2(dirname8(command.destination), "clone parent");
|
|
31048
31149
|
assertBelow2(parent, command.destination, "clone destination");
|
|
31049
31150
|
const destination = await lstat8(command.destination).catch((error52) => {
|
|
31050
31151
|
if (error52.code === "ENOENT") return null;
|
|
@@ -31332,9 +31433,9 @@ function createGithubGitBridge(input) {
|
|
|
31332
31433
|
async createPrivateBridge() {
|
|
31333
31434
|
if (closed) throw new GithubGitProcessError("cancelled");
|
|
31334
31435
|
const current = await roots();
|
|
31335
|
-
const path =
|
|
31436
|
+
const path = join11(current.bridges, `${randomUUID7()}.git`);
|
|
31336
31437
|
assertBelow2(current.bridges, path, "git bridge");
|
|
31337
|
-
await
|
|
31438
|
+
await mkdir7(path, { mode: DIRECTORY_MODE2 });
|
|
31338
31439
|
await chmod4(path, DIRECTORY_MODE2);
|
|
31339
31440
|
try {
|
|
31340
31441
|
await runGit(
|
|
@@ -31350,16 +31451,16 @@ function createGithubGitBridge(input) {
|
|
|
31350
31451
|
);
|
|
31351
31452
|
const real = await requireRealDirectory2(path, "git bridge");
|
|
31352
31453
|
assertBelow2(current.bridges, real, "git bridge");
|
|
31353
|
-
const hooks =
|
|
31354
|
-
await
|
|
31355
|
-
await
|
|
31454
|
+
const hooks = join11(real, "hooks");
|
|
31455
|
+
await rm7(hooks, { recursive: true, force: true });
|
|
31456
|
+
await mkdir7(hooks, { mode: DIRECTORY_MODE2 });
|
|
31356
31457
|
await chmod4(hooks, DIRECTORY_MODE2);
|
|
31357
|
-
const config2 =
|
|
31458
|
+
const config2 = join11(real, "config");
|
|
31358
31459
|
await chmod4(config2, 384);
|
|
31359
31460
|
active.add(real);
|
|
31360
31461
|
return real;
|
|
31361
31462
|
} catch (error52) {
|
|
31362
|
-
await
|
|
31463
|
+
await rm7(path, { recursive: true, force: true }).catch(() => {
|
|
31363
31464
|
});
|
|
31364
31465
|
throw error52;
|
|
31365
31466
|
}
|
|
@@ -31453,7 +31554,7 @@ function createGithubGitBridge(input) {
|
|
|
31453
31554
|
},
|
|
31454
31555
|
async destroyPrivateBridge(path) {
|
|
31455
31556
|
const bridge = await requireBridge(path);
|
|
31456
|
-
await
|
|
31557
|
+
await rm7(bridge, { recursive: true, force: true });
|
|
31457
31558
|
active.delete(bridge);
|
|
31458
31559
|
credentialed2.delete(bridge);
|
|
31459
31560
|
},
|
|
@@ -31461,7 +31562,7 @@ function createGithubGitBridge(input) {
|
|
|
31461
31562
|
if (closed) return;
|
|
31462
31563
|
closed = true;
|
|
31463
31564
|
const paths = [...active];
|
|
31464
|
-
await Promise.all(paths.map((path) =>
|
|
31565
|
+
await Promise.all(paths.map((path) => rm7(path, { recursive: true, force: true })));
|
|
31465
31566
|
active.clear();
|
|
31466
31567
|
credentialed2.clear();
|
|
31467
31568
|
}
|
|
@@ -31802,8 +31903,8 @@ function createRepositoryTools(runtime) {
|
|
|
31802
31903
|
|
|
31803
31904
|
// src/tool-packs/github/workspace.ts
|
|
31804
31905
|
import { randomUUID as randomUUID8 } from "node:crypto";
|
|
31805
|
-
import { chmod as chmod5, lstat as lstat9, mkdir as
|
|
31806
|
-
import { isAbsolute as isAbsolute11, join as
|
|
31906
|
+
import { chmod as chmod5, lstat as lstat9, mkdir as mkdir8, readFile as readFile8, realpath as realpath6, rename as rename5, rm as rm8, writeFile as writeFile3 } from "node:fs/promises";
|
|
31907
|
+
import { isAbsolute as isAbsolute11, join as join12, relative as relative7, resolve as resolve8 } from "node:path";
|
|
31807
31908
|
var SAFE_LOCAL_ID = /^[A-Za-z0-9_-]{1,200}$/;
|
|
31808
31909
|
var FULL_NAME2 = /^[A-Za-z0-9_.-]{1,100}\/[A-Za-z0-9_.-]{1,100}$/;
|
|
31809
31910
|
var DIRECTORY_MODE3 = 448;
|
|
@@ -31840,10 +31941,10 @@ async function requireRealDirectory3(path, label) {
|
|
|
31840
31941
|
return real;
|
|
31841
31942
|
}
|
|
31842
31943
|
async function createOrRequirePrivateDirectory(parent, name, label) {
|
|
31843
|
-
const path =
|
|
31944
|
+
const path = join12(parent, name);
|
|
31844
31945
|
assertBelow3(parent, path, label);
|
|
31845
31946
|
try {
|
|
31846
|
-
await
|
|
31947
|
+
await mkdir8(path, { mode: DIRECTORY_MODE3 });
|
|
31847
31948
|
} catch (error52) {
|
|
31848
31949
|
if (error52.code !== "EEXIST") throw error52;
|
|
31849
31950
|
}
|
|
@@ -31923,8 +32024,8 @@ async function createGithubWorkspaceService(input) {
|
|
|
31923
32024
|
if (expectedFullName !== void 0 && repository.fullName !== expectedFullName) {
|
|
31924
32025
|
throw new Error("GitHub repository name does not match this task grant");
|
|
31925
32026
|
}
|
|
31926
|
-
const destination =
|
|
31927
|
-
const metadataPath =
|
|
32027
|
+
const destination = join12(repositoriesRoot, parsed.data);
|
|
32028
|
+
const metadataPath = join12(metadataRoot, `${parsed.data}.json`);
|
|
31928
32029
|
if (!await pathExists(destination) || !await pathExists(metadataPath)) {
|
|
31929
32030
|
throw new Error("GitHub repository workspace has not been prepared");
|
|
31930
32031
|
}
|
|
@@ -31941,14 +32042,14 @@ async function createGithubWorkspaceService(input) {
|
|
|
31941
32042
|
return real;
|
|
31942
32043
|
};
|
|
31943
32044
|
const cloneRepository = async (clone2) => {
|
|
31944
|
-
const destination =
|
|
31945
|
-
const metadataPath =
|
|
32045
|
+
const destination = join12(repositoriesRoot, clone2.repositoryId);
|
|
32046
|
+
const metadataPath = join12(metadataRoot, `${clone2.repositoryId}.json`);
|
|
31946
32047
|
assertBelow3(repositoriesRoot, destination, "repository path");
|
|
31947
32048
|
assertBelow3(metadataRoot, metadataPath, "repository metadata");
|
|
31948
32049
|
if (await pathExists(destination) || await pathExists(metadataPath)) {
|
|
31949
32050
|
throw new Error("GitHub repository workspace already exists or is inconsistent");
|
|
31950
32051
|
}
|
|
31951
|
-
const temporary =
|
|
32052
|
+
const temporary = join12(repositoriesRoot, `.clone-${randomUUID8()}`);
|
|
31952
32053
|
assertBelow3(repositoriesRoot, temporary, "temporary clone");
|
|
31953
32054
|
try {
|
|
31954
32055
|
await input.git.clone({
|
|
@@ -31973,7 +32074,7 @@ async function createGithubWorkspaceService(input) {
|
|
|
31973
32074
|
path: destination,
|
|
31974
32075
|
...clone2.createIntentId === void 0 ? {} : { createIntentId: clone2.createIntentId }
|
|
31975
32076
|
};
|
|
31976
|
-
const metadataTemporary =
|
|
32077
|
+
const metadataTemporary = join12(metadataRoot, `.${clone2.repositoryId}-${randomUUID8()}.tmp`);
|
|
31977
32078
|
assertBelow3(metadataRoot, metadataTemporary, "temporary repository metadata");
|
|
31978
32079
|
await writeFile3(metadataTemporary, `${JSON.stringify(metadata)}
|
|
31979
32080
|
`, {
|
|
@@ -31986,11 +32087,11 @@ async function createGithubWorkspaceService(input) {
|
|
|
31986
32087
|
try {
|
|
31987
32088
|
await rename5(metadataTemporary, metadataPath);
|
|
31988
32089
|
} catch (error52) {
|
|
31989
|
-
await
|
|
32090
|
+
await rm8(destination, { recursive: true, force: true });
|
|
31990
32091
|
throw error52;
|
|
31991
32092
|
}
|
|
31992
32093
|
} finally {
|
|
31993
|
-
await
|
|
32094
|
+
await rm8(metadataTemporary, { force: true }).catch(() => {
|
|
31994
32095
|
});
|
|
31995
32096
|
}
|
|
31996
32097
|
const path = await requireRealDirectory3(destination, "GitHub repository");
|
|
@@ -32002,14 +32103,14 @@ async function createGithubWorkspaceService(input) {
|
|
|
32002
32103
|
headSha
|
|
32003
32104
|
};
|
|
32004
32105
|
} finally {
|
|
32005
|
-
await
|
|
32106
|
+
await rm8(temporary, { recursive: true, force: true }).catch(() => {
|
|
32006
32107
|
});
|
|
32007
32108
|
}
|
|
32008
32109
|
};
|
|
32009
32110
|
const prepareRepository = async (authority) => {
|
|
32010
32111
|
const { repository } = authority;
|
|
32011
|
-
const destination =
|
|
32012
|
-
const metadataPath =
|
|
32112
|
+
const destination = join12(repositoriesRoot, repository.repositoryId);
|
|
32113
|
+
const metadataPath = join12(metadataRoot, `${repository.repositoryId}.json`);
|
|
32013
32114
|
assertBelow3(repositoriesRoot, destination, "repository path");
|
|
32014
32115
|
assertBelow3(metadataRoot, metadataPath, "repository metadata");
|
|
32015
32116
|
return withWorkspaceLock(destination, async () => {
|
|
@@ -32174,7 +32275,7 @@ async function createGithubWorkspaceService(input) {
|
|
|
32174
32275
|
throw new Error("GitHub created repository is outside this installation");
|
|
32175
32276
|
}
|
|
32176
32277
|
parseGitRef(cloneInput.repository.defaultBranch, "default branch");
|
|
32177
|
-
return withWorkspaceLock(
|
|
32278
|
+
return withWorkspaceLock(join12(repositoriesRoot, repositoryId2), async () => {
|
|
32178
32279
|
const prepared = await cloneRepository({
|
|
32179
32280
|
repositoryId: repositoryId2,
|
|
32180
32281
|
fullName: cloneInput.repository.fullName,
|
|
@@ -32581,7 +32682,7 @@ function createGithubToolPackFactory(options = {}) {
|
|
|
32581
32682
|
var githubToolPackFactory = createGithubToolPackFactory();
|
|
32582
32683
|
|
|
32583
32684
|
// src/runners/linear-api.ts
|
|
32584
|
-
import { createHash as
|
|
32685
|
+
import { createHash as createHash4, randomUUID as randomUUID9 } from "node:crypto";
|
|
32585
32686
|
var MAX_RESPONSE_BYTES2 = 2 * 1024 * 1024;
|
|
32586
32687
|
var MAX_RESULT_STRING = 1e5;
|
|
32587
32688
|
var MAX_RESULT_ARRAY = 100;
|
|
@@ -33152,7 +33253,7 @@ function operationFor(name, args, appUserId, heldBy) {
|
|
|
33152
33253
|
}
|
|
33153
33254
|
}
|
|
33154
33255
|
function fingerprint(value) {
|
|
33155
|
-
return
|
|
33256
|
+
return createHash4("sha256").update(canonicalLinearMutationPayload(value)).digest("hex");
|
|
33156
33257
|
}
|
|
33157
33258
|
function providerIntentFor(mutation, payloadFingerprint2) {
|
|
33158
33259
|
const common = {
|
|
@@ -33715,8 +33816,8 @@ function createDefaultToolPackRegistry() {
|
|
|
33715
33816
|
}
|
|
33716
33817
|
|
|
33717
33818
|
// src/runners/attachments.ts
|
|
33718
|
-
import { mkdir as
|
|
33719
|
-
import { join as
|
|
33819
|
+
import { mkdir as mkdir9, writeFile as writeFile4 } from "node:fs/promises";
|
|
33820
|
+
import { join as join13 } from "node:path";
|
|
33720
33821
|
var WINDOWS_RESERVED = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\..*)?$/i;
|
|
33721
33822
|
function sanitizeAttachmentFileName(name) {
|
|
33722
33823
|
const base = name.split(/[/\\]/).pop() ?? "";
|
|
@@ -33745,9 +33846,9 @@ async function materializeAttachments(task, taskRoot) {
|
|
|
33745
33846
|
`attached file "${attachment.name}" arrived incomplete (${bytes.byteLength} of ${attachment.size} bytes)`
|
|
33746
33847
|
);
|
|
33747
33848
|
}
|
|
33748
|
-
const directory =
|
|
33749
|
-
await
|
|
33750
|
-
const path =
|
|
33849
|
+
const directory = join13(taskRoot, ".zixt-attachments", task.taskId, attachment.id);
|
|
33850
|
+
await mkdir9(directory, { recursive: true });
|
|
33851
|
+
const path = join13(directory, sanitizeAttachmentFileName(attachment.name));
|
|
33751
33852
|
await writeFile4(path, bytes);
|
|
33752
33853
|
materialized.push({
|
|
33753
33854
|
path,
|
|
@@ -33775,7 +33876,7 @@ function renderAttachmentSection(files) {
|
|
|
33775
33876
|
}
|
|
33776
33877
|
|
|
33777
33878
|
// src/runners/ask-user-server.ts
|
|
33778
|
-
import { createServer as
|
|
33879
|
+
import { createServer as createServer3 } from "node:http";
|
|
33779
33880
|
|
|
33780
33881
|
// src/runners/ask-user-secrets.ts
|
|
33781
33882
|
var SECRET_NOUN_SOURCE = "(?:passwords?|passphrases?|api[ -]?keys?|access tokens?|auth tokens?|api tokens?|bearer tokens?|refresh tokens?|tokens?|secret keys?|client secrets?|private keys?|one[- ]time (?:code|password)s?|otps?|2fa codes?|mfa codes?|verification codes?|security codes?|session cookies?)";
|
|
@@ -34445,7 +34546,7 @@ function createAskUserServer() {
|
|
|
34445
34546
|
let listening;
|
|
34446
34547
|
function ensureListening() {
|
|
34447
34548
|
listening ??= new Promise((resolve17, reject3) => {
|
|
34448
|
-
server =
|
|
34549
|
+
server = createServer3((req, res) => {
|
|
34449
34550
|
res.on("error", () => {
|
|
34450
34551
|
});
|
|
34451
34552
|
handle(req, res).catch(() => {
|
|
@@ -34852,9 +34953,9 @@ function buildRunnerEnv(input) {
|
|
|
34852
34953
|
// src/runners/github-shell-auth.ts
|
|
34853
34954
|
import { execFile } from "node:child_process";
|
|
34854
34955
|
import { randomBytes as randomBytes2, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
|
|
34855
|
-
import { chmod as chmod6, lstat as lstat10, mkdir as
|
|
34856
|
-
import { createServer as
|
|
34857
|
-
import { isAbsolute as isAbsolute13, join as
|
|
34956
|
+
import { chmod as chmod6, lstat as lstat10, mkdir as mkdir10, realpath as realpath7, writeFile as writeFile5 } from "node:fs/promises";
|
|
34957
|
+
import { createServer as createServer4 } from "node:http";
|
|
34958
|
+
import { isAbsolute as isAbsolute13, join as join14, relative as relative8 } from "node:path";
|
|
34858
34959
|
var MAX_REQUEST_BYTES2 = 16 * 1024;
|
|
34859
34960
|
var DIRECTORY_MODE4 = 448;
|
|
34860
34961
|
var PRIVATE_FILE_MODE = 384;
|
|
@@ -35242,7 +35343,7 @@ async function prepareHelpers(input) {
|
|
|
35242
35343
|
throw new Error("GitHub shell authentication requires a private real run directory");
|
|
35243
35344
|
}
|
|
35244
35345
|
const runRoot = await realpath7(input.runRoot);
|
|
35245
|
-
const helperPath =
|
|
35346
|
+
const helperPath = join14(runRoot, "github-shell-git-credential.cjs");
|
|
35246
35347
|
assertChildPath2(runRoot, helperPath);
|
|
35247
35348
|
await writePrivate(helperPath, GIT_HELPER_SOURCE);
|
|
35248
35349
|
if (!input.ghExecutablePath) {
|
|
@@ -35253,14 +35354,14 @@ async function prepareHelpers(input) {
|
|
|
35253
35354
|
wrapperSourcePath: null
|
|
35254
35355
|
};
|
|
35255
35356
|
}
|
|
35256
|
-
const shellToolsDirectory =
|
|
35357
|
+
const shellToolsDirectory = join14(runRoot, "shell-tools");
|
|
35257
35358
|
assertChildPath2(runRoot, shellToolsDirectory);
|
|
35258
|
-
await
|
|
35359
|
+
await mkdir10(shellToolsDirectory, { mode: DIRECTORY_MODE4 });
|
|
35259
35360
|
await chmod6(shellToolsDirectory, DIRECTORY_MODE4);
|
|
35260
|
-
const wrapperSourcePath =
|
|
35361
|
+
const wrapperSourcePath = join14(runRoot, "github-shell-gh-wrapper.cjs");
|
|
35261
35362
|
assertChildPath2(runRoot, wrapperSourcePath);
|
|
35262
35363
|
await writePrivate(wrapperSourcePath, GH_WRAPPER_SOURCE);
|
|
35263
|
-
const wrapperPath =
|
|
35364
|
+
const wrapperPath = join14(shellToolsDirectory, process.platform === "win32" ? "gh.cmd" : "gh");
|
|
35264
35365
|
assertChildPath2(runRoot, wrapperPath);
|
|
35265
35366
|
const launcher = process.platform === "win32" ? `@"${process.execPath.replaceAll('"', '""')}" "${wrapperSourcePath.replaceAll('"', '""')}" %*\r
|
|
35266
35367
|
` : `#!/bin/sh
|
|
@@ -35380,7 +35481,7 @@ async function createGithubShellAuth(input) {
|
|
|
35380
35481
|
});
|
|
35381
35482
|
const capability2 = randomBytes2(32).toString("base64url");
|
|
35382
35483
|
let closed = false;
|
|
35383
|
-
const server =
|
|
35484
|
+
const server = createServer4(async (request, response) => {
|
|
35384
35485
|
try {
|
|
35385
35486
|
if (closed || input.authoritySignal.aborted) {
|
|
35386
35487
|
reject2(response, 410);
|
|
@@ -36054,7 +36155,7 @@ async function settlesWithin(promise2, timeoutMs) {
|
|
|
36054
36155
|
}
|
|
36055
36156
|
}
|
|
36056
36157
|
function defaultRunnerWorkspaceRoot() {
|
|
36057
|
-
return
|
|
36158
|
+
return join15(homedir5(), ".zixt", "workspaces");
|
|
36058
36159
|
}
|
|
36059
36160
|
function defaultRunnerArtifactRoot() {
|
|
36060
36161
|
return defaultRunArtifactRoot();
|
|
@@ -36103,7 +36204,7 @@ function createCliRunner(adapter, opts = {}) {
|
|
|
36103
36204
|
const prefixArgs = opts.commandPrefixArgs ?? [];
|
|
36104
36205
|
const maxWallTimeMs = opts.maxWallTimeMs;
|
|
36105
36206
|
const workspaceRoot = opts.workspaceRoot ?? defaultRunnerWorkspaceRoot();
|
|
36106
|
-
const artifactRoot = opts.artifactRoot ?? (opts.workspaceRoot === void 0 ? defaultRunnerArtifactRoot() :
|
|
36207
|
+
const artifactRoot = opts.artifactRoot ?? (opts.workspaceRoot === void 0 ? defaultRunnerArtifactRoot() : join15(dirname9(workspaceRoot), "run-artifacts"));
|
|
36107
36208
|
const runRegistryRoot2 = opts.runRegistryRoot ?? defaultRunRegistryRoot();
|
|
36108
36209
|
const createArtifacts = opts.createArtifacts ?? createRunArtifacts;
|
|
36109
36210
|
const toolPackRegistry2 = opts.toolPackRegistry ?? createDefaultToolPackRegistry();
|
|
@@ -36121,7 +36222,7 @@ function createCliRunner(adapter, opts = {}) {
|
|
|
36121
36222
|
};
|
|
36122
36223
|
const askUserServer = createAskUserServer();
|
|
36123
36224
|
const windowsRoot = process.env.SystemRoot ?? process.env.WINDIR;
|
|
36124
|
-
const windowsComspecCandidate = process.platform === "win32" && windowsRoot ?
|
|
36225
|
+
const windowsComspecCandidate = process.platform === "win32" && windowsRoot ? join15(windowsRoot, "System32", "cmd.exe") : void 0;
|
|
36125
36226
|
let safetyFailure;
|
|
36126
36227
|
return async (task) => {
|
|
36127
36228
|
if (safetyFailure) {
|
|
@@ -36161,8 +36262,8 @@ function createCliRunner(adapter, opts = {}) {
|
|
|
36161
36262
|
usage: { inputTokens: 0, outputTokens: 0 }
|
|
36162
36263
|
};
|
|
36163
36264
|
}
|
|
36164
|
-
const taskRoot =
|
|
36165
|
-
await
|
|
36265
|
+
const taskRoot = join15(workspaceRoot, task.agentId);
|
|
36266
|
+
await mkdir11(taskRoot, { recursive: true });
|
|
36166
36267
|
if (task.cancelledNow()) return cancelledBeforeRun();
|
|
36167
36268
|
const configuredWorkspace = task.spec.workspace;
|
|
36168
36269
|
let cwd = taskRoot;
|
|
@@ -36470,7 +36571,7 @@ ${attachmentSection}` : prompt;
|
|
|
36470
36571
|
for (const path of paths) {
|
|
36471
36572
|
if (!path || path.length > 4096) continue;
|
|
36472
36573
|
const absolutePath = isAbsolute14(path) ? path : resolve10(cwd, path);
|
|
36473
|
-
const directory =
|
|
36574
|
+
const directory = dirname9(absolutePath);
|
|
36474
36575
|
observedWorkingDirectories.delete(directory);
|
|
36475
36576
|
observedWorkingDirectories.add(directory);
|
|
36476
36577
|
while (observedWorkingDirectories.size > 19) {
|
|
@@ -36916,7 +37017,7 @@ function runCliProcess(options) {
|
|
|
36916
37017
|
// The idle pre-assignment guardian must never load from or depend
|
|
36917
37018
|
// on an untrusted Task checkout. Only the post-gate target enters
|
|
36918
37019
|
// the requested working directory from its private release frame.
|
|
36919
|
-
cwd:
|
|
37020
|
+
cwd: dirname9(options.guardian.scriptPath),
|
|
36920
37021
|
env: runnerGuardianEnv(process.env, containmentGateNonce),
|
|
36921
37022
|
stdio: ["pipe", "pipe", "pipe"],
|
|
36922
37023
|
windowsHide: true,
|
|
@@ -37198,7 +37299,7 @@ import { randomUUID as randomUUID11 } from "node:crypto";
|
|
|
37198
37299
|
// src/runners/runtime-observation.ts
|
|
37199
37300
|
import { open as open6, readdir as readdir4, realpath as realpath9 } from "node:fs/promises";
|
|
37200
37301
|
import { homedir as homedir6 } from "node:os";
|
|
37201
|
-
import { join as
|
|
37302
|
+
import { join as join16 } from "node:path";
|
|
37202
37303
|
var READ_WINDOW_BYTES = 1024 * 1024;
|
|
37203
37304
|
var CATALOG_TIMEOUT_MS = 15e3;
|
|
37204
37305
|
var CATALOG_OUTPUT_LIMIT_BYTES = 4 * 1024 * 1024;
|
|
@@ -37258,9 +37359,9 @@ function displayValue(value, maxLength) {
|
|
|
37258
37359
|
return trimmed;
|
|
37259
37360
|
}
|
|
37260
37361
|
function claudeTranscriptPath(input) {
|
|
37261
|
-
const configDir = input.env["CLAUDE_CONFIG_DIR"] ||
|
|
37362
|
+
const configDir = input.env["CLAUDE_CONFIG_DIR"] || join16(homeFrom(input.env), ".claude");
|
|
37262
37363
|
const slug = input.resolvedCwd.replace(/[^a-zA-Z0-9]/g, "-");
|
|
37263
|
-
return
|
|
37364
|
+
return join16(configDir, "projects", slug, `${input.sessionId}.jsonl`);
|
|
37264
37365
|
}
|
|
37265
37366
|
async function readClaudeSessionEffort(input) {
|
|
37266
37367
|
const resolvedCwd = await realpath9(input.cwd).catch(() => input.cwd);
|
|
@@ -37276,18 +37377,18 @@ async function readClaudeSessionEffort(input) {
|
|
|
37276
37377
|
}
|
|
37277
37378
|
async function newestDirectories(root, limit) {
|
|
37278
37379
|
const entries = await readdir4(root, { withFileTypes: true }).catch(() => []);
|
|
37279
|
-
return entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort((left, right) => right.localeCompare(left)).slice(0, limit).map((name) =>
|
|
37380
|
+
return entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort((left, right) => right.localeCompare(left)).slice(0, limit).map((name) => join16(root, name));
|
|
37280
37381
|
}
|
|
37281
37382
|
async function findCodexRolloutPath(input) {
|
|
37282
|
-
const codexHome = input.env["CODEX_HOME"] ||
|
|
37283
|
-
const sessions =
|
|
37383
|
+
const codexHome = input.env["CODEX_HOME"] || join16(homeFrom(input.env), ".codex");
|
|
37384
|
+
const sessions = join16(codexHome, "sessions");
|
|
37284
37385
|
const suffix = `-${input.threadId}.jsonl`;
|
|
37285
37386
|
for (const year of await newestDirectories(sessions, 2)) {
|
|
37286
37387
|
for (const month of await newestDirectories(year, 2)) {
|
|
37287
37388
|
for (const day of await newestDirectories(month, 3)) {
|
|
37288
37389
|
const files = await readdir4(day).catch(() => []);
|
|
37289
37390
|
const match = files.find((name) => name.endsWith(suffix));
|
|
37290
|
-
if (match) return
|
|
37391
|
+
if (match) return join16(day, match);
|
|
37291
37392
|
}
|
|
37292
37393
|
}
|
|
37293
37394
|
}
|
|
@@ -37671,18 +37772,18 @@ function improveErrorMessage(error52) {
|
|
|
37671
37772
|
}
|
|
37672
37773
|
|
|
37673
37774
|
// src/runners/codex.ts
|
|
37674
|
-
import { mkdir as
|
|
37775
|
+
import { mkdir as mkdir12, readFile as readFile9, writeFile as writeFile6 } from "node:fs/promises";
|
|
37675
37776
|
import { randomUUID as randomUUID12 } from "node:crypto";
|
|
37676
37777
|
import { homedir as homedir7 } from "node:os";
|
|
37677
|
-
import { join as
|
|
37778
|
+
import { join as join17 } from "node:path";
|
|
37678
37779
|
var CODEX_NOT_FOUND_MESSAGE = "The `codex` CLI was not found on this Machine. Install it (npm install -g @openai/codex) and sign in with `codex login`, or switch the agent to API-key auth.";
|
|
37679
37780
|
function defaultCodexThreadIndexRoot() {
|
|
37680
|
-
return
|
|
37781
|
+
return join17(homedir7(), ".zixt", "codex-threads");
|
|
37681
37782
|
}
|
|
37682
37783
|
var SAFE_SEGMENT3 = /^[A-Za-z0-9_-]{1,200}$/;
|
|
37683
37784
|
function threadIndexPath(root, agentId, sessionKey) {
|
|
37684
37785
|
if (!SAFE_SEGMENT3.test(agentId) || !SAFE_SEGMENT3.test(sessionKey)) return null;
|
|
37685
|
-
return
|
|
37786
|
+
return join17(root, agentId, `${sessionKey}.json`);
|
|
37686
37787
|
}
|
|
37687
37788
|
async function readThreadId(path) {
|
|
37688
37789
|
try {
|
|
@@ -37777,7 +37878,7 @@ ${value}` : value;
|
|
|
37777
37878
|
const recordedThreadId = indexPath ? await readThreadId(indexPath) : null;
|
|
37778
37879
|
const rememberThread = (threadId) => {
|
|
37779
37880
|
if (!indexPath) return;
|
|
37780
|
-
void
|
|
37881
|
+
void mkdir12(join17(threadIndexRoot, task.agentId), { recursive: true }).then(() => writeFile6(indexPath, JSON.stringify({ threadId }), "utf8")).catch(() => {
|
|
37781
37882
|
});
|
|
37782
37883
|
};
|
|
37783
37884
|
const observeRuntime = (threadId) => {
|
|
@@ -38513,9 +38614,9 @@ function run2(command, args) {
|
|
|
38513
38614
|
// src/linux-service.ts
|
|
38514
38615
|
import { spawn as spawn10 } from "node:child_process";
|
|
38515
38616
|
import { constants as constants2 } from "node:fs";
|
|
38516
|
-
import { access as access4, chmod as chmod7, mkdir as
|
|
38617
|
+
import { access as access4, chmod as chmod7, mkdir as mkdir13, open as open7, rename as rename6, rm as rm9 } from "node:fs/promises";
|
|
38517
38618
|
import { homedir as homedir8, userInfo } from "node:os";
|
|
38518
|
-
import { basename as
|
|
38619
|
+
import { basename as basename5, dirname as dirname10, join as join18, relative as relative9, resolve as resolve12, sep as sep5 } from "node:path";
|
|
38519
38620
|
var SERVICE_NAME = "zixt-host.service";
|
|
38520
38621
|
var SYSTEM_SERVICE_COMMAND_TIMEOUT_MS = 7e4;
|
|
38521
38622
|
var SERVICE_STABILITY_DELAY_MS = 2e3;
|
|
@@ -38616,22 +38717,22 @@ async function defaultSyncDirectory(path) {
|
|
|
38616
38717
|
}
|
|
38617
38718
|
}
|
|
38618
38719
|
async function ensureDirectory(path, mode, syncDirectory7) {
|
|
38619
|
-
const firstCreated = await
|
|
38720
|
+
const firstCreated = await mkdir13(path, { recursive: true, mode });
|
|
38620
38721
|
if (!firstCreated) return;
|
|
38621
38722
|
const first = resolve12(firstCreated);
|
|
38622
38723
|
const target = resolve12(path);
|
|
38623
|
-
await syncDirectory7(
|
|
38724
|
+
await syncDirectory7(dirname10(first));
|
|
38624
38725
|
let current = first;
|
|
38625
38726
|
const descendants = relative9(first, target);
|
|
38626
38727
|
for (const part of descendants ? descendants.split(sep5) : []) {
|
|
38627
38728
|
await syncDirectory7(current);
|
|
38628
|
-
current =
|
|
38729
|
+
current = join18(current, part);
|
|
38629
38730
|
}
|
|
38630
38731
|
}
|
|
38631
38732
|
async function replacePrivateFile(path, contents, mode, syncDirectory7) {
|
|
38632
|
-
const parent =
|
|
38733
|
+
const parent = dirname10(path);
|
|
38633
38734
|
await ensureDirectory(parent, 448, syncDirectory7);
|
|
38634
|
-
const temporary =
|
|
38735
|
+
const temporary = join18(parent, `.${basename5(path)}.${process.pid}.${crypto.randomUUID()}.tmp`);
|
|
38635
38736
|
const handle = await open7(temporary, "wx", mode);
|
|
38636
38737
|
try {
|
|
38637
38738
|
await handle.writeFile(contents, "utf8");
|
|
@@ -38642,7 +38743,7 @@ async function replacePrivateFile(path, contents, mode, syncDirectory7) {
|
|
|
38642
38743
|
await syncDirectory7(parent);
|
|
38643
38744
|
} catch (error52) {
|
|
38644
38745
|
await handle.close().catch(() => void 0);
|
|
38645
|
-
await
|
|
38746
|
+
await rm9(temporary, { force: true }).catch(() => void 0);
|
|
38646
38747
|
throw error52;
|
|
38647
38748
|
}
|
|
38648
38749
|
}
|
|
@@ -38683,11 +38784,11 @@ async function installLinuxService(options) {
|
|
|
38683
38784
|
"command search path"
|
|
38684
38785
|
);
|
|
38685
38786
|
const cloudUrl = options.cloudUrl ? oneLine(options.cloudUrl, "Zixt Cloud address") : void 0;
|
|
38686
|
-
const xdgConfigHome = env.XDG_CONFIG_HOME ? oneLine(env.XDG_CONFIG_HOME, "Linux configuration path") :
|
|
38687
|
-
const configRoot = options.serviceConfigRoot ??
|
|
38688
|
-
const unitRoot = options.userUnitRoot ??
|
|
38689
|
-
const environmentPath =
|
|
38690
|
-
const unitPath =
|
|
38787
|
+
const xdgConfigHome = env.XDG_CONFIG_HOME ? oneLine(env.XDG_CONFIG_HOME, "Linux configuration path") : join18(home, ".config");
|
|
38788
|
+
const configRoot = options.serviceConfigRoot ?? join18(xdgConfigHome, "zixt");
|
|
38789
|
+
const unitRoot = options.userUnitRoot ?? join18(xdgConfigHome, "systemd", "user");
|
|
38790
|
+
const environmentPath = join18(configRoot, "host.env");
|
|
38791
|
+
const unitPath = join18(unitRoot, SERVICE_NAME);
|
|
38691
38792
|
const installVersion = options.installVersion ?? installRelease;
|
|
38692
38793
|
const activateVersion = options.activateVersion ?? (options.installVersion ? async (entry) => entry : activateInstalledRelease);
|
|
38693
38794
|
const resolveCommand = options.resolveCommand ?? defaultResolveCommand;
|
|
@@ -38806,9 +38907,9 @@ async function installLinuxService(options) {
|
|
|
38806
38907
|
// src/macos-service.ts
|
|
38807
38908
|
import { spawn as spawn11 } from "node:child_process";
|
|
38808
38909
|
import { constants as constants3 } from "node:fs";
|
|
38809
|
-
import { access as access5, chmod as chmod8, mkdir as
|
|
38910
|
+
import { access as access5, chmod as chmod8, mkdir as mkdir14, open as open8, rename as rename7, rm as rm10 } from "node:fs/promises";
|
|
38810
38911
|
import { homedir as homedir9, userInfo as userInfo2 } from "node:os";
|
|
38811
|
-
import { basename as
|
|
38912
|
+
import { basename as basename6, dirname as dirname11, join as join19, relative as relative10, resolve as resolve13, sep as sep6 } from "node:path";
|
|
38812
38913
|
var LAUNCH_AGENT_LABEL = "ai.zixt.host";
|
|
38813
38914
|
var SERVICE_STABILITY_DELAY_MS2 = 2e3;
|
|
38814
38915
|
var COMMAND_TIMEOUT_MS2 = 7e4;
|
|
@@ -38832,21 +38933,21 @@ async function syncDirectory4(path) {
|
|
|
38832
38933
|
}
|
|
38833
38934
|
}
|
|
38834
38935
|
async function ensureDirectory2(path, sync) {
|
|
38835
|
-
const firstCreated = await
|
|
38936
|
+
const firstCreated = await mkdir14(path, { recursive: true, mode: 448 });
|
|
38836
38937
|
if (!firstCreated) return;
|
|
38837
38938
|
const first = resolve13(firstCreated);
|
|
38838
38939
|
const target = resolve13(path);
|
|
38839
|
-
await sync(
|
|
38940
|
+
await sync(dirname11(first));
|
|
38840
38941
|
let current = first;
|
|
38841
38942
|
for (const part of relative10(first, target).split(sep6).filter(Boolean)) {
|
|
38842
38943
|
await sync(current);
|
|
38843
|
-
current =
|
|
38944
|
+
current = join19(current, part);
|
|
38844
38945
|
}
|
|
38845
38946
|
}
|
|
38846
38947
|
async function replacePrivateFile2(path, contents, mode, sync) {
|
|
38847
|
-
const parent =
|
|
38948
|
+
const parent = dirname11(path);
|
|
38848
38949
|
await ensureDirectory2(parent, sync);
|
|
38849
|
-
const temporary =
|
|
38950
|
+
const temporary = join19(parent, `.${basename6(path)}.${process.pid}.${crypto.randomUUID()}.tmp`);
|
|
38850
38951
|
const handle = await open8(temporary, "wx", mode);
|
|
38851
38952
|
try {
|
|
38852
38953
|
await handle.writeFile(contents, "utf8");
|
|
@@ -38857,7 +38958,7 @@ async function replacePrivateFile2(path, contents, mode, sync) {
|
|
|
38857
38958
|
await sync(parent);
|
|
38858
38959
|
} catch (error52) {
|
|
38859
38960
|
await handle.close().catch(() => void 0);
|
|
38860
|
-
await
|
|
38961
|
+
await rm10(temporary, { force: true }).catch(() => void 0);
|
|
38861
38962
|
throw error52;
|
|
38862
38963
|
}
|
|
38863
38964
|
}
|
|
@@ -38943,14 +39044,14 @@ async function installMacosService(options) {
|
|
|
38943
39044
|
options.path ?? env.PATH ?? "/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin",
|
|
38944
39045
|
"command search path"
|
|
38945
39046
|
);
|
|
38946
|
-
const configRoot = options.configRoot ??
|
|
38947
|
-
const launchAgentsRoot = options.launchAgentsRoot ??
|
|
38948
|
-
const logRoot = options.logRoot ??
|
|
38949
|
-
const configPath =
|
|
38950
|
-
const launcherPath =
|
|
38951
|
-
const plistPath =
|
|
38952
|
-
const stdoutPath =
|
|
38953
|
-
const stderrPath =
|
|
39047
|
+
const configRoot = options.configRoot ?? join19(home, "Library", "Application Support", "Zixt");
|
|
39048
|
+
const launchAgentsRoot = options.launchAgentsRoot ?? join19(home, "Library", "LaunchAgents");
|
|
39049
|
+
const logRoot = options.logRoot ?? join19(home, "Library", "Logs", "Zixt");
|
|
39050
|
+
const configPath = join19(configRoot, "host.env");
|
|
39051
|
+
const launcherPath = join19(configRoot, "host-launcher.sh");
|
|
39052
|
+
const plistPath = join19(launchAgentsRoot, `${LAUNCH_AGENT_LABEL}.plist`);
|
|
39053
|
+
const stdoutPath = join19(logRoot, "host.log");
|
|
39054
|
+
const stderrPath = join19(logRoot, "host-error.log");
|
|
38954
39055
|
const installVersion = options.installVersion ?? installRelease;
|
|
38955
39056
|
const activateVersion = options.activateVersion ?? (options.installVersion ? async (entry) => entry : (entry) => activateInstalledRelease(entry));
|
|
38956
39057
|
const resolveCommand = options.resolveCommand ?? (async () => defaultResolveCommand2());
|
|
@@ -39037,9 +39138,9 @@ async function installMacosService(options) {
|
|
|
39037
39138
|
// src/windows-service.ts
|
|
39038
39139
|
import { spawn as spawn12 } from "node:child_process";
|
|
39039
39140
|
import { constants as constants4 } from "node:fs";
|
|
39040
|
-
import { access as access6, mkdir as
|
|
39141
|
+
import { access as access6, mkdir as mkdir15, open as open9, readFile as readFile10, rename as rename8, rm as rm11 } from "node:fs/promises";
|
|
39041
39142
|
import { homedir as homedir10 } from "node:os";
|
|
39042
|
-
import { basename as
|
|
39143
|
+
import { basename as basename7, dirname as dirname12, isAbsolute as isAbsolute16, join as join20, relative as relative11, resolve as resolve14, sep as sep7 } from "node:path";
|
|
39043
39144
|
var TASK_NAME = "Zixt Host";
|
|
39044
39145
|
var COMMAND_TIMEOUT_MS3 = 7e4;
|
|
39045
39146
|
var SERVICE_STABILITY_DELAY_MS3 = 2e3;
|
|
@@ -39065,21 +39166,21 @@ async function syncDirectory5(path) {
|
|
|
39065
39166
|
}
|
|
39066
39167
|
}
|
|
39067
39168
|
async function ensureDirectory3(path, sync) {
|
|
39068
|
-
const firstCreated = await
|
|
39169
|
+
const firstCreated = await mkdir15(path, { recursive: true, mode: 448 });
|
|
39069
39170
|
if (!firstCreated) return;
|
|
39070
39171
|
const first = resolve14(firstCreated);
|
|
39071
39172
|
const target = resolve14(path);
|
|
39072
|
-
await sync(
|
|
39173
|
+
await sync(dirname12(first));
|
|
39073
39174
|
let current = first;
|
|
39074
39175
|
for (const part of relative11(first, target).split(sep7).filter(Boolean)) {
|
|
39075
39176
|
await sync(current);
|
|
39076
|
-
current =
|
|
39177
|
+
current = join20(current, part);
|
|
39077
39178
|
}
|
|
39078
39179
|
}
|
|
39079
39180
|
async function replacePrivateFile3(path, contents, sync) {
|
|
39080
|
-
const parent =
|
|
39181
|
+
const parent = dirname12(path);
|
|
39081
39182
|
await ensureDirectory3(parent, sync);
|
|
39082
|
-
const temporary =
|
|
39183
|
+
const temporary = join20(parent, `.${basename7(path)}.${process.pid}.${crypto.randomUUID()}.tmp`);
|
|
39083
39184
|
const handle = await open9(temporary, "wx", 384);
|
|
39084
39185
|
try {
|
|
39085
39186
|
await handle.writeFile(contents, "utf8");
|
|
@@ -39089,7 +39190,7 @@ async function replacePrivateFile3(path, contents, sync) {
|
|
|
39089
39190
|
await sync(parent);
|
|
39090
39191
|
} catch (error52) {
|
|
39091
39192
|
await handle.close().catch(() => void 0);
|
|
39092
|
-
await
|
|
39193
|
+
await rm11(temporary, { force: true }).catch(() => void 0);
|
|
39093
39194
|
throw error52;
|
|
39094
39195
|
}
|
|
39095
39196
|
}
|
|
@@ -39134,7 +39235,7 @@ async function runChild(command, args, env, input) {
|
|
|
39134
39235
|
async function defaultResolveCommand3(name, env) {
|
|
39135
39236
|
const root = env.SYSTEMROOT ?? env.WINDIR;
|
|
39136
39237
|
if (!root || !isAbsolute16(root)) return null;
|
|
39137
|
-
const candidate = name === "powershell" ?
|
|
39238
|
+
const candidate = name === "powershell" ? join20(root, "System32", "WindowsPowerShell", "v1.0", "powershell.exe") : join20(root, "System32", `${name}.exe`);
|
|
39138
39239
|
return access6(candidate, constants4.X_OK).then(
|
|
39139
39240
|
() => candidate,
|
|
39140
39241
|
() => null
|
|
@@ -39271,11 +39372,11 @@ async function installWindowsService(options) {
|
|
|
39271
39372
|
const token2 = oneLine3(options.token, "pairing code");
|
|
39272
39373
|
const cloudUrl = options.cloudUrl ? oneLine3(options.cloudUrl, "Zixt Cloud address") : void 0;
|
|
39273
39374
|
const path = oneLine3(options.path ?? env.PATH ?? "", "command search path");
|
|
39274
|
-
const configRoot = options.configRoot ??
|
|
39275
|
-
const configPath =
|
|
39276
|
-
const launcherPath =
|
|
39277
|
-
const taskXmlPath =
|
|
39278
|
-
const statusPath =
|
|
39375
|
+
const configRoot = options.configRoot ?? join20(localAppData, "Zixt", "Host");
|
|
39376
|
+
const configPath = join20(configRoot, "host.json");
|
|
39377
|
+
const launcherPath = join20(configRoot, "host-launcher.ps1");
|
|
39378
|
+
const taskXmlPath = join20(configRoot, "host-task.xml");
|
|
39379
|
+
const statusPath = join20(configRoot, "host-status.json");
|
|
39279
39380
|
const installVersion = options.installVersion ?? installRelease;
|
|
39280
39381
|
const activateVersion = options.activateVersion ?? (options.installVersion ? async (entry) => entry : (entry) => activateInstalledRelease(entry));
|
|
39281
39382
|
const resolveCommand = options.resolveCommand ?? ((name) => defaultResolveCommand3(name, env));
|
|
@@ -39324,7 +39425,7 @@ async function installWindowsService(options) {
|
|
|
39324
39425
|
);
|
|
39325
39426
|
await replacePrivateFile3(launcherPath, launcherSource2(configPath, statusPath), sync);
|
|
39326
39427
|
await replacePrivateFile3(taskXmlPath, taskXml({ sid, powershell, launcherPath, home }), sync);
|
|
39327
|
-
await
|
|
39428
|
+
await rm11(statusPath, { force: true });
|
|
39328
39429
|
const acl = await run3(icacls, [
|
|
39329
39430
|
configRoot,
|
|
39330
39431
|
"/inheritance:r",
|
|
@@ -39376,23 +39477,23 @@ async function installSystemService(options) {
|
|
|
39376
39477
|
}
|
|
39377
39478
|
|
|
39378
39479
|
// src/terminal-outcomes.ts
|
|
39379
|
-
import { chmod as chmod9, lstat as lstat12, mkdir as
|
|
39480
|
+
import { chmod as chmod9, lstat as lstat12, mkdir as mkdir16, open as open10, readdir as readdir5, readFile as readFile11, rename as rename9, rm as rm12 } from "node:fs/promises";
|
|
39380
39481
|
import { homedir as homedir11 } from "node:os";
|
|
39381
|
-
import { dirname as
|
|
39482
|
+
import { dirname as dirname13, join as join21, relative as relative12, resolve as resolve15, sep as sep8 } from "node:path";
|
|
39382
39483
|
var DIRECTORY_MODE5 = 448;
|
|
39383
39484
|
var FILE_MODE4 = 384;
|
|
39384
39485
|
var MAX_OUTCOME_BYTES = 4 * 1024 * 1024;
|
|
39385
39486
|
var HOST_DIRECTORY = /^hst_[0-9a-f]{32}$/;
|
|
39386
39487
|
var OUTCOME_FILE = /^(tsk_[0-9a-f]{32})\.([1-9][0-9]*)\.json$/;
|
|
39387
39488
|
function defaultTerminalOutcomeRoot() {
|
|
39388
|
-
return
|
|
39489
|
+
return join21(homedir11(), ".zixt", "terminal-outcomes");
|
|
39389
39490
|
}
|
|
39390
39491
|
function hostOutcomeRoot(root, hostId) {
|
|
39391
39492
|
if (!HOST_DIRECTORY.test(hostId)) throw new Error("terminal outcome Host identity is malformed");
|
|
39392
|
-
return
|
|
39493
|
+
return join21(root, hostId);
|
|
39393
39494
|
}
|
|
39394
39495
|
function outcomePath(root, hostId, taskId, epoch) {
|
|
39395
|
-
return
|
|
39496
|
+
return join21(hostOutcomeRoot(root, hostId), `${taskId}.${epoch}.json`);
|
|
39396
39497
|
}
|
|
39397
39498
|
async function syncDirectory6(root) {
|
|
39398
39499
|
if (process.platform === "win32") return;
|
|
@@ -39404,15 +39505,15 @@ async function syncDirectory6(root) {
|
|
|
39404
39505
|
}
|
|
39405
39506
|
}
|
|
39406
39507
|
async function requirePrivateRoot(root, sync = syncDirectory6) {
|
|
39407
|
-
const firstCreated = await
|
|
39508
|
+
const firstCreated = await mkdir16(root, { recursive: true, mode: DIRECTORY_MODE5 });
|
|
39408
39509
|
if (firstCreated) {
|
|
39409
39510
|
const first = resolve15(firstCreated);
|
|
39410
39511
|
const target = resolve15(root);
|
|
39411
|
-
await sync(
|
|
39512
|
+
await sync(dirname13(first));
|
|
39412
39513
|
let current = first;
|
|
39413
39514
|
for (const part of relative12(first, target).split(sep8).filter(Boolean)) {
|
|
39414
39515
|
await sync(current);
|
|
39415
|
-
current =
|
|
39516
|
+
current = join21(current, part);
|
|
39416
39517
|
}
|
|
39417
39518
|
}
|
|
39418
39519
|
const stat3 = await lstat12(root);
|
|
@@ -39452,7 +39553,7 @@ async function recordTerminalOutcome(hostId, input, root = defaultTerminalOutcom
|
|
|
39452
39553
|
} catch (error52) {
|
|
39453
39554
|
if (error52.code !== "ENOENT") throw error52;
|
|
39454
39555
|
}
|
|
39455
|
-
const temporary =
|
|
39556
|
+
const temporary = join21(
|
|
39456
39557
|
scopedRoot,
|
|
39457
39558
|
`.${outcome.taskId}.${outcome.epoch}.${process.pid}.${Date.now()}.${outcome.resultId}.tmp`
|
|
39458
39559
|
);
|
|
@@ -39469,7 +39570,7 @@ async function recordTerminalOutcome(hostId, input, root = defaultTerminalOutcom
|
|
|
39469
39570
|
} finally {
|
|
39470
39571
|
await handle?.close().catch(() => {
|
|
39471
39572
|
});
|
|
39472
|
-
await
|
|
39573
|
+
await rm12(temporary, { force: true }).catch(() => {
|
|
39473
39574
|
});
|
|
39474
39575
|
}
|
|
39475
39576
|
}
|
|
@@ -39505,7 +39606,7 @@ async function readTerminalOutcomesStrict(root = defaultTerminalOutcomeRoot()) {
|
|
|
39505
39606
|
if (!match || !entry.isFile() || entry.isSymbolicLink()) {
|
|
39506
39607
|
throw new Error("committed terminal outcome is not a trusted regular file");
|
|
39507
39608
|
}
|
|
39508
|
-
const path =
|
|
39609
|
+
const path = join21(scopedRoot, entry.name);
|
|
39509
39610
|
const stat3 = await lstat12(path);
|
|
39510
39611
|
if (!stat3.isFile() || stat3.isSymbolicLink() || stat3.size > MAX_OUTCOME_BYTES) {
|
|
39511
39612
|
throw new Error("committed terminal outcome is not a trusted regular file");
|
|
@@ -39538,7 +39639,7 @@ async function forgetAcknowledgedTerminalOutcomes(refs, root = defaultTerminalOu
|
|
|
39538
39639
|
if (acknowledged.get(`${hostId}:${outcome.taskId}:${outcome.epoch}`) !== outcome.resultId) {
|
|
39539
39640
|
continue;
|
|
39540
39641
|
}
|
|
39541
|
-
await
|
|
39642
|
+
await rm12(outcomePath(root, hostId, outcome.taskId, outcome.epoch), { force: true });
|
|
39542
39643
|
changedHostRoots.add(hostOutcomeRoot(root, hostId));
|
|
39543
39644
|
}
|
|
39544
39645
|
for (const scopedRoot of changedHostRoots) await syncDirectory6(scopedRoot);
|
|
@@ -39550,7 +39651,7 @@ async function forgetSupersededTerminalOutcomes(hostId, taskId, epoch, root = de
|
|
|
39550
39651
|
if (scoped.hostId !== hostId) continue;
|
|
39551
39652
|
const { outcome } = scoped;
|
|
39552
39653
|
if (outcome.taskId !== taskId || outcome.epoch >= epoch) continue;
|
|
39553
|
-
await
|
|
39654
|
+
await rm12(outcomePath(root, hostId, outcome.taskId, outcome.epoch), { force: true });
|
|
39554
39655
|
removed = true;
|
|
39555
39656
|
}
|
|
39556
39657
|
if (removed) await syncDirectory6(hostOutcomeRoot(root, hostId));
|
|
@@ -39658,7 +39759,7 @@ function createHostLogger(options = {}) {
|
|
|
39658
39759
|
}
|
|
39659
39760
|
|
|
39660
39761
|
// src/demo-state.ts
|
|
39661
|
-
import { isAbsolute as isAbsolute17, join as
|
|
39762
|
+
import { isAbsolute as isAbsolute17, join as join22, parse as parse3, resolve as resolve16 } from "node:path";
|
|
39662
39763
|
var DEMO_STATE_ROOT_ENV = "ZIXT_DEMO_STATE_ROOT";
|
|
39663
39764
|
function resolveDemoHostStatePaths(env = process.env) {
|
|
39664
39765
|
const configured = env.ZIXT_RUNNER === "demo" ? env[DEMO_STATE_ROOT_ENV] : void 0;
|
|
@@ -39668,12 +39769,12 @@ function resolveDemoHostStatePaths(env = process.env) {
|
|
|
39668
39769
|
throw new Error(`${DEMO_STATE_ROOT_ENV} must be a dedicated absolute directory`);
|
|
39669
39770
|
}
|
|
39670
39771
|
return {
|
|
39671
|
-
runRegistryRoot:
|
|
39672
|
-
terminalOutcomeRoot:
|
|
39673
|
-
runArtifactRoot:
|
|
39674
|
-
browserProfileRoot:
|
|
39675
|
-
runnerWorkspaceRoot:
|
|
39676
|
-
codexThreadIndexRoot:
|
|
39772
|
+
runRegistryRoot: join22(root, "run-registry"),
|
|
39773
|
+
terminalOutcomeRoot: join22(root, "terminal-outcomes"),
|
|
39774
|
+
runArtifactRoot: join22(root, "run-artifacts"),
|
|
39775
|
+
browserProfileRoot: join22(root, "browser-profiles"),
|
|
39776
|
+
runnerWorkspaceRoot: join22(root, "workspaces"),
|
|
39777
|
+
codexThreadIndexRoot: join22(root, "codex-threads")
|
|
39677
39778
|
};
|
|
39678
39779
|
}
|
|
39679
39780
|
|