@zixt/host 0.0.135 → 0.0.137
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 +843 -182
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -28,7 +28,7 @@ import { homedir as homedir4 } from "node:os";
|
|
|
28
28
|
// package.json
|
|
29
29
|
var package_default = {
|
|
30
30
|
name: "@zixt/host",
|
|
31
|
-
version: "0.0.
|
|
31
|
+
version: "0.0.137",
|
|
32
32
|
type: "module",
|
|
33
33
|
exports: {
|
|
34
34
|
".": "./src/client.ts",
|
|
@@ -14700,6 +14700,10 @@ var ID_PREFIXES = {
|
|
|
14700
14700
|
voiceTurn: "vtr",
|
|
14701
14701
|
/** One signed voice-provider webhook receipt. */
|
|
14702
14702
|
voiceWebhookEvent: "vwe",
|
|
14703
|
+
/** One live browser microphone session with the Zixt Guide (UI-16). */
|
|
14704
|
+
guideVoiceSession: "gvs",
|
|
14705
|
+
/** One Guide reply authorized to be spoken on that session. */
|
|
14706
|
+
guideVoiceSpeech: "gvt",
|
|
14703
14707
|
/** Org-singleton Company setup record (PRD OB-5). */
|
|
14704
14708
|
companySetup: "cst",
|
|
14705
14709
|
/** One durable set of teammate-proposed Automations awaiting an Admin (OB-12). */
|
|
@@ -14780,6 +14784,11 @@ var VoiceLineId = idSchema(ID_PREFIXES.voiceLine, "voice line id");
|
|
|
14780
14784
|
var VoiceCallerId = idSchema(ID_PREFIXES.voiceCaller, "voice caller id");
|
|
14781
14785
|
var VoiceCallId = idSchema(ID_PREFIXES.voiceCall, "voice call id");
|
|
14782
14786
|
var VoiceTurnId = idSchema(ID_PREFIXES.voiceTurn, "voice turn id");
|
|
14787
|
+
var GuideVoiceSessionId = idSchema(
|
|
14788
|
+
ID_PREFIXES.guideVoiceSession,
|
|
14789
|
+
"Guide voice session id"
|
|
14790
|
+
);
|
|
14791
|
+
var GuideVoiceSpeechId = idSchema(ID_PREFIXES.guideVoiceSpeech, "Guide speech id");
|
|
14783
14792
|
var VoiceWebhookEventId = idSchema(
|
|
14784
14793
|
ID_PREFIXES.voiceWebhookEvent,
|
|
14785
14794
|
"voice webhook event id"
|
|
@@ -19659,6 +19668,19 @@ var TestWebhookDeliveryRequest = external_exports.object({
|
|
|
19659
19668
|
// ../../packages/contracts/src/manager.ts
|
|
19660
19669
|
var MANAGER_DEFAULT_MODEL = "gpt-5.6-luna";
|
|
19661
19670
|
var MANAGER_DEFAULT_PORTRAIT = 23;
|
|
19671
|
+
var ManagerVoiceName = external_exports.enum([
|
|
19672
|
+
"marin",
|
|
19673
|
+
"cedar",
|
|
19674
|
+
"alloy",
|
|
19675
|
+
"ash",
|
|
19676
|
+
"ballad",
|
|
19677
|
+
"coral",
|
|
19678
|
+
"echo",
|
|
19679
|
+
"sage",
|
|
19680
|
+
"shimmer",
|
|
19681
|
+
"verse"
|
|
19682
|
+
]);
|
|
19683
|
+
var MANAGER_DEFAULT_VOICE = "marin";
|
|
19662
19684
|
var MANAGER_DISPLAY_NAME_MAX = 60;
|
|
19663
19685
|
var MANAGER_INSTRUCTIONS_MAX = 2e4;
|
|
19664
19686
|
var CONVERSATION_MESSAGE_MAX = 1e5;
|
|
@@ -19694,6 +19716,11 @@ var ManagerConfigProjection = external_exports.object({
|
|
|
19694
19716
|
* never rejected by a server that has not shipped the newer artwork yet.
|
|
19695
19717
|
*/
|
|
19696
19718
|
portrait: external_exports.number().int().min(0).max(63).default(MANAGER_DEFAULT_PORTRAIT),
|
|
19719
|
+
/**
|
|
19720
|
+
* The voice every spoken Zixt surface renders in for this organization.
|
|
19721
|
+
* Older rows carry none and read as MANAGER_DEFAULT_VOICE.
|
|
19722
|
+
*/
|
|
19723
|
+
voice: ManagerVoiceName.default(MANAGER_DEFAULT_VOICE),
|
|
19697
19724
|
revision: external_exports.number().int().min(0),
|
|
19698
19725
|
updatedAt: external_exports.string().nullable()
|
|
19699
19726
|
}).strict();
|
|
@@ -19709,10 +19736,11 @@ var UpdateManagerRequest = external_exports.object({
|
|
|
19709
19736
|
answerDirectMessages: external_exports.boolean().optional()
|
|
19710
19737
|
}).strict().optional(),
|
|
19711
19738
|
portrait: external_exports.number().int().min(0).max(63).optional(),
|
|
19739
|
+
voice: ManagerVoiceName.optional(),
|
|
19712
19740
|
/** Optimistic concurrency: refuse when another admin saved first. */
|
|
19713
19741
|
expectedRevision: external_exports.number().int().min(0).optional()
|
|
19714
19742
|
}).strict().superRefine((value, ctx) => {
|
|
19715
|
-
if (value.displayName === void 0 && value.instructions === void 0 && value.model === void 0 && value.reasoningEffort === void 0 && value.slack === void 0 && value.portrait === void 0) {
|
|
19743
|
+
if (value.displayName === void 0 && value.instructions === void 0 && value.model === void 0 && value.reasoningEffort === void 0 && value.slack === void 0 && value.portrait === void 0 && value.voice === void 0) {
|
|
19716
19744
|
ctx.addIssue({ code: "custom", message: "nothing to update" });
|
|
19717
19745
|
}
|
|
19718
19746
|
});
|
|
@@ -22184,7 +22212,13 @@ var SetupGuideReplyRequest = external_exports.object({
|
|
|
22184
22212
|
onboarding: SetupGuideOnboardingState,
|
|
22185
22213
|
actions: external_exports.array(SetupGuideAvailableAction).max(128),
|
|
22186
22214
|
toolResults: external_exports.array(SetupGuideToolResult).max(12).default([]),
|
|
22187
|
-
mission: SetupGuideMission.nullable().optional()
|
|
22215
|
+
mission: SetupGuideMission.nullable().optional(),
|
|
22216
|
+
/**
|
|
22217
|
+
* The live Guide voice session this turn was spoken into. It only authorizes
|
|
22218
|
+
* the resulting reply to be spoken on that same session; it never changes
|
|
22219
|
+
* what the Guide may read, propose, or execute.
|
|
22220
|
+
*/
|
|
22221
|
+
voiceSessionId: GuideVoiceSessionId.optional()
|
|
22188
22222
|
});
|
|
22189
22223
|
var SetupGuideProposedAction = external_exports.object({
|
|
22190
22224
|
actionId: external_exports.string().regex(/^[a-z][a-z0-9_.-]{0,79}$/),
|
|
@@ -22195,11 +22229,21 @@ var SetupGuideProposedAction = external_exports.object({
|
|
|
22195
22229
|
*/
|
|
22196
22230
|
parameters: external_exports.array(SetupGuideActionParameter).max(12)
|
|
22197
22231
|
});
|
|
22198
|
-
var
|
|
22232
|
+
var SetupGuideAnswer = external_exports.object({
|
|
22199
22233
|
message: GuideText,
|
|
22200
22234
|
/** One tool at a time keeps UI execution and its result causally ordered. */
|
|
22201
22235
|
proposedActions: external_exports.array(SetupGuideProposedAction).max(1)
|
|
22202
22236
|
});
|
|
22237
|
+
var SetupGuideReplyResponse = SetupGuideAnswer.extend({
|
|
22238
|
+
/**
|
|
22239
|
+
* Identity this exact committed reply may be spoken under, present only when
|
|
22240
|
+
* the request named a live voice session. The browser runs a bounded action
|
|
22241
|
+
* loop, so only it knows which reply in that loop is the person's answer;
|
|
22242
|
+
* this id is how it says "speak that one" without ever sending prose back for
|
|
22243
|
+
* the cloud to read aloud.
|
|
22244
|
+
*/
|
|
22245
|
+
speech: external_exports.object({ id: GuideVoiceSpeechId }).strict().nullable().default(null)
|
|
22246
|
+
});
|
|
22203
22247
|
var SetupGuideTranscriptionRequest = external_exports.object({
|
|
22204
22248
|
mediaType: external_exports.enum(["audio/webm", "audio/mp4", "audio/ogg"]),
|
|
22205
22249
|
/** Bounded short-lived audio. The route decodes it in memory and never stores it. */
|
|
@@ -22208,6 +22252,52 @@ var SetupGuideTranscriptionRequest = external_exports.object({
|
|
|
22208
22252
|
var SetupGuideTranscriptionResponse = external_exports.object({
|
|
22209
22253
|
text: GuideText
|
|
22210
22254
|
});
|
|
22255
|
+
var StartGuideVoiceSessionRequest = external_exports.object({
|
|
22256
|
+
/** Stable client fence; an ambiguous provider create is never resubmitted under it. */
|
|
22257
|
+
requestId: external_exports.uuid(),
|
|
22258
|
+
offerSdp: BrowserVoiceSessionDescription
|
|
22259
|
+
}).strict();
|
|
22260
|
+
var GuideVoiceSessionStatus = external_exports.enum([
|
|
22261
|
+
"connecting",
|
|
22262
|
+
"connected",
|
|
22263
|
+
"ending",
|
|
22264
|
+
"ended",
|
|
22265
|
+
"failed"
|
|
22266
|
+
]);
|
|
22267
|
+
var GuideVoiceSessionProjection = external_exports.object({
|
|
22268
|
+
id: GuideVoiceSessionId,
|
|
22269
|
+
status: GuideVoiceSessionStatus,
|
|
22270
|
+
startedAt: IsoDate2,
|
|
22271
|
+
expiresAt: IsoDate2
|
|
22272
|
+
}).strict();
|
|
22273
|
+
var StartGuideVoiceSessionResponse = external_exports.object({
|
|
22274
|
+
session: GuideVoiceSessionProjection,
|
|
22275
|
+
/** Applied directly to the browser peer connection and never persisted by Zixt. */
|
|
22276
|
+
answerSdp: BrowserVoiceSessionDescription
|
|
22277
|
+
}).strict();
|
|
22278
|
+
var AckGuideVoiceSessionResponse = external_exports.object({ session: GuideVoiceSessionProjection }).strict();
|
|
22279
|
+
var EndGuideVoiceSessionResponse = external_exports.object({ ended: external_exports.literal(true) }).strict();
|
|
22280
|
+
var GuideVoiceCaption = external_exports.string().max(4e3);
|
|
22281
|
+
var GuideVoicePresentationFrame = external_exports.discriminatedUnion("type", [
|
|
22282
|
+
external_exports.object({ type: external_exports.literal("listening_started") }).strict(),
|
|
22283
|
+
external_exports.object({ type: external_exports.literal("listening_stopped") }).strict(),
|
|
22284
|
+
external_exports.object({ type: external_exports.literal("user_caption"), text: GuideVoiceCaption, final: external_exports.boolean() }).strict(),
|
|
22285
|
+
external_exports.object({
|
|
22286
|
+
type: external_exports.literal("guide_speech_started"),
|
|
22287
|
+
speechId: GuideVoiceSpeechId,
|
|
22288
|
+
text: GuideVoiceCaption
|
|
22289
|
+
}).strict(),
|
|
22290
|
+
external_exports.object({ type: external_exports.literal("guide_speech_stopped"), speechId: GuideVoiceSpeechId }).strict(),
|
|
22291
|
+
external_exports.object({ type: external_exports.literal("guide_speech_failed"), speechId: GuideVoiceSpeechId }).strict(),
|
|
22292
|
+
external_exports.object({ type: external_exports.literal("guide_speech_idle") }).strict(),
|
|
22293
|
+
external_exports.object({ type: external_exports.literal("transcription_failed") }).strict(),
|
|
22294
|
+
external_exports.object({ type: external_exports.literal("session_ended") }).strict(),
|
|
22295
|
+
external_exports.object({ type: external_exports.literal("session_failed") }).strict()
|
|
22296
|
+
]);
|
|
22297
|
+
var SpeakGuideVoiceReplyRequest = external_exports.object({ speechId: GuideVoiceSpeechId }).strict();
|
|
22298
|
+
var SpeakGuideVoiceReplyResponse = external_exports.object({ speaking: external_exports.boolean() }).strict();
|
|
22299
|
+
var InterruptGuideVoiceSessionRequest = external_exports.object({ speechId: GuideVoiceSpeechId }).strict();
|
|
22300
|
+
var InterruptGuideVoiceSessionResponse = external_exports.object({ interrupted: external_exports.boolean() }).strict();
|
|
22211
22301
|
|
|
22212
22302
|
// ../../packages/contracts/src/roles.ts
|
|
22213
22303
|
var CompanyToolKind = external_exports.enum([
|
|
@@ -22472,6 +22562,12 @@ var CompanySetupProgress = external_exports.object({
|
|
|
22472
22562
|
/** Every recommended step is done or skipped. */
|
|
22473
22563
|
recommendedSettled: external_exports.boolean()
|
|
22474
22564
|
});
|
|
22565
|
+
var COMPANY_SETUP_PLANNING_NOTE_MAX = 200;
|
|
22566
|
+
var COMPANY_SETUP_PLANNING_NOTES_MAX = 20;
|
|
22567
|
+
var CompanySetupPlanningNote = external_exports.object({
|
|
22568
|
+
at: IsoDate,
|
|
22569
|
+
text: external_exports.string().trim().min(1).max(COMPANY_SETUP_PLANNING_NOTE_MAX)
|
|
22570
|
+
});
|
|
22475
22571
|
var CompanySetupApproval = external_exports.object({
|
|
22476
22572
|
at: IsoDate,
|
|
22477
22573
|
by: MemberId.nullable(),
|
|
@@ -22524,7 +22620,12 @@ var CompanySetupView = external_exports.object({
|
|
|
22524
22620
|
* The plan is being proposed in the background (a planner call can take a
|
|
22525
22621
|
* minute); the page polls until the plan lands or an error is recorded.
|
|
22526
22622
|
*/
|
|
22527
|
-
planning: external_exports.object({
|
|
22623
|
+
planning: external_exports.object({
|
|
22624
|
+
startedAt: IsoDate,
|
|
22625
|
+
error: external_exports.string().max(500).nullable(),
|
|
22626
|
+
/** Oldest first; the planner's visible decisions so far. */
|
|
22627
|
+
notes: external_exports.array(CompanySetupPlanningNote).max(COMPANY_SETUP_PLANNING_NOTES_MAX).default([])
|
|
22628
|
+
}).nullable(),
|
|
22528
22629
|
approval: CompanySetupApproval.nullable(),
|
|
22529
22630
|
steps: external_exports.array(CompanySetupStep),
|
|
22530
22631
|
progress: CompanySetupProgress,
|
|
@@ -31615,11 +31716,11 @@ function createPlaywrightBrowserAdapterFactory(dependencies = {}) {
|
|
|
31615
31716
|
}
|
|
31616
31717
|
|
|
31617
31718
|
// src/runners/cli-runner.ts
|
|
31618
|
-
import { spawn as
|
|
31619
|
-
import { randomUUID as
|
|
31620
|
-
import { lstat as lstat11, mkdir as
|
|
31719
|
+
import { spawn as spawn11 } from "node:child_process";
|
|
31720
|
+
import { randomUUID as randomUUID12 } from "node:crypto";
|
|
31721
|
+
import { lstat as lstat11, mkdir as mkdir13, realpath as realpath8 } from "node:fs/promises";
|
|
31621
31722
|
import { homedir as homedir7 } from "node:os";
|
|
31622
|
-
import { dirname as dirname10, isAbsolute as isAbsolute16, join as
|
|
31723
|
+
import { dirname as dirname10, isAbsolute as isAbsolute16, join as join19, resolve as resolve10 } from "node:path";
|
|
31623
31724
|
|
|
31624
31725
|
// src/tool-packs/browser/authentication-wall.ts
|
|
31625
31726
|
var AUTH_PATH_SEGMENT = /(?:^|\/)(?:log[-_]?in|sign[-_]?in|sso|saml|auth|authorize|authenticate|oauth2?|session\/new|checkpoint)(?:\/|$)/i;
|
|
@@ -38006,6 +38107,415 @@ function renderAttachmentSection(files) {
|
|
|
38006
38107
|
|
|
38007
38108
|
// src/runners/ask-user-server.ts
|
|
38008
38109
|
import { createServer as createServer2 } from "node:http";
|
|
38110
|
+
|
|
38111
|
+
// src/runners/software-install.ts
|
|
38112
|
+
import { spawn as spawn9 } from "node:child_process";
|
|
38113
|
+
import { createHash as createHash6, randomUUID as randomUUID11 } from "node:crypto";
|
|
38114
|
+
import { chmod as chmod6, mkdir as mkdir11, readFile as readFile10, readdir as readdir5, rename as rename6, rm as rm10, symlink as symlink2, writeFile as writeFile7 } from "node:fs/promises";
|
|
38115
|
+
import { join as join17, relative as relative8, resolve as resolvePath, sep as sep5 } from "node:path";
|
|
38116
|
+
var SOFTWARE_INSTALL_METHODS = ["npm", "download"];
|
|
38117
|
+
var SOFTWARE_INSTALL_REFUSAL = "Zixt installs software only into its own folder on this Machine, using npm or a direct download. It never runs a system package manager, never asks for elevation, and never builds from source. Tell the person plainly what is missing, why this work needs it, and the exact command they would run themselves.";
|
|
38118
|
+
var MAX_DOWNLOAD_BYTES = 512 * 1024 * 1024;
|
|
38119
|
+
var PROCESS_TIMEOUT_MS = 10 * 6e4;
|
|
38120
|
+
var DOWNLOAD_TIMEOUT_MS = 10 * 6e4;
|
|
38121
|
+
var FAILURE_COOLDOWN_MS2 = 10 * 6e4;
|
|
38122
|
+
var MAX_ARCHIVE_SEARCH_DEPTH = 5;
|
|
38123
|
+
var MANIFEST_NAME = "installed.json";
|
|
38124
|
+
var COMMAND_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._+-]{0,63}$/;
|
|
38125
|
+
var NPM_SPEC_PATTERN = /^(?:@[a-z0-9~][a-z0-9._~-]*\/)?[a-z0-9~][a-z0-9._~-]*(?:@\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?)?$/;
|
|
38126
|
+
function defaultSoftwareToolsRoot() {
|
|
38127
|
+
return defaultRunnerToolsRoot();
|
|
38128
|
+
}
|
|
38129
|
+
function softwareSearchPathEntries(toolsRoot = defaultSoftwareToolsRoot()) {
|
|
38130
|
+
return [toolsRoot, join17(toolsRoot, "bin")];
|
|
38131
|
+
}
|
|
38132
|
+
function refuseSoftwareRequest(request) {
|
|
38133
|
+
if (!COMMAND_PATTERN.test(request.command)) {
|
|
38134
|
+
return "The command name must be a plain executable name with no path, spaces, or shell characters.";
|
|
38135
|
+
}
|
|
38136
|
+
if (!SOFTWARE_INSTALL_METHODS.includes(request.method)) {
|
|
38137
|
+
return SOFTWARE_INSTALL_REFUSAL;
|
|
38138
|
+
}
|
|
38139
|
+
if (request.method === "npm") {
|
|
38140
|
+
if (!NPM_SPEC_PATTERN.test(request.source)) {
|
|
38141
|
+
return "The npm source must be a package name, optionally with one exact version as name@1.2.3. Ranges, tags, git specs, URLs, and local paths are not installed.";
|
|
38142
|
+
}
|
|
38143
|
+
if (request.sha256 !== void 0) {
|
|
38144
|
+
return "An expected sha256 applies only to downloads; the npm registry names versions, not file digests.";
|
|
38145
|
+
}
|
|
38146
|
+
return null;
|
|
38147
|
+
}
|
|
38148
|
+
let url3;
|
|
38149
|
+
try {
|
|
38150
|
+
url3 = new URL(request.source);
|
|
38151
|
+
} catch {
|
|
38152
|
+
return "The download source must be an absolute HTTPS URL.";
|
|
38153
|
+
}
|
|
38154
|
+
if (url3.protocol !== "https:") return "The download source must use HTTPS.";
|
|
38155
|
+
if (url3.username || url3.password) {
|
|
38156
|
+
return "The download source must not carry credentials in the URL.";
|
|
38157
|
+
}
|
|
38158
|
+
if (request.sha256 !== void 0 && !/^[a-f0-9]{64}$/i.test(request.sha256)) {
|
|
38159
|
+
return "The expected sha256 must be 64 hexadecimal characters.";
|
|
38160
|
+
}
|
|
38161
|
+
return null;
|
|
38162
|
+
}
|
|
38163
|
+
async function runProcess(plan, label) {
|
|
38164
|
+
const env = sanitizedInstallerEnv(process.env);
|
|
38165
|
+
await new Promise((resolveRun, rejectRun) => {
|
|
38166
|
+
const child = plan.shellLine !== void 0 ? spawn9(plan.shellLine, {
|
|
38167
|
+
...plan.cwd ? { cwd: plan.cwd } : {},
|
|
38168
|
+
env,
|
|
38169
|
+
// stdin stays closed; output reaches the ordinary worker console, so
|
|
38170
|
+
// progress and failure land on the Host console like a runner install.
|
|
38171
|
+
stdio: ["ignore", "inherit", "inherit"],
|
|
38172
|
+
windowsHide: true,
|
|
38173
|
+
shell: true
|
|
38174
|
+
}) : spawn9(plan.command, plan.args, {
|
|
38175
|
+
...plan.cwd ? { cwd: plan.cwd } : {},
|
|
38176
|
+
env,
|
|
38177
|
+
stdio: ["ignore", "inherit", "inherit"],
|
|
38178
|
+
windowsHide: true
|
|
38179
|
+
});
|
|
38180
|
+
let settled = false;
|
|
38181
|
+
const finish = (error52) => {
|
|
38182
|
+
if (settled) return;
|
|
38183
|
+
settled = true;
|
|
38184
|
+
clearTimeout(timer);
|
|
38185
|
+
if (error52) rejectRun(error52);
|
|
38186
|
+
else resolveRun();
|
|
38187
|
+
};
|
|
38188
|
+
const timer = setTimeout(() => {
|
|
38189
|
+
child.kill();
|
|
38190
|
+
finish(new Error(`${label} did not finish within 10 minutes`));
|
|
38191
|
+
}, PROCESS_TIMEOUT_MS);
|
|
38192
|
+
timer.unref?.();
|
|
38193
|
+
child.once("error", (error52) => finish(error52));
|
|
38194
|
+
child.once("exit", (code, signal) => {
|
|
38195
|
+
if (code === 0) finish();
|
|
38196
|
+
else if (signal) finish(new Error(`${label} stopped with ${signal}`));
|
|
38197
|
+
else finish(new Error(`${label} exited with code ${code ?? "unknown"}`));
|
|
38198
|
+
});
|
|
38199
|
+
});
|
|
38200
|
+
}
|
|
38201
|
+
async function resolveTarCommand(platform) {
|
|
38202
|
+
if (platform !== "win32") return "tar";
|
|
38203
|
+
const root = process.env["SYSTEMROOT"] ?? process.env["WINDIR"];
|
|
38204
|
+
if (!root) return "tar";
|
|
38205
|
+
return await resolveTrustedCliCommand(join17(root, "System32", "tar.exe"), { platform }) ?? "tar";
|
|
38206
|
+
}
|
|
38207
|
+
function archiveKindFor(url3) {
|
|
38208
|
+
let path;
|
|
38209
|
+
try {
|
|
38210
|
+
path = new URL(url3).pathname.toLowerCase();
|
|
38211
|
+
} catch {
|
|
38212
|
+
return "binary";
|
|
38213
|
+
}
|
|
38214
|
+
if (/\.(?:tar\.(?:gz|xz|bz2)|tgz|tbz2|txz|tar)$/.test(path)) return "tar";
|
|
38215
|
+
if (path.endsWith(".zip")) return "zip";
|
|
38216
|
+
return "binary";
|
|
38217
|
+
}
|
|
38218
|
+
async function findExtractedExecutable(root, command, platform = process.platform) {
|
|
38219
|
+
const names = platform === "win32" ? [`${command}.exe`, `${command}.cmd`, `${command}.bat`, command] : [command];
|
|
38220
|
+
let frontier = [root];
|
|
38221
|
+
for (let depth = 0; depth <= MAX_ARCHIVE_SEARCH_DEPTH && frontier.length > 0; depth += 1) {
|
|
38222
|
+
const next = [];
|
|
38223
|
+
for (const directory of frontier) {
|
|
38224
|
+
let entries;
|
|
38225
|
+
try {
|
|
38226
|
+
entries = await readdir5(directory, { withFileTypes: true });
|
|
38227
|
+
} catch {
|
|
38228
|
+
continue;
|
|
38229
|
+
}
|
|
38230
|
+
for (const name of names) {
|
|
38231
|
+
if (entries.some((entry) => entry.name === name && entry.isFile())) {
|
|
38232
|
+
return join17(directory, name);
|
|
38233
|
+
}
|
|
38234
|
+
}
|
|
38235
|
+
for (const entry of entries) {
|
|
38236
|
+
if (entry.isDirectory()) next.push(join17(directory, entry.name));
|
|
38237
|
+
}
|
|
38238
|
+
}
|
|
38239
|
+
frontier = next;
|
|
38240
|
+
}
|
|
38241
|
+
return null;
|
|
38242
|
+
}
|
|
38243
|
+
function withinRoot(root, candidate) {
|
|
38244
|
+
const base = resolvePath(root);
|
|
38245
|
+
const target = resolvePath(candidate);
|
|
38246
|
+
return target === base || target.startsWith(base.endsWith(sep5) ? base : `${base}${sep5}`);
|
|
38247
|
+
}
|
|
38248
|
+
function downloadedBinaryName(command, source, platform = process.platform) {
|
|
38249
|
+
if (platform !== "win32") return command;
|
|
38250
|
+
const extension = /(\.[A-Za-z0-9]{1,8})$/.exec(new URL(source).pathname)?.[1]?.toLowerCase();
|
|
38251
|
+
if (extension !== ".exe" && extension !== ".com") {
|
|
38252
|
+
throw new Error(
|
|
38253
|
+
"a direct Windows download must be a .exe or .com file; use the tool\u2019s .zip release instead"
|
|
38254
|
+
);
|
|
38255
|
+
}
|
|
38256
|
+
return `${command}${extension}`;
|
|
38257
|
+
}
|
|
38258
|
+
async function placeDownloadedPayload(body, request, options) {
|
|
38259
|
+
const platform = options.platform ?? process.platform;
|
|
38260
|
+
const { toolsRoot } = options;
|
|
38261
|
+
const staging = join17(toolsRoot, ".staging", randomUUID11());
|
|
38262
|
+
const stagedPackage = join17(staging, "pkg");
|
|
38263
|
+
const packageRoot = join17(toolsRoot, "pkgs", request.command);
|
|
38264
|
+
const binDirectory = platform === "win32" ? toolsRoot : join17(toolsRoot, "bin");
|
|
38265
|
+
const kind = archiveKindFor(request.source);
|
|
38266
|
+
await mkdir11(stagedPackage, { recursive: true, mode: 448 });
|
|
38267
|
+
try {
|
|
38268
|
+
if (kind === "binary") {
|
|
38269
|
+
await writeFile7(
|
|
38270
|
+
join17(stagedPackage, downloadedBinaryName(request.command, request.source, platform)),
|
|
38271
|
+
body,
|
|
38272
|
+
{
|
|
38273
|
+
mode: 448
|
|
38274
|
+
}
|
|
38275
|
+
);
|
|
38276
|
+
} else {
|
|
38277
|
+
await writeFile7(join17(staging, "archive"), body, { mode: 448 });
|
|
38278
|
+
if (kind === "tar" || platform !== "linux") {
|
|
38279
|
+
await runProcess(
|
|
38280
|
+
{
|
|
38281
|
+
command: await resolveTarCommand(platform),
|
|
38282
|
+
args: ["-xf", "archive", "-C", "pkg"],
|
|
38283
|
+
cwd: staging
|
|
38284
|
+
},
|
|
38285
|
+
"the archive extraction"
|
|
38286
|
+
);
|
|
38287
|
+
} else {
|
|
38288
|
+
await runProcess(
|
|
38289
|
+
{ command: "unzip", args: ["-q", "-o", "archive", "-d", "pkg"], cwd: staging },
|
|
38290
|
+
"the archive extraction"
|
|
38291
|
+
);
|
|
38292
|
+
}
|
|
38293
|
+
await rm10(join17(staging, "archive"), { force: true }).catch(() => void 0);
|
|
38294
|
+
}
|
|
38295
|
+
const stagedExecutable = await findExtractedExecutable(
|
|
38296
|
+
stagedPackage,
|
|
38297
|
+
request.command,
|
|
38298
|
+
platform
|
|
38299
|
+
);
|
|
38300
|
+
if (!stagedExecutable) {
|
|
38301
|
+
throw new Error(`the download did not contain an executable named ${request.command}`);
|
|
38302
|
+
}
|
|
38303
|
+
if (!withinRoot(stagedPackage, stagedExecutable)) {
|
|
38304
|
+
throw new Error("the archive tried to place its executable outside the Zixt folder");
|
|
38305
|
+
}
|
|
38306
|
+
await mkdir11(join17(toolsRoot, "pkgs"), { recursive: true, mode: 448 });
|
|
38307
|
+
await rm10(packageRoot, { recursive: true, force: true });
|
|
38308
|
+
await rename6(stagedPackage, packageRoot);
|
|
38309
|
+
const executable = join17(packageRoot, relative8(stagedPackage, stagedExecutable));
|
|
38310
|
+
await mkdir11(binDirectory, { recursive: true, mode: 448 });
|
|
38311
|
+
if (platform === "win32") {
|
|
38312
|
+
const shim = join17(binDirectory, `${request.command}.cmd`);
|
|
38313
|
+
await writeFile7(shim, `@echo off\r
|
|
38314
|
+
${quoteForCmd(executable)} %*\r
|
|
38315
|
+
`, {
|
|
38316
|
+
encoding: "utf8",
|
|
38317
|
+
mode: 448
|
|
38318
|
+
});
|
|
38319
|
+
return shim;
|
|
38320
|
+
}
|
|
38321
|
+
await chmod6(executable, 493);
|
|
38322
|
+
const link = join17(binDirectory, request.command);
|
|
38323
|
+
await rm10(link, { force: true });
|
|
38324
|
+
await symlink2(executable, link);
|
|
38325
|
+
return link;
|
|
38326
|
+
} finally {
|
|
38327
|
+
await rm10(staging, { recursive: true, force: true }).catch(() => void 0);
|
|
38328
|
+
}
|
|
38329
|
+
}
|
|
38330
|
+
function createSoftwareInstaller(options = {}) {
|
|
38331
|
+
const platform = options.platform ?? process.platform;
|
|
38332
|
+
const toolsRoot = options.toolsRoot ?? defaultSoftwareToolsRoot();
|
|
38333
|
+
const now = options.now ?? Date.now;
|
|
38334
|
+
const manifestPath = join17(toolsRoot, MANIFEST_NAME);
|
|
38335
|
+
const inFlight = /* @__PURE__ */ new Map();
|
|
38336
|
+
const failures = /* @__PURE__ */ new Map();
|
|
38337
|
+
const searchPath = () => {
|
|
38338
|
+
const inherited = options.resolution?.searchPath ?? process.env.PATH ?? "";
|
|
38339
|
+
const separator = platform === "win32" ? ";" : ":";
|
|
38340
|
+
return [inherited, ...softwareSearchPathEntries(toolsRoot)].filter(Boolean).join(separator);
|
|
38341
|
+
};
|
|
38342
|
+
const resolveCommand = async (command) => resolveTrustedCliCommand(command, {
|
|
38343
|
+
...options.resolution ?? {},
|
|
38344
|
+
platform,
|
|
38345
|
+
searchPath: searchPath()
|
|
38346
|
+
});
|
|
38347
|
+
const readManifest = async () => {
|
|
38348
|
+
try {
|
|
38349
|
+
const parsed = JSON.parse(await readFile10(manifestPath, "utf8"));
|
|
38350
|
+
return Array.isArray(parsed) ? parsed : [];
|
|
38351
|
+
} catch {
|
|
38352
|
+
return [];
|
|
38353
|
+
}
|
|
38354
|
+
};
|
|
38355
|
+
let manifestTurn = Promise.resolve();
|
|
38356
|
+
const recordInstall = (record2) => {
|
|
38357
|
+
const write = manifestTurn.then(async () => {
|
|
38358
|
+
const existing = (await readManifest()).filter((entry) => entry.command !== record2.command);
|
|
38359
|
+
const staged = `${manifestPath}.${randomUUID11()}`;
|
|
38360
|
+
await writeFile7(staged, `${JSON.stringify([...existing, record2], null, 2)}
|
|
38361
|
+
`, {
|
|
38362
|
+
encoding: "utf8",
|
|
38363
|
+
mode: 384
|
|
38364
|
+
});
|
|
38365
|
+
await rename6(staged, manifestPath);
|
|
38366
|
+
});
|
|
38367
|
+
manifestTurn = write.catch(() => void 0);
|
|
38368
|
+
return write;
|
|
38369
|
+
};
|
|
38370
|
+
const installFromNpm = async (request) => {
|
|
38371
|
+
await mkdir11(toolsRoot, { recursive: true, mode: 448 });
|
|
38372
|
+
const npm = await resolveInstallerCommand({ platform });
|
|
38373
|
+
const args = [
|
|
38374
|
+
"install",
|
|
38375
|
+
"-g",
|
|
38376
|
+
"--prefix",
|
|
38377
|
+
toolsRoot,
|
|
38378
|
+
"--no-audit",
|
|
38379
|
+
"--no-fund",
|
|
38380
|
+
"--ignore-scripts",
|
|
38381
|
+
// `--` ends npm's flag parsing, so even a spec that slipped the pattern
|
|
38382
|
+
// could not become an npm option.
|
|
38383
|
+
"--",
|
|
38384
|
+
request.source
|
|
38385
|
+
];
|
|
38386
|
+
if (platform === "win32") {
|
|
38387
|
+
await runProcess(
|
|
38388
|
+
{ shellLine: windowsInstallerCommandLine(npm, args), cwd: toolsRoot },
|
|
38389
|
+
"the npm install"
|
|
38390
|
+
);
|
|
38391
|
+
} else {
|
|
38392
|
+
await runProcess({ command: npm, args, cwd: toolsRoot }, "the npm install");
|
|
38393
|
+
}
|
|
38394
|
+
};
|
|
38395
|
+
const installFromDownload = async (request) => {
|
|
38396
|
+
const response = await fetch(request.source, {
|
|
38397
|
+
redirect: "follow",
|
|
38398
|
+
signal: AbortSignal.timeout(DOWNLOAD_TIMEOUT_MS)
|
|
38399
|
+
});
|
|
38400
|
+
if (!response.ok) throw new Error(`the download answered HTTP ${response.status}`);
|
|
38401
|
+
if (response.url && !response.url.startsWith("https:")) {
|
|
38402
|
+
throw new Error("the download redirected off HTTPS and was not installed");
|
|
38403
|
+
}
|
|
38404
|
+
const declared = Number(response.headers.get("content-length") ?? "0");
|
|
38405
|
+
if (Number.isFinite(declared) && declared > MAX_DOWNLOAD_BYTES) {
|
|
38406
|
+
throw new Error("the download is larger than Zixt installs unattended");
|
|
38407
|
+
}
|
|
38408
|
+
if (!response.body) throw new Error("the download had no body");
|
|
38409
|
+
const reader = response.body.getReader();
|
|
38410
|
+
const chunks = [];
|
|
38411
|
+
let total = 0;
|
|
38412
|
+
for (; ; ) {
|
|
38413
|
+
const { done, value } = await reader.read();
|
|
38414
|
+
if (done) break;
|
|
38415
|
+
total += value.byteLength;
|
|
38416
|
+
if (total > MAX_DOWNLOAD_BYTES) {
|
|
38417
|
+
await reader.cancel().catch(() => void 0);
|
|
38418
|
+
throw new Error("the download is larger than Zixt installs unattended");
|
|
38419
|
+
}
|
|
38420
|
+
chunks.push(Buffer.from(value));
|
|
38421
|
+
}
|
|
38422
|
+
const body = Buffer.concat(chunks);
|
|
38423
|
+
if (body.length === 0) throw new Error("the download was empty");
|
|
38424
|
+
const digest = createHash6("sha256").update(body).digest("hex");
|
|
38425
|
+
if (request.sha256 && digest !== request.sha256.toLowerCase()) {
|
|
38426
|
+
throw new Error("the download did not match the expected sha256");
|
|
38427
|
+
}
|
|
38428
|
+
await placeDownloadedPayload(body, request, { toolsRoot, platform });
|
|
38429
|
+
};
|
|
38430
|
+
const perform = options.perform ?? (async (request) => {
|
|
38431
|
+
if (request.method === "npm") await installFromNpm(request);
|
|
38432
|
+
else await installFromDownload(request);
|
|
38433
|
+
const resolved = await resolveCommand(request.command);
|
|
38434
|
+
if (!resolved) {
|
|
38435
|
+
throw new Error(
|
|
38436
|
+
`the install finished but ${request.command} is still not runnable on this Machine`
|
|
38437
|
+
);
|
|
38438
|
+
}
|
|
38439
|
+
return resolved;
|
|
38440
|
+
});
|
|
38441
|
+
const attempt = async (request) => {
|
|
38442
|
+
options.onEvent?.({ command: request.command, state: "started" });
|
|
38443
|
+
try {
|
|
38444
|
+
const path = await perform(request, toolsRoot);
|
|
38445
|
+
if (!withinRoot(toolsRoot, path)) {
|
|
38446
|
+
throw new Error(
|
|
38447
|
+
`${request.command} resolves outside the Zixt folder and was not installed by Zixt`
|
|
38448
|
+
);
|
|
38449
|
+
}
|
|
38450
|
+
const record2 = {
|
|
38451
|
+
command: request.command,
|
|
38452
|
+
method: request.method,
|
|
38453
|
+
source: request.source,
|
|
38454
|
+
path,
|
|
38455
|
+
sha256: request.sha256 ? request.sha256.toLowerCase() : null,
|
|
38456
|
+
installedAt: new Date(now()).toISOString()
|
|
38457
|
+
};
|
|
38458
|
+
await recordInstall(record2).catch(() => void 0);
|
|
38459
|
+
options.onEvent?.({ command: request.command, state: "completed" });
|
|
38460
|
+
return { ok: true, record: record2 };
|
|
38461
|
+
} catch (error52) {
|
|
38462
|
+
const message = error52 instanceof Error ? error52.message : "unknown software install error";
|
|
38463
|
+
options.onEvent?.({ command: request.command, state: "failed", error: message });
|
|
38464
|
+
return { ok: false, error: message };
|
|
38465
|
+
}
|
|
38466
|
+
};
|
|
38467
|
+
return {
|
|
38468
|
+
toolsRoot,
|
|
38469
|
+
async probe(command) {
|
|
38470
|
+
if (!COMMAND_PATTERN.test(command)) {
|
|
38471
|
+
return { command, present: false, path: null, managed: false };
|
|
38472
|
+
}
|
|
38473
|
+
const path = await resolveCommand(command);
|
|
38474
|
+
return {
|
|
38475
|
+
command,
|
|
38476
|
+
present: path !== null,
|
|
38477
|
+
path,
|
|
38478
|
+
managed: path !== null && withinRoot(toolsRoot, path)
|
|
38479
|
+
};
|
|
38480
|
+
},
|
|
38481
|
+
async install(request) {
|
|
38482
|
+
const refusal = refuseSoftwareRequest(request);
|
|
38483
|
+
if (refusal) return { ok: false, error: refusal };
|
|
38484
|
+
const key = [
|
|
38485
|
+
request.command,
|
|
38486
|
+
request.method,
|
|
38487
|
+
request.source,
|
|
38488
|
+
request.sha256?.toLowerCase() ?? ""
|
|
38489
|
+
].join("\n");
|
|
38490
|
+
const running = inFlight.get(key);
|
|
38491
|
+
if (running) return running;
|
|
38492
|
+
const failure2 = failures.get(key);
|
|
38493
|
+
if (failure2 && now() - failure2.at < FAILURE_COOLDOWN_MS2) {
|
|
38494
|
+
return {
|
|
38495
|
+
ok: false,
|
|
38496
|
+
error: `This exact install already failed on this Machine: ${failure2.error}. Do not repeat it. Finish the work another way, or tell the person what is missing and the command they would run.`
|
|
38497
|
+
};
|
|
38498
|
+
}
|
|
38499
|
+
const started = (async () => {
|
|
38500
|
+
const result = await attempt(request);
|
|
38501
|
+
if (result.ok) failures.delete(key);
|
|
38502
|
+
else failures.set(key, { at: now(), error: result.error });
|
|
38503
|
+
return result;
|
|
38504
|
+
})();
|
|
38505
|
+
inFlight.set(key, started);
|
|
38506
|
+
try {
|
|
38507
|
+
return await started;
|
|
38508
|
+
} finally {
|
|
38509
|
+
inFlight.delete(key);
|
|
38510
|
+
}
|
|
38511
|
+
},
|
|
38512
|
+
async installed() {
|
|
38513
|
+
return readManifest();
|
|
38514
|
+
}
|
|
38515
|
+
};
|
|
38516
|
+
}
|
|
38517
|
+
|
|
38518
|
+
// src/runners/ask-user-server.ts
|
|
38009
38519
|
var CADENCE_PROPS = {
|
|
38010
38520
|
cadence_kind: {
|
|
38011
38521
|
type: "string",
|
|
@@ -38121,6 +38631,55 @@ var TOOLS = [
|
|
|
38121
38631
|
additionalProperties: false
|
|
38122
38632
|
}
|
|
38123
38633
|
},
|
|
38634
|
+
{
|
|
38635
|
+
name: "check_software",
|
|
38636
|
+
description: "Check whether a command is already available on this Machine before assuming it is missing. Returns whether it is present, where it resolved, and whether Zixt is the one that installed it.",
|
|
38637
|
+
inputSchema: {
|
|
38638
|
+
type: "object",
|
|
38639
|
+
properties: {
|
|
38640
|
+
command: {
|
|
38641
|
+
type: "string",
|
|
38642
|
+
description: "The plain command name, for example ffmpeg or gh. No path, no arguments."
|
|
38643
|
+
}
|
|
38644
|
+
},
|
|
38645
|
+
required: ["command"],
|
|
38646
|
+
additionalProperties: false
|
|
38647
|
+
}
|
|
38648
|
+
},
|
|
38649
|
+
{
|
|
38650
|
+
name: "install_software",
|
|
38651
|
+
description: "Install a command this Machine is missing, into the folder Zixt owns, after the person approves it. Prefer not to call this. Installing software on someone else\u2019s computer is friction, so first try to finish the work with what the Machine already has: a different tool, a project dependency, or another approach. Call it only when the missing command genuinely blocks the work or is clearly the right way to do it, and never speculatively. Zixt can install an npm package, or download and unpack a release from an HTTPS URL. It cannot use a system package manager such as apt, brew, winget, or choco, cannot ask for elevation or sudo, and cannot build from source. When the tool needs any of those, or the install looks complicated, do not call this: tell the person what is missing, why this work needs it, and the exact command they would run on their operating system. The person sees your reason and the exact source before anything runs, and may say no.",
|
|
38652
|
+
inputSchema: {
|
|
38653
|
+
type: "object",
|
|
38654
|
+
properties: {
|
|
38655
|
+
command: {
|
|
38656
|
+
type: "string",
|
|
38657
|
+
description: "The plain command name the work needs on PATH, for example ffmpeg."
|
|
38658
|
+
},
|
|
38659
|
+
reason: {
|
|
38660
|
+
type: "string",
|
|
38661
|
+
minLength: 1,
|
|
38662
|
+
maxLength: 500,
|
|
38663
|
+
description: "Why this work needs it, in one plain sentence. The person reads this before deciding."
|
|
38664
|
+
},
|
|
38665
|
+
method: {
|
|
38666
|
+
type: "string",
|
|
38667
|
+
enum: [...SOFTWARE_INSTALL_METHODS],
|
|
38668
|
+
description: "npm for an npm package; download for a release archive or binary."
|
|
38669
|
+
},
|
|
38670
|
+
source: {
|
|
38671
|
+
type: "string",
|
|
38672
|
+
description: "npm: the package name, optionally name@version with an exact version. download: the HTTPS URL of the release archive or binary."
|
|
38673
|
+
},
|
|
38674
|
+
sha256: {
|
|
38675
|
+
type: "string",
|
|
38676
|
+
description: "download only: the published SHA-256 of that file, when the project publishes one. Include it whenever you can."
|
|
38677
|
+
}
|
|
38678
|
+
},
|
|
38679
|
+
required: ["command", "reason", "method", "source"],
|
|
38680
|
+
additionalProperties: false
|
|
38681
|
+
}
|
|
38682
|
+
},
|
|
38124
38683
|
{
|
|
38125
38684
|
name: "publish_file",
|
|
38126
38685
|
description: "Snapshot a file you created in this Task workspace into Zixt so the user can download it. This only creates the Zixt file; it does not send it anywhere externally. The result returns an artifact_id.",
|
|
@@ -38906,6 +39465,57 @@ function createAskUserServer() {
|
|
|
38906
39465
|
}
|
|
38907
39466
|
return;
|
|
38908
39467
|
}
|
|
39468
|
+
if (surface.platform && (name === "check_software" || name === "install_software")) {
|
|
39469
|
+
if (!handlers.software) {
|
|
39470
|
+
toolText("Software checks are unavailable for this runner.", true);
|
|
39471
|
+
return;
|
|
39472
|
+
}
|
|
39473
|
+
const command = typeof args["command"] === "string" ? args["command"].trim() : "";
|
|
39474
|
+
if (!command) {
|
|
39475
|
+
toolText("missing required argument `command`", true);
|
|
39476
|
+
return;
|
|
39477
|
+
}
|
|
39478
|
+
try {
|
|
39479
|
+
if (name === "check_software") {
|
|
39480
|
+
toolText(JSON.stringify(await handlers.software.check(command), null, 2));
|
|
39481
|
+
return;
|
|
39482
|
+
}
|
|
39483
|
+
const reason = typeof args["reason"] === "string" ? args["reason"].trim() : "";
|
|
39484
|
+
const method = typeof args["method"] === "string" ? args["method"] : "";
|
|
39485
|
+
const source = typeof args["source"] === "string" ? args["source"].trim() : "";
|
|
39486
|
+
const sha256 = typeof args["sha256"] === "string" && args["sha256"] ? args["sha256"] : void 0;
|
|
39487
|
+
if (!reason) {
|
|
39488
|
+
toolText(
|
|
39489
|
+
"missing required argument `reason`: the person decides by reading why this work needs it",
|
|
39490
|
+
true
|
|
39491
|
+
);
|
|
39492
|
+
return;
|
|
39493
|
+
}
|
|
39494
|
+
if (!SOFTWARE_INSTALL_METHODS.includes(method)) {
|
|
39495
|
+
toolText(`\`method\` must be one of ${SOFTWARE_INSTALL_METHODS.join(", ")}.`, true);
|
|
39496
|
+
return;
|
|
39497
|
+
}
|
|
39498
|
+
const request = {
|
|
39499
|
+
command,
|
|
39500
|
+
method,
|
|
39501
|
+
source,
|
|
39502
|
+
sha256
|
|
39503
|
+
};
|
|
39504
|
+
const refusal = refuseSoftwareRequest(request);
|
|
39505
|
+
if (refusal) {
|
|
39506
|
+
toolText(refusal, true);
|
|
39507
|
+
return;
|
|
39508
|
+
}
|
|
39509
|
+
const outcome = await handlers.software.install({ ...request, reason });
|
|
39510
|
+
toolText(outcome.detail, !outcome.ok);
|
|
39511
|
+
} catch (err) {
|
|
39512
|
+
toolText(
|
|
39513
|
+
`The software request could not be completed: ${String(err instanceof Error ? err.message : err)}`,
|
|
39514
|
+
true
|
|
39515
|
+
);
|
|
39516
|
+
}
|
|
39517
|
+
return;
|
|
39518
|
+
}
|
|
38909
39519
|
if (surface.platform && name === "publish_file") {
|
|
38910
39520
|
if (!handlers.publishFile) {
|
|
38911
39521
|
toolText("file publishing is unavailable for this runner", true);
|
|
@@ -39021,6 +39631,7 @@ function createAskUserServer() {
|
|
|
39021
39631
|
agentOp: input.agentOp,
|
|
39022
39632
|
..."requestApproval" in input && input.requestApproval ? { requestApproval: input.requestApproval } : {},
|
|
39023
39633
|
..."publishFile" in input && input.publishFile ? { publishFile: input.publishFile } : {},
|
|
39634
|
+
..."software" in input && input.software ? { software: input.software } : {},
|
|
39024
39635
|
...toolPacks.length > 0 ? { toolPacks } : {}
|
|
39025
39636
|
};
|
|
39026
39637
|
const toolOwners = /* @__PURE__ */ new Map();
|
|
@@ -39173,7 +39784,10 @@ function buildRunnerEnv(input) {
|
|
|
39173
39784
|
env[name] = value;
|
|
39174
39785
|
}
|
|
39175
39786
|
}
|
|
39176
|
-
const searchPath =
|
|
39787
|
+
const searchPath = [
|
|
39788
|
+
sanitizeInheritedSearchPath(inheritedValue(input.inherited, "PATH")),
|
|
39789
|
+
...(input.softwareToolsPath ?? []).filter((entry) => isAbsolute14(entry))
|
|
39790
|
+
].filter((entry) => entry !== "").join(delimiter2);
|
|
39177
39791
|
const gitConfig = input.githubShell ? [
|
|
39178
39792
|
["credential.helper", ""],
|
|
39179
39793
|
["credential.helper", input.githubShell.gitCredentialHelper],
|
|
@@ -39240,9 +39854,9 @@ function buildRunnerEnv(input) {
|
|
|
39240
39854
|
// src/runners/github-shell-auth.ts
|
|
39241
39855
|
import { execFile } from "node:child_process";
|
|
39242
39856
|
import { randomBytes as randomBytes2, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
|
|
39243
|
-
import { chmod as
|
|
39857
|
+
import { chmod as chmod7, lstat as lstat10, mkdir as mkdir12, realpath as realpath7, writeFile as writeFile8 } from "node:fs/promises";
|
|
39244
39858
|
import { createServer as createServer3 } from "node:http";
|
|
39245
|
-
import { isAbsolute as isAbsolute15, join as
|
|
39859
|
+
import { isAbsolute as isAbsolute15, join as join18, relative as relative9 } from "node:path";
|
|
39246
39860
|
var MAX_REQUEST_BYTES2 = 16 * 1024;
|
|
39247
39861
|
var DIRECTORY_MODE4 = 448;
|
|
39248
39862
|
var PRIVATE_FILE_MODE = 384;
|
|
@@ -39606,7 +40220,7 @@ function activationCredential(grant, now = Date.now()) {
|
|
|
39606
40220
|
return expiresAt.getTime() <= now ? null : { accessToken: grant.accessToken, expiresAt };
|
|
39607
40221
|
}
|
|
39608
40222
|
function assertChildPath2(parent, child) {
|
|
39609
|
-
const path =
|
|
40223
|
+
const path = relative9(parent, child);
|
|
39610
40224
|
if (!path || path === ".." || path.startsWith("../") || path.startsWith("..\\") || isAbsolute15(path)) {
|
|
39611
40225
|
throw new Error("GitHub shell helper path escaped its private run directory");
|
|
39612
40226
|
}
|
|
@@ -39618,11 +40232,11 @@ function quoteForPosixShell(value) {
|
|
|
39618
40232
|
return quoteForGitShell2(value);
|
|
39619
40233
|
}
|
|
39620
40234
|
async function writePrivate(path, content, executable = false) {
|
|
39621
|
-
await
|
|
40235
|
+
await writeFile8(path, content, {
|
|
39622
40236
|
flag: "wx",
|
|
39623
40237
|
mode: executable ? EXECUTABLE_FILE_MODE : PRIVATE_FILE_MODE
|
|
39624
40238
|
});
|
|
39625
|
-
await
|
|
40239
|
+
await chmod7(path, executable ? EXECUTABLE_FILE_MODE : PRIVATE_FILE_MODE);
|
|
39626
40240
|
}
|
|
39627
40241
|
async function prepareHelpers(input) {
|
|
39628
40242
|
const rootEntry = await lstat10(input.runRoot);
|
|
@@ -39630,7 +40244,7 @@ async function prepareHelpers(input) {
|
|
|
39630
40244
|
throw new Error("GitHub shell authentication requires a private real run directory");
|
|
39631
40245
|
}
|
|
39632
40246
|
const runRoot = await realpath7(input.runRoot);
|
|
39633
|
-
const helperPath =
|
|
40247
|
+
const helperPath = join18(runRoot, "github-shell-git-credential.cjs");
|
|
39634
40248
|
assertChildPath2(runRoot, helperPath);
|
|
39635
40249
|
await writePrivate(helperPath, GIT_HELPER_SOURCE);
|
|
39636
40250
|
if (!input.ghExecutablePath) {
|
|
@@ -39641,14 +40255,14 @@ async function prepareHelpers(input) {
|
|
|
39641
40255
|
wrapperSourcePath: null
|
|
39642
40256
|
};
|
|
39643
40257
|
}
|
|
39644
|
-
const shellToolsDirectory =
|
|
40258
|
+
const shellToolsDirectory = join18(runRoot, "shell-tools");
|
|
39645
40259
|
assertChildPath2(runRoot, shellToolsDirectory);
|
|
39646
|
-
await
|
|
39647
|
-
await
|
|
39648
|
-
const wrapperSourcePath =
|
|
40260
|
+
await mkdir12(shellToolsDirectory, { mode: DIRECTORY_MODE4 });
|
|
40261
|
+
await chmod7(shellToolsDirectory, DIRECTORY_MODE4);
|
|
40262
|
+
const wrapperSourcePath = join18(runRoot, "github-shell-gh-wrapper.cjs");
|
|
39649
40263
|
assertChildPath2(runRoot, wrapperSourcePath);
|
|
39650
40264
|
await writePrivate(wrapperSourcePath, GH_WRAPPER_SOURCE);
|
|
39651
|
-
const wrapperPath =
|
|
40265
|
+
const wrapperPath = join18(shellToolsDirectory, process.platform === "win32" ? "gh.cmd" : "gh");
|
|
39652
40266
|
assertChildPath2(runRoot, wrapperPath);
|
|
39653
40267
|
const launcher = process.platform === "win32" ? `@"${process.execPath.replaceAll('"', '""')}" "${wrapperSourcePath.replaceAll('"', '""')}" %*\r
|
|
39654
40268
|
` : `#!/bin/sh
|
|
@@ -39871,7 +40485,7 @@ password=${credential.accessToken}
|
|
|
39871
40485
|
}
|
|
39872
40486
|
|
|
39873
40487
|
// src/runners/working-context.ts
|
|
39874
|
-
import { spawn as
|
|
40488
|
+
import { spawn as spawn10 } from "node:child_process";
|
|
39875
40489
|
import { resolve as resolve9 } from "node:path";
|
|
39876
40490
|
var COMMAND_TIMEOUT_MS = 5e3;
|
|
39877
40491
|
var OUTPUT_LIMIT_BYTES = 128 * 1024;
|
|
@@ -40002,7 +40616,7 @@ async function stopWorkingContextCommand(child, childExited, options = {}) {
|
|
|
40002
40616
|
function run(command, args, cwd, env, signal) {
|
|
40003
40617
|
if (signal?.aborted) return Promise.resolve(null);
|
|
40004
40618
|
return new Promise((resolvePromise) => {
|
|
40005
|
-
const child =
|
|
40619
|
+
const child = spawn10(command, [...args], {
|
|
40006
40620
|
cwd,
|
|
40007
40621
|
env: { ...env, GIT_OPTIONAL_LOCKS: "0" },
|
|
40008
40622
|
detached: process.platform !== "win32",
|
|
@@ -40420,6 +41034,7 @@ var WorkingContextPullRequestCache = class {
|
|
|
40420
41034
|
};
|
|
40421
41035
|
|
|
40422
41036
|
// src/runners/cli-runner.ts
|
|
41037
|
+
var softwareInstaller = createSoftwareInstaller();
|
|
40423
41038
|
var PRIVATE_CLEANUP_FAILURE = "Private runner cleanup could not be completed. Restart the Zixt Host before accepting more work.";
|
|
40424
41039
|
var PROCESS_CLEANUP_FAILURE = "Runner process cleanup could not be confirmed. Restart the Zixt Host before accepting more work.";
|
|
40425
41040
|
var PROVIDER_CLEANUP_FAILURE = "Provider tool cleanup could not be completed. Restart the Zixt Host before accepting more work.";
|
|
@@ -40442,7 +41057,7 @@ async function settlesWithin(promise2, timeoutMs) {
|
|
|
40442
41057
|
}
|
|
40443
41058
|
}
|
|
40444
41059
|
function defaultRunnerWorkspaceRoot() {
|
|
40445
|
-
return
|
|
41060
|
+
return join19(homedir7(), ".zixt", "workspaces");
|
|
40446
41061
|
}
|
|
40447
41062
|
function defaultRunnerArtifactRoot() {
|
|
40448
41063
|
return defaultRunArtifactRoot();
|
|
@@ -40491,7 +41106,7 @@ function createCliRunner(adapter, opts = {}) {
|
|
|
40491
41106
|
const prefixArgs = opts.commandPrefixArgs ?? [];
|
|
40492
41107
|
const maxWallTimeMs = opts.maxWallTimeMs;
|
|
40493
41108
|
const workspaceRoot = opts.workspaceRoot ?? defaultRunnerWorkspaceRoot();
|
|
40494
|
-
const artifactRoot = opts.artifactRoot ?? (opts.workspaceRoot === void 0 ? defaultRunnerArtifactRoot() :
|
|
41109
|
+
const artifactRoot = opts.artifactRoot ?? (opts.workspaceRoot === void 0 ? defaultRunnerArtifactRoot() : join19(dirname10(workspaceRoot), "run-artifacts"));
|
|
40495
41110
|
const runRegistryRoot2 = opts.runRegistryRoot ?? defaultRunRegistryRoot();
|
|
40496
41111
|
const createArtifacts = opts.createArtifacts ?? createRunArtifacts;
|
|
40497
41112
|
const toolPackRegistry2 = opts.toolPackRegistry ?? createDefaultToolPackRegistry();
|
|
@@ -40509,7 +41124,7 @@ function createCliRunner(adapter, opts = {}) {
|
|
|
40509
41124
|
};
|
|
40510
41125
|
const askUserServer = createAskUserServer();
|
|
40511
41126
|
const windowsRoot = process.env.SystemRoot ?? process.env.WINDIR;
|
|
40512
|
-
const windowsComspecCandidate = process.platform === "win32" && windowsRoot ?
|
|
41127
|
+
const windowsComspecCandidate = process.platform === "win32" && windowsRoot ? join19(windowsRoot, "System32", "cmd.exe") : void 0;
|
|
40513
41128
|
let safetyFailure;
|
|
40514
41129
|
return async (task) => {
|
|
40515
41130
|
if (safetyFailure) {
|
|
@@ -40549,8 +41164,8 @@ function createCliRunner(adapter, opts = {}) {
|
|
|
40549
41164
|
usage: { inputTokens: 0, outputTokens: 0 }
|
|
40550
41165
|
};
|
|
40551
41166
|
}
|
|
40552
|
-
const taskRoot =
|
|
40553
|
-
await
|
|
41167
|
+
const taskRoot = join19(workspaceRoot, task.agentId);
|
|
41168
|
+
await mkdir13(taskRoot, { recursive: true });
|
|
40554
41169
|
if (task.cancelledNow()) return cancelledBeforeRun();
|
|
40555
41170
|
const configuredWorkspace = task.spec.workspace;
|
|
40556
41171
|
let cwd = taskRoot;
|
|
@@ -40597,7 +41212,7 @@ function createCliRunner(adapter, opts = {}) {
|
|
|
40597
41212
|
summaryEvidence: "host_observed"
|
|
40598
41213
|
};
|
|
40599
41214
|
}
|
|
40600
|
-
const runToken =
|
|
41215
|
+
const runToken = randomUUID12();
|
|
40601
41216
|
const artifacts = await createArtifacts({
|
|
40602
41217
|
root: artifactRoot,
|
|
40603
41218
|
agentId: task.agentId,
|
|
@@ -40653,7 +41268,8 @@ function createCliRunner(adapter, opts = {}) {
|
|
|
40653
41268
|
runner: { type: adapter.type, auth: runner.auth },
|
|
40654
41269
|
gitIdentity: githubCommitIdentity(providerGrants),
|
|
40655
41270
|
isolation: artifacts,
|
|
40656
|
-
githubShell
|
|
41271
|
+
githubShell,
|
|
41272
|
+
softwareToolsPath: softwareSearchPathEntries(softwareInstaller.toolsRoot)
|
|
40657
41273
|
});
|
|
40658
41274
|
toolPacks = await toolPackRegistry2.createInstances(providerGrants, {
|
|
40659
41275
|
taskId: task.taskId,
|
|
@@ -40746,6 +41362,51 @@ function createCliRunner(adapter, opts = {}) {
|
|
|
40746
41362
|
}
|
|
40747
41363
|
},
|
|
40748
41364
|
publishFile,
|
|
41365
|
+
// AG-4a. The person approves in the Task thread through the ordinary
|
|
41366
|
+
// approvals pipeline, so the wall clock pauses while they decide, and
|
|
41367
|
+
// a refusal is an answer the session can act on rather than a failure.
|
|
41368
|
+
software: {
|
|
41369
|
+
check: (command2) => softwareInstaller.probe(command2),
|
|
41370
|
+
install: async ({ reason, ...request }) => {
|
|
41371
|
+
pendingAsks++;
|
|
41372
|
+
let decision;
|
|
41373
|
+
try {
|
|
41374
|
+
decision = await task.requestApproval(
|
|
41375
|
+
"agent.question",
|
|
41376
|
+
`Install ${request.command} on this Machine: ${reason}`.slice(0, 500),
|
|
41377
|
+
JSON.stringify({
|
|
41378
|
+
command: request.command,
|
|
41379
|
+
reason,
|
|
41380
|
+
method: request.method,
|
|
41381
|
+
source: request.source,
|
|
41382
|
+
...request.sha256 ? { sha256: request.sha256 } : {},
|
|
41383
|
+
folder: softwareInstaller.toolsRoot
|
|
41384
|
+
}).slice(0, MAX_APPROVAL_PAYLOAD)
|
|
41385
|
+
);
|
|
41386
|
+
} finally {
|
|
41387
|
+
pendingAsks--;
|
|
41388
|
+
}
|
|
41389
|
+
if (!decision.approved) {
|
|
41390
|
+
return {
|
|
41391
|
+
ok: false,
|
|
41392
|
+
detail: decision.guidance ?? `The person did not approve installing ${request.command}. Do not ask again for this task. Finish the work another way, or explain what is blocked.`
|
|
41393
|
+
};
|
|
41394
|
+
}
|
|
41395
|
+
task.event("status", `Installing ${request.command} on this Machine`, {
|
|
41396
|
+
tool: "install_software"
|
|
41397
|
+
});
|
|
41398
|
+
const result2 = await softwareInstaller.install(request);
|
|
41399
|
+
task.event(
|
|
41400
|
+
"status",
|
|
41401
|
+
result2.ok ? `Installed ${request.command} on this Machine` : `Could not install ${request.command} on this Machine`,
|
|
41402
|
+
{ tool: "install_software" }
|
|
41403
|
+
);
|
|
41404
|
+
return result2.ok ? {
|
|
41405
|
+
ok: true,
|
|
41406
|
+
detail: `${request.command} is installed at ${result2.record.path} and is on your PATH. Continue the work.`
|
|
41407
|
+
} : { ok: false, detail: result2.error };
|
|
41408
|
+
}
|
|
41409
|
+
},
|
|
40749
41410
|
agentOp: (op) => task.agentOp(op),
|
|
40750
41411
|
// GitHub repository work belongs in the installed `git` and `gh`
|
|
40751
41412
|
// commands backed by GithubShellAuth. Do not advertise the bundled
|
|
@@ -40970,8 +41631,8 @@ ${attachmentSection}` : prompt;
|
|
|
40970
41631
|
}
|
|
40971
41632
|
comspec = resolvedWindowsComspec;
|
|
40972
41633
|
}
|
|
40973
|
-
const exitMarker = `__ZIXT_RUNNER_EXIT_${
|
|
40974
|
-
const guardianNonce =
|
|
41634
|
+
const exitMarker = `__ZIXT_RUNNER_EXIT_${randomUUID12()}__`;
|
|
41635
|
+
const guardianNonce = randomUUID12();
|
|
40975
41636
|
return runCliProcess({
|
|
40976
41637
|
command: resolvedCommand,
|
|
40977
41638
|
args,
|
|
@@ -41328,8 +41989,8 @@ function runCliProcess(options) {
|
|
|
41328
41989
|
}
|
|
41329
41990
|
return new Promise((resolve19) => {
|
|
41330
41991
|
const platform = options.platform ?? process.platform;
|
|
41331
|
-
const containmentGateNonce = options.guardian && platform === "win32" ?
|
|
41332
|
-
const child = options.guardian ?
|
|
41992
|
+
const containmentGateNonce = options.guardian && platform === "win32" ? randomUUID12() : void 0;
|
|
41993
|
+
const child = options.guardian ? spawn11(
|
|
41333
41994
|
options.guardian.nodeCommand,
|
|
41334
41995
|
[
|
|
41335
41996
|
options.guardian.scriptPath,
|
|
@@ -41617,12 +42278,12 @@ function runCliProcess(options) {
|
|
|
41617
42278
|
}
|
|
41618
42279
|
|
|
41619
42280
|
// src/runners/claude-code.ts
|
|
41620
|
-
import { randomUUID as
|
|
42281
|
+
import { randomUUID as randomUUID13 } from "node:crypto";
|
|
41621
42282
|
|
|
41622
42283
|
// src/runners/runtime-observation.ts
|
|
41623
|
-
import { open as open6, readdir as
|
|
42284
|
+
import { open as open6, readdir as readdir6, realpath as realpath9 } from "node:fs/promises";
|
|
41624
42285
|
import { homedir as homedir8 } from "node:os";
|
|
41625
|
-
import { join as
|
|
42286
|
+
import { join as join20 } from "node:path";
|
|
41626
42287
|
var READ_WINDOW_BYTES = 1024 * 1024;
|
|
41627
42288
|
var CATALOG_TIMEOUT_MS = 15e3;
|
|
41628
42289
|
var CATALOG_OUTPUT_LIMIT_BYTES = 4 * 1024 * 1024;
|
|
@@ -41682,9 +42343,9 @@ function displayValue(value, maxLength) {
|
|
|
41682
42343
|
return trimmed;
|
|
41683
42344
|
}
|
|
41684
42345
|
function claudeTranscriptPath(input) {
|
|
41685
|
-
const configDir = input.env["CLAUDE_CONFIG_DIR"] ||
|
|
42346
|
+
const configDir = input.env["CLAUDE_CONFIG_DIR"] || join20(homeFrom(input.env), ".claude");
|
|
41686
42347
|
const slug = input.resolvedCwd.replace(/[^a-zA-Z0-9]/g, "-");
|
|
41687
|
-
return
|
|
42348
|
+
return join20(configDir, "projects", slug, `${input.sessionId}.jsonl`);
|
|
41688
42349
|
}
|
|
41689
42350
|
async function readClaudeSessionEffort(input) {
|
|
41690
42351
|
const resolvedCwd = await realpath9(input.cwd).catch(() => input.cwd);
|
|
@@ -41699,19 +42360,19 @@ async function readClaudeSessionEffort(input) {
|
|
|
41699
42360
|
return null;
|
|
41700
42361
|
}
|
|
41701
42362
|
async function newestDirectories(root, limit) {
|
|
41702
|
-
const entries = await
|
|
41703
|
-
return entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort((left, right) => right.localeCompare(left)).slice(0, limit).map((name) =>
|
|
42363
|
+
const entries = await readdir6(root, { withFileTypes: true }).catch(() => []);
|
|
42364
|
+
return entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort((left, right) => right.localeCompare(left)).slice(0, limit).map((name) => join20(root, name));
|
|
41704
42365
|
}
|
|
41705
42366
|
async function findCodexRolloutPath(input) {
|
|
41706
|
-
const codexHome = input.env["CODEX_HOME"] ||
|
|
41707
|
-
const sessions =
|
|
42367
|
+
const codexHome = input.env["CODEX_HOME"] || join20(homeFrom(input.env), ".codex");
|
|
42368
|
+
const sessions = join20(codexHome, "sessions");
|
|
41708
42369
|
const suffix = `-${input.threadId}.jsonl`;
|
|
41709
42370
|
for (const year of await newestDirectories(sessions, 2)) {
|
|
41710
42371
|
for (const month of await newestDirectories(year, 2)) {
|
|
41711
42372
|
for (const day of await newestDirectories(month, 3)) {
|
|
41712
|
-
const files = await
|
|
42373
|
+
const files = await readdir6(day).catch(() => []);
|
|
41713
42374
|
const match = files.find((name) => name.endsWith(suffix));
|
|
41714
|
-
if (match) return
|
|
42375
|
+
if (match) return join20(day, match);
|
|
41715
42376
|
}
|
|
41716
42377
|
}
|
|
41717
42378
|
}
|
|
@@ -41809,7 +42470,7 @@ var claudeCodeAdapter = {
|
|
|
41809
42470
|
input.gitDetected,
|
|
41810
42471
|
liveInput
|
|
41811
42472
|
);
|
|
41812
|
-
const sessionId = input.task.spec.sessionKey ??
|
|
42473
|
+
const sessionId = input.task.spec.sessionKey ?? randomUUID13();
|
|
41813
42474
|
const observeRuntime = createRuntimeReporter(input, sessionId);
|
|
41814
42475
|
return {
|
|
41815
42476
|
argsFor: (mode) => [
|
|
@@ -41938,7 +42599,7 @@ function createClaudeLiveParser(onStream, onSessionModel) {
|
|
|
41938
42599
|
...parser,
|
|
41939
42600
|
async start(writer, prompt) {
|
|
41940
42601
|
write = writer;
|
|
41941
|
-
await writer(input(
|
|
42602
|
+
await writer(input(randomUUID13(), prompt));
|
|
41942
42603
|
},
|
|
41943
42604
|
async steer(followUp) {
|
|
41944
42605
|
if (!write) return false;
|
|
@@ -42105,22 +42766,22 @@ function improveErrorMessage(error52) {
|
|
|
42105
42766
|
}
|
|
42106
42767
|
|
|
42107
42768
|
// src/runners/codex.ts
|
|
42108
|
-
import { mkdir as
|
|
42109
|
-
import { randomUUID as
|
|
42769
|
+
import { mkdir as mkdir14, readFile as readFile11, writeFile as writeFile9 } from "node:fs/promises";
|
|
42770
|
+
import { randomUUID as randomUUID14 } from "node:crypto";
|
|
42110
42771
|
import { homedir as homedir9 } from "node:os";
|
|
42111
|
-
import { join as
|
|
42772
|
+
import { join as join21 } from "node:path";
|
|
42112
42773
|
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.";
|
|
42113
42774
|
function defaultCodexThreadIndexRoot() {
|
|
42114
|
-
return
|
|
42775
|
+
return join21(homedir9(), ".zixt", "codex-threads");
|
|
42115
42776
|
}
|
|
42116
42777
|
var SAFE_SEGMENT3 = /^[A-Za-z0-9_-]{1,200}$/;
|
|
42117
42778
|
function threadIndexPath(root, agentId, sessionKey) {
|
|
42118
42779
|
if (!SAFE_SEGMENT3.test(agentId) || !SAFE_SEGMENT3.test(sessionKey)) return null;
|
|
42119
|
-
return
|
|
42780
|
+
return join21(root, agentId, `${sessionKey}.json`);
|
|
42120
42781
|
}
|
|
42121
42782
|
async function readThreadId(path) {
|
|
42122
42783
|
try {
|
|
42123
|
-
const parsed = JSON.parse(await
|
|
42784
|
+
const parsed = JSON.parse(await readFile11(path, "utf8"));
|
|
42124
42785
|
return typeof parsed.threadId === "string" && /^[A-Za-z0-9-]{1,120}$/.test(parsed.threadId) ? parsed.threadId : null;
|
|
42125
42786
|
} catch {
|
|
42126
42787
|
return null;
|
|
@@ -42220,7 +42881,7 @@ ${value}` : value;
|
|
|
42220
42881
|
const recordedThreadId = indexPath ? await readThreadId(indexPath) : null;
|
|
42221
42882
|
const rememberThread = (threadId) => {
|
|
42222
42883
|
if (!indexPath) return;
|
|
42223
|
-
void
|
|
42884
|
+
void mkdir14(join21(threadIndexRoot, task.agentId), { recursive: true }).then(() => writeFile9(indexPath, JSON.stringify({ threadId }), "utf8")).catch(() => {
|
|
42224
42885
|
});
|
|
42225
42886
|
};
|
|
42226
42887
|
const observeRuntime = (threadId) => {
|
|
@@ -42324,7 +42985,7 @@ function createCodexAppServerParser(onStream, options) {
|
|
|
42324
42985
|
params: {
|
|
42325
42986
|
threadId,
|
|
42326
42987
|
input: [{ type: "text", text: prompt }],
|
|
42327
|
-
clientUserMessageId:
|
|
42988
|
+
clientUserMessageId: randomUUID14(),
|
|
42328
42989
|
...options.model ? { model: options.model } : {},
|
|
42329
42990
|
...options.effort ? { effort: options.effort } : {}
|
|
42330
42991
|
}
|
|
@@ -42683,7 +43344,7 @@ function improveCodexErrorMessage(error52) {
|
|
|
42683
43344
|
}
|
|
42684
43345
|
|
|
42685
43346
|
// src/runners/git-preflight.ts
|
|
42686
|
-
import { spawn as
|
|
43347
|
+
import { spawn as spawn12 } from "node:child_process";
|
|
42687
43348
|
import { realpath as realpath10 } from "node:fs/promises";
|
|
42688
43349
|
import { isAbsolute as isAbsolute17, resolve as resolve11 } from "node:path";
|
|
42689
43350
|
var OUTPUT_LIMIT = 8192;
|
|
@@ -42732,7 +43393,7 @@ async function preflightGit(options = {}) {
|
|
|
42732
43393
|
}
|
|
42733
43394
|
async function runVersionProbe(input) {
|
|
42734
43395
|
return new Promise((resolvePromise) => {
|
|
42735
|
-
const child =
|
|
43396
|
+
const child = spawn12(input.executablePath, input.args, {
|
|
42736
43397
|
cwd: input.cwd,
|
|
42737
43398
|
env: {
|
|
42738
43399
|
...process.env.SystemRoot ? { SystemRoot: process.env.SystemRoot } : {},
|
|
@@ -42954,16 +43615,16 @@ function run2(command, args) {
|
|
|
42954
43615
|
}
|
|
42955
43616
|
|
|
42956
43617
|
// src/linux-service.ts
|
|
42957
|
-
import { spawn as
|
|
43618
|
+
import { spawn as spawn13 } from "node:child_process";
|
|
42958
43619
|
import { constants as constants2 } from "node:fs";
|
|
42959
|
-
import { access as access5, chmod as
|
|
43620
|
+
import { access as access5, chmod as chmod9, mkdir as mkdir16, open as open7, rename as rename8, rm as rm12 } from "node:fs/promises";
|
|
42960
43621
|
import { homedir as homedir11, userInfo } from "node:os";
|
|
42961
|
-
import { basename as basename4, dirname as dirname11, join as
|
|
43622
|
+
import { basename as basename4, dirname as dirname11, join as join23, relative as relative10, resolve as resolve13, sep as sep7 } from "node:path";
|
|
42962
43623
|
|
|
42963
43624
|
// src/service-runtime.ts
|
|
42964
|
-
import { access as access4, chmod as
|
|
43625
|
+
import { access as access4, chmod as chmod8, copyFile, mkdir as mkdir15, rename as rename7, rm as rm11 } from "node:fs/promises";
|
|
42965
43626
|
import { homedir as homedir10 } from "node:os";
|
|
42966
|
-
import { join as
|
|
43627
|
+
import { join as join22, resolve as resolve12, sep as sep6 } from "node:path";
|
|
42967
43628
|
async function ensureDurableServiceNode(options = {}) {
|
|
42968
43629
|
const execPath = resolve12(options.execPath ?? process.execPath);
|
|
42969
43630
|
const home = options.home ?? homedir10();
|
|
@@ -42973,22 +43634,22 @@ async function ensureDurableServiceNode(options = {}) {
|
|
|
42973
43634
|
throw new Error("the Node runtime version is not a safe directory name");
|
|
42974
43635
|
}
|
|
42975
43636
|
const zixtRoot = resolve12(home, ".zixt");
|
|
42976
|
-
if (execPath === zixtRoot || execPath.startsWith(zixtRoot +
|
|
42977
|
-
const directory =
|
|
42978
|
-
const destination =
|
|
43637
|
+
if (execPath === zixtRoot || execPath.startsWith(zixtRoot + sep6)) return execPath;
|
|
43638
|
+
const directory = join22(zixtRoot, "runtime", `node-${version2}`);
|
|
43639
|
+
const destination = join22(directory, platform === "win32" ? "node.exe" : "node");
|
|
42979
43640
|
const alreadyCopied = await access4(destination).then(
|
|
42980
43641
|
() => true,
|
|
42981
43642
|
() => false
|
|
42982
43643
|
);
|
|
42983
43644
|
if (alreadyCopied) return destination;
|
|
42984
|
-
await
|
|
43645
|
+
await mkdir15(directory, { recursive: true, mode: 448 });
|
|
42985
43646
|
const temporary = `${destination}.${process.pid}.${crypto.randomUUID()}.tmp`;
|
|
42986
43647
|
try {
|
|
42987
43648
|
await copyFile(execPath, temporary);
|
|
42988
|
-
await
|
|
42989
|
-
await
|
|
43649
|
+
await chmod8(temporary, 493);
|
|
43650
|
+
await rename7(temporary, destination);
|
|
42990
43651
|
} catch (error52) {
|
|
42991
|
-
await
|
|
43652
|
+
await rm11(temporary, { force: true }).catch(() => void 0);
|
|
42992
43653
|
throw error52;
|
|
42993
43654
|
}
|
|
42994
43655
|
await options.syncDirectory?.(directory);
|
|
@@ -43024,7 +43685,7 @@ function boundedAppend(current, chunk) {
|
|
|
43024
43685
|
async function defaultRunCommand(command, args) {
|
|
43025
43686
|
const commandEnvironment3 = systemServiceCommandEnvironment();
|
|
43026
43687
|
return new Promise((resolve19) => {
|
|
43027
|
-
const child =
|
|
43688
|
+
const child = spawn13(command, [...args], {
|
|
43028
43689
|
stdio: ["ignore", "pipe", "pipe"],
|
|
43029
43690
|
env: commandEnvironment3,
|
|
43030
43691
|
windowsHide: true
|
|
@@ -43096,33 +43757,33 @@ async function defaultSyncDirectory(path) {
|
|
|
43096
43757
|
}
|
|
43097
43758
|
}
|
|
43098
43759
|
async function ensureDirectory(path, mode, syncDirectory8) {
|
|
43099
|
-
const firstCreated = await
|
|
43760
|
+
const firstCreated = await mkdir16(path, { recursive: true, mode });
|
|
43100
43761
|
if (!firstCreated) return;
|
|
43101
43762
|
const first = resolve13(firstCreated);
|
|
43102
43763
|
const target = resolve13(path);
|
|
43103
43764
|
await syncDirectory8(dirname11(first));
|
|
43104
43765
|
let current = first;
|
|
43105
|
-
const descendants =
|
|
43106
|
-
for (const part of descendants ? descendants.split(
|
|
43766
|
+
const descendants = relative10(first, target);
|
|
43767
|
+
for (const part of descendants ? descendants.split(sep7) : []) {
|
|
43107
43768
|
await syncDirectory8(current);
|
|
43108
|
-
current =
|
|
43769
|
+
current = join23(current, part);
|
|
43109
43770
|
}
|
|
43110
43771
|
}
|
|
43111
43772
|
async function replacePrivateFile(path, contents, mode, syncDirectory8) {
|
|
43112
43773
|
const parent = dirname11(path);
|
|
43113
43774
|
await ensureDirectory(parent, 448, syncDirectory8);
|
|
43114
|
-
const temporary =
|
|
43775
|
+
const temporary = join23(parent, `.${basename4(path)}.${process.pid}.${crypto.randomUUID()}.tmp`);
|
|
43115
43776
|
const handle = await open7(temporary, "wx", mode);
|
|
43116
43777
|
try {
|
|
43117
43778
|
await handle.writeFile(contents, "utf8");
|
|
43118
43779
|
await handle.sync();
|
|
43119
43780
|
await handle.close();
|
|
43120
|
-
await
|
|
43121
|
-
await
|
|
43781
|
+
await rename8(temporary, path);
|
|
43782
|
+
await chmod9(path, mode);
|
|
43122
43783
|
await syncDirectory8(parent);
|
|
43123
43784
|
} catch (error52) {
|
|
43124
43785
|
await handle.close().catch(() => void 0);
|
|
43125
|
-
await
|
|
43786
|
+
await rm12(temporary, { force: true }).catch(() => void 0);
|
|
43126
43787
|
throw error52;
|
|
43127
43788
|
}
|
|
43128
43789
|
}
|
|
@@ -43163,11 +43824,11 @@ async function installLinuxService(options) {
|
|
|
43163
43824
|
"command search path"
|
|
43164
43825
|
);
|
|
43165
43826
|
const cloudUrl = options.cloudUrl ? oneLine(options.cloudUrl, "Zixt Cloud address") : void 0;
|
|
43166
|
-
const xdgConfigHome = env.XDG_CONFIG_HOME ? oneLine(env.XDG_CONFIG_HOME, "Linux configuration path") :
|
|
43167
|
-
const configRoot = options.serviceConfigRoot ??
|
|
43168
|
-
const unitRoot = options.userUnitRoot ??
|
|
43169
|
-
const environmentPath =
|
|
43170
|
-
const unitPath =
|
|
43827
|
+
const xdgConfigHome = env.XDG_CONFIG_HOME ? oneLine(env.XDG_CONFIG_HOME, "Linux configuration path") : join23(home, ".config");
|
|
43828
|
+
const configRoot = options.serviceConfigRoot ?? join23(xdgConfigHome, "zixt");
|
|
43829
|
+
const unitRoot = options.userUnitRoot ?? join23(xdgConfigHome, "systemd", "user");
|
|
43830
|
+
const environmentPath = join23(configRoot, "host.env");
|
|
43831
|
+
const unitPath = join23(unitRoot, SERVICE_NAME);
|
|
43171
43832
|
const installVersion = options.installVersion ?? ((version2, onFailure) => installRelease(version2, onFailure ? { onFailure } : {}));
|
|
43172
43833
|
const activateVersion = options.activateVersion ?? (options.installVersion ? async (entry) => entry : activateInstalledRelease);
|
|
43173
43834
|
const resolveCommand = options.resolveCommand ?? defaultResolveCommand;
|
|
@@ -43207,7 +43868,7 @@ async function installLinuxService(options) {
|
|
|
43207
43868
|
}
|
|
43208
43869
|
}
|
|
43209
43870
|
await ensureDirectory(configRoot, 448, syncDirectory8);
|
|
43210
|
-
await
|
|
43871
|
+
await chmod9(configRoot, 448);
|
|
43211
43872
|
const serviceEnvironment = [
|
|
43212
43873
|
`ZIXT_HOST_TOKEN=${systemdEnvironmentValue(token2)}`,
|
|
43213
43874
|
...cloudUrl ? [`ZIXT_CLOUD_URL=${systemdEnvironmentValue(cloudUrl)}`] : [],
|
|
@@ -43295,11 +43956,11 @@ async function installLinuxService(options) {
|
|
|
43295
43956
|
}
|
|
43296
43957
|
|
|
43297
43958
|
// src/macos-service.ts
|
|
43298
|
-
import { spawn as
|
|
43959
|
+
import { spawn as spawn14 } from "node:child_process";
|
|
43299
43960
|
import { constants as constants3 } from "node:fs";
|
|
43300
|
-
import { access as access6, chmod as
|
|
43961
|
+
import { access as access6, chmod as chmod10, mkdir as mkdir17, open as open8, rename as rename9, rm as rm13 } from "node:fs/promises";
|
|
43301
43962
|
import { homedir as homedir12, userInfo as userInfo2 } from "node:os";
|
|
43302
|
-
import { basename as basename5, dirname as dirname12, join as
|
|
43963
|
+
import { basename as basename5, dirname as dirname12, join as join24, relative as relative11, resolve as resolve14, sep as sep8 } from "node:path";
|
|
43303
43964
|
var LAUNCH_AGENT_LABEL = "ai.zixt.host";
|
|
43304
43965
|
var SERVICE_STABILITY_DELAY_MS2 = 2e3;
|
|
43305
43966
|
var STATUS_WAIT_MS = 2e4;
|
|
@@ -43324,32 +43985,32 @@ async function syncDirectory4(path) {
|
|
|
43324
43985
|
}
|
|
43325
43986
|
}
|
|
43326
43987
|
async function ensureDirectory2(path, sync) {
|
|
43327
|
-
const firstCreated = await
|
|
43988
|
+
const firstCreated = await mkdir17(path, { recursive: true, mode: 448 });
|
|
43328
43989
|
if (!firstCreated) return;
|
|
43329
43990
|
const first = resolve14(firstCreated);
|
|
43330
43991
|
const target = resolve14(path);
|
|
43331
43992
|
await sync(dirname12(first));
|
|
43332
43993
|
let current = first;
|
|
43333
|
-
for (const part of
|
|
43994
|
+
for (const part of relative11(first, target).split(sep8).filter(Boolean)) {
|
|
43334
43995
|
await sync(current);
|
|
43335
|
-
current =
|
|
43996
|
+
current = join24(current, part);
|
|
43336
43997
|
}
|
|
43337
43998
|
}
|
|
43338
43999
|
async function replacePrivateFile2(path, contents, mode, sync) {
|
|
43339
44000
|
const parent = dirname12(path);
|
|
43340
44001
|
await ensureDirectory2(parent, sync);
|
|
43341
|
-
const temporary =
|
|
44002
|
+
const temporary = join24(parent, `.${basename5(path)}.${process.pid}.${crypto.randomUUID()}.tmp`);
|
|
43342
44003
|
const handle = await open8(temporary, "wx", mode);
|
|
43343
44004
|
try {
|
|
43344
44005
|
await handle.writeFile(contents, "utf8");
|
|
43345
44006
|
await handle.sync();
|
|
43346
44007
|
await handle.close();
|
|
43347
|
-
await
|
|
43348
|
-
await
|
|
44008
|
+
await rename9(temporary, path);
|
|
44009
|
+
await chmod10(path, mode);
|
|
43349
44010
|
await sync(parent);
|
|
43350
44011
|
} catch (error52) {
|
|
43351
44012
|
await handle.close().catch(() => void 0);
|
|
43352
|
-
await
|
|
44013
|
+
await rm13(temporary, { force: true }).catch(() => void 0);
|
|
43353
44014
|
throw error52;
|
|
43354
44015
|
}
|
|
43355
44016
|
}
|
|
@@ -43363,7 +44024,7 @@ function commandEnvironment(env) {
|
|
|
43363
44024
|
}
|
|
43364
44025
|
async function defaultRunCommand2(command, args, env) {
|
|
43365
44026
|
return new Promise((resolveResult) => {
|
|
43366
|
-
const child =
|
|
44027
|
+
const child = spawn14(command, [...args], {
|
|
43367
44028
|
stdio: ["ignore", "pipe", "pipe"],
|
|
43368
44029
|
env: commandEnvironment(env)
|
|
43369
44030
|
});
|
|
@@ -43435,14 +44096,14 @@ async function installMacosService(options) {
|
|
|
43435
44096
|
options.path ?? env.PATH ?? "/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin",
|
|
43436
44097
|
"command search path"
|
|
43437
44098
|
);
|
|
43438
|
-
const configRoot = options.configRoot ??
|
|
43439
|
-
const launchAgentsRoot = options.launchAgentsRoot ??
|
|
43440
|
-
const logRoot = options.logRoot ??
|
|
43441
|
-
const configPath =
|
|
43442
|
-
const launcherPath =
|
|
43443
|
-
const plistPath =
|
|
43444
|
-
const stdoutPath =
|
|
43445
|
-
const stderrPath =
|
|
44099
|
+
const configRoot = options.configRoot ?? join24(home, "Library", "Application Support", "Zixt");
|
|
44100
|
+
const launchAgentsRoot = options.launchAgentsRoot ?? join24(home, "Library", "LaunchAgents");
|
|
44101
|
+
const logRoot = options.logRoot ?? join24(home, "Library", "Logs", "Zixt");
|
|
44102
|
+
const configPath = join24(configRoot, "host.env");
|
|
44103
|
+
const launcherPath = join24(configRoot, "host-launcher.sh");
|
|
44104
|
+
const plistPath = join24(launchAgentsRoot, `${LAUNCH_AGENT_LABEL}.plist`);
|
|
44105
|
+
const stdoutPath = join24(logRoot, "host.log");
|
|
44106
|
+
const stderrPath = join24(logRoot, "host-error.log");
|
|
43446
44107
|
const installVersion = options.installVersion ?? ((version2, onFailure) => installRelease(version2, onFailure ? { onFailure } : {}));
|
|
43447
44108
|
const activateVersion = options.activateVersion ?? (options.installVersion ? async (entry) => entry : (entry) => activateInstalledRelease(entry));
|
|
43448
44109
|
const resolveCommand = options.resolveCommand ?? (async () => defaultResolveCommand2());
|
|
@@ -43465,7 +44126,7 @@ async function installMacosService(options) {
|
|
|
43465
44126
|
await ensureDirectory2(configRoot, sync);
|
|
43466
44127
|
await ensureDirectory2(launchAgentsRoot, sync);
|
|
43467
44128
|
await ensureDirectory2(logRoot, sync);
|
|
43468
|
-
await
|
|
44129
|
+
await chmod10(configRoot, 448);
|
|
43469
44130
|
const serviceEnvironment = [
|
|
43470
44131
|
`ZIXT_HOST_TOKEN=${shellValue(token2)}`,
|
|
43471
44132
|
...cloudUrl ? [`ZIXT_CLOUD_URL=${shellValue(cloudUrl)}`] : [],
|
|
@@ -43543,11 +44204,11 @@ async function installMacosService(options) {
|
|
|
43543
44204
|
}
|
|
43544
44205
|
|
|
43545
44206
|
// src/windows-service.ts
|
|
43546
|
-
import { spawn as
|
|
44207
|
+
import { spawn as spawn15 } from "node:child_process";
|
|
43547
44208
|
import { constants as constants4 } from "node:fs";
|
|
43548
|
-
import { access as access7, mkdir as
|
|
44209
|
+
import { access as access7, mkdir as mkdir18, open as open9, readFile as readFile12, rename as rename10, rm as rm14 } from "node:fs/promises";
|
|
43549
44210
|
import { homedir as homedir13 } from "node:os";
|
|
43550
|
-
import { basename as basename6, dirname as dirname13, isAbsolute as isAbsolute18, join as
|
|
44211
|
+
import { basename as basename6, dirname as dirname13, isAbsolute as isAbsolute18, join as join25, relative as relative12, resolve as resolve15, sep as sep9 } from "node:path";
|
|
43551
44212
|
var TASK_NAME = "Zixt Host";
|
|
43552
44213
|
var COMMAND_TIMEOUT_MS3 = 7e4;
|
|
43553
44214
|
var SERVICE_STABILITY_DELAY_MS3 = 2e3;
|
|
@@ -43573,31 +44234,31 @@ async function syncDirectory5(path) {
|
|
|
43573
44234
|
}
|
|
43574
44235
|
}
|
|
43575
44236
|
async function ensureDirectory3(path, sync) {
|
|
43576
|
-
const firstCreated = await
|
|
44237
|
+
const firstCreated = await mkdir18(path, { recursive: true, mode: 448 });
|
|
43577
44238
|
if (!firstCreated) return;
|
|
43578
44239
|
const first = resolve15(firstCreated);
|
|
43579
44240
|
const target = resolve15(path);
|
|
43580
44241
|
await sync(dirname13(first));
|
|
43581
44242
|
let current = first;
|
|
43582
|
-
for (const part of
|
|
44243
|
+
for (const part of relative12(first, target).split(sep9).filter(Boolean)) {
|
|
43583
44244
|
await sync(current);
|
|
43584
|
-
current =
|
|
44245
|
+
current = join25(current, part);
|
|
43585
44246
|
}
|
|
43586
44247
|
}
|
|
43587
44248
|
async function replacePrivateFile3(path, contents, sync, encoding = "utf8") {
|
|
43588
44249
|
const parent = dirname13(path);
|
|
43589
44250
|
await ensureDirectory3(parent, sync);
|
|
43590
|
-
const temporary =
|
|
44251
|
+
const temporary = join25(parent, `.${basename6(path)}.${process.pid}.${crypto.randomUUID()}.tmp`);
|
|
43591
44252
|
const handle = await open9(temporary, "wx", 384);
|
|
43592
44253
|
try {
|
|
43593
44254
|
await handle.writeFile(encoding === "utf16le" ? `\uFEFF${contents}` : contents, encoding);
|
|
43594
44255
|
await handle.sync();
|
|
43595
44256
|
await handle.close();
|
|
43596
|
-
await
|
|
44257
|
+
await rename10(temporary, path);
|
|
43597
44258
|
await sync(parent);
|
|
43598
44259
|
} catch (error52) {
|
|
43599
44260
|
await handle.close().catch(() => void 0);
|
|
43600
|
-
await
|
|
44261
|
+
await rm14(temporary, { force: true }).catch(() => void 0);
|
|
43601
44262
|
throw error52;
|
|
43602
44263
|
}
|
|
43603
44264
|
}
|
|
@@ -43608,7 +44269,7 @@ function commandEnvironment2(env) {
|
|
|
43608
44269
|
}
|
|
43609
44270
|
async function runChild(command, args, env, input) {
|
|
43610
44271
|
return new Promise((resolveResult) => {
|
|
43611
|
-
const child =
|
|
44272
|
+
const child = spawn15(command, [...args], {
|
|
43612
44273
|
stdio: [input === void 0 ? "ignore" : "pipe", "pipe", "pipe"],
|
|
43613
44274
|
env: commandEnvironment2(env),
|
|
43614
44275
|
windowsHide: true
|
|
@@ -43642,7 +44303,7 @@ async function runChild(command, args, env, input) {
|
|
|
43642
44303
|
async function defaultResolveCommand3(name, env) {
|
|
43643
44304
|
const root = env.SYSTEMROOT ?? env.WINDIR;
|
|
43644
44305
|
if (!root || !isAbsolute18(root)) return null;
|
|
43645
|
-
const candidate = name === "powershell" ?
|
|
44306
|
+
const candidate = name === "powershell" ? join25(root, "System32", "WindowsPowerShell", "v1.0", "powershell.exe") : join25(root, "System32", `${name}.exe`);
|
|
43646
44307
|
return access7(candidate, constants4.X_OK).then(
|
|
43647
44308
|
() => candidate,
|
|
43648
44309
|
() => null
|
|
@@ -43732,7 +44393,7 @@ exit $code
|
|
|
43732
44393
|
}
|
|
43733
44394
|
async function defaultObserveStatus(path, generation) {
|
|
43734
44395
|
try {
|
|
43735
|
-
const text = (await
|
|
44396
|
+
const text = (await readFile12(path, "utf8")).replace(/^\uFEFF/, "");
|
|
43736
44397
|
const value = JSON.parse(text);
|
|
43737
44398
|
if (value.schema !== 1 || value.generation !== generation || typeof value.pid !== "number" || !Number.isSafeInteger(value.pid) || value.pid <= 0) {
|
|
43738
44399
|
return null;
|
|
@@ -43793,12 +44454,12 @@ async function installWindowsService(options) {
|
|
|
43793
44454
|
const token2 = oneLine3(options.token, "pairing code");
|
|
43794
44455
|
const cloudUrl = options.cloudUrl ? oneLine3(options.cloudUrl, "Zixt Cloud address") : void 0;
|
|
43795
44456
|
const path = oneLine3(options.path ?? env.PATH ?? "", "command search path");
|
|
43796
|
-
const configRoot = options.configRoot ??
|
|
43797
|
-
const configPath =
|
|
43798
|
-
const launcherPath =
|
|
43799
|
-
const launchShimPath =
|
|
43800
|
-
const taskXmlPath =
|
|
43801
|
-
const statusPath =
|
|
44457
|
+
const configRoot = options.configRoot ?? join25(localAppData, "Zixt", "Host");
|
|
44458
|
+
const configPath = join25(configRoot, "host.json");
|
|
44459
|
+
const launcherPath = join25(configRoot, "host-launcher.ps1");
|
|
44460
|
+
const launchShimPath = join25(configRoot, "host-launch.vbs");
|
|
44461
|
+
const taskXmlPath = join25(configRoot, "host-task.xml");
|
|
44462
|
+
const statusPath = join25(configRoot, "host-status.json");
|
|
43802
44463
|
const installVersion = options.installVersion ?? ((version2, onFailure) => installRelease(version2, onFailure ? { onFailure } : {}));
|
|
43803
44464
|
const activateVersion = options.activateVersion ?? (options.installVersion ? async (entry) => entry : (entry) => activateInstalledRelease(entry));
|
|
43804
44465
|
const resolveCommand = options.resolveCommand ?? ((name) => defaultResolveCommand3(name, env));
|
|
@@ -43865,7 +44526,7 @@ async function installWindowsService(options) {
|
|
|
43865
44526
|
sync,
|
|
43866
44527
|
"utf16le"
|
|
43867
44528
|
);
|
|
43868
|
-
await
|
|
44529
|
+
await rm14(statusPath, { force: true });
|
|
43869
44530
|
const acl = await run3(icacls, [
|
|
43870
44531
|
configRoot,
|
|
43871
44532
|
"/inheritance:r",
|
|
@@ -43925,23 +44586,23 @@ async function installSystemService(options) {
|
|
|
43925
44586
|
}
|
|
43926
44587
|
|
|
43927
44588
|
// src/terminal-outcomes.ts
|
|
43928
|
-
import { chmod as
|
|
44589
|
+
import { chmod as chmod11, lstat as lstat12, mkdir as mkdir19, open as open10, readdir as readdir7, readFile as readFile13, rename as rename11, rm as rm15 } from "node:fs/promises";
|
|
43929
44590
|
import { homedir as homedir14 } from "node:os";
|
|
43930
|
-
import { dirname as dirname14, join as
|
|
44591
|
+
import { dirname as dirname14, join as join26, relative as relative13, resolve as resolve16, sep as sep10 } from "node:path";
|
|
43931
44592
|
var DIRECTORY_MODE5 = 448;
|
|
43932
44593
|
var FILE_MODE4 = 384;
|
|
43933
44594
|
var MAX_OUTCOME_BYTES = 4 * 1024 * 1024;
|
|
43934
44595
|
var HOST_DIRECTORY = /^hst_[0-9a-f]{32}$/;
|
|
43935
44596
|
var OUTCOME_FILE = /^(tsk_[0-9a-f]{32})\.([1-9][0-9]*)\.json$/;
|
|
43936
44597
|
function defaultTerminalOutcomeRoot() {
|
|
43937
|
-
return
|
|
44598
|
+
return join26(homedir14(), ".zixt", "terminal-outcomes");
|
|
43938
44599
|
}
|
|
43939
44600
|
function hostOutcomeRoot(root, hostId) {
|
|
43940
44601
|
if (!HOST_DIRECTORY.test(hostId)) throw new Error("terminal outcome Host identity is malformed");
|
|
43941
|
-
return
|
|
44602
|
+
return join26(root, hostId);
|
|
43942
44603
|
}
|
|
43943
44604
|
function outcomePath(root, hostId, taskId, epoch) {
|
|
43944
|
-
return
|
|
44605
|
+
return join26(hostOutcomeRoot(root, hostId), `${taskId}.${epoch}.json`);
|
|
43945
44606
|
}
|
|
43946
44607
|
async function syncDirectory6(root) {
|
|
43947
44608
|
if (process.platform === "win32") return;
|
|
@@ -43953,22 +44614,22 @@ async function syncDirectory6(root) {
|
|
|
43953
44614
|
}
|
|
43954
44615
|
}
|
|
43955
44616
|
async function requirePrivateRoot(root, sync = syncDirectory6) {
|
|
43956
|
-
const firstCreated = await
|
|
44617
|
+
const firstCreated = await mkdir19(root, { recursive: true, mode: DIRECTORY_MODE5 });
|
|
43957
44618
|
if (firstCreated) {
|
|
43958
44619
|
const first = resolve16(firstCreated);
|
|
43959
44620
|
const target = resolve16(root);
|
|
43960
44621
|
await sync(dirname14(first));
|
|
43961
44622
|
let current = first;
|
|
43962
|
-
for (const part of
|
|
44623
|
+
for (const part of relative13(first, target).split(sep10).filter(Boolean)) {
|
|
43963
44624
|
await sync(current);
|
|
43964
|
-
current =
|
|
44625
|
+
current = join26(current, part);
|
|
43965
44626
|
}
|
|
43966
44627
|
}
|
|
43967
44628
|
const stat4 = await lstat12(root);
|
|
43968
44629
|
if (stat4.isSymbolicLink() || !stat4.isDirectory()) {
|
|
43969
44630
|
throw new Error("terminal outcome journal root is not a trusted directory");
|
|
43970
44631
|
}
|
|
43971
|
-
await
|
|
44632
|
+
await chmod11(root, DIRECTORY_MODE5);
|
|
43972
44633
|
}
|
|
43973
44634
|
function parseCommittedOutcome(text, taskId, epoch) {
|
|
43974
44635
|
let json2;
|
|
@@ -43992,7 +44653,7 @@ async function recordTerminalOutcome(hostId, input, root = defaultTerminalOutcom
|
|
|
43992
44653
|
const destination = outcomePath(root, hostId, outcome.taskId, outcome.epoch);
|
|
43993
44654
|
try {
|
|
43994
44655
|
const existing = parseCommittedOutcome(
|
|
43995
|
-
await
|
|
44656
|
+
await readFile13(destination, { encoding: "utf8", flag: "r" }),
|
|
43996
44657
|
outcome.taskId,
|
|
43997
44658
|
outcome.epoch
|
|
43998
44659
|
);
|
|
@@ -44001,7 +44662,7 @@ async function recordTerminalOutcome(hostId, input, root = defaultTerminalOutcom
|
|
|
44001
44662
|
} catch (error52) {
|
|
44002
44663
|
if (error52.code !== "ENOENT") throw error52;
|
|
44003
44664
|
}
|
|
44004
|
-
const temporary =
|
|
44665
|
+
const temporary = join26(
|
|
44005
44666
|
scopedRoot,
|
|
44006
44667
|
`.${outcome.taskId}.${outcome.epoch}.${process.pid}.${Date.now()}.${outcome.resultId}.tmp`
|
|
44007
44668
|
);
|
|
@@ -44012,13 +44673,13 @@ async function recordTerminalOutcome(hostId, input, root = defaultTerminalOutcom
|
|
|
44012
44673
|
await handle.sync();
|
|
44013
44674
|
await handle.close();
|
|
44014
44675
|
handle = void 0;
|
|
44015
|
-
await
|
|
44676
|
+
await rename11(temporary, destination);
|
|
44016
44677
|
await sync(scopedRoot);
|
|
44017
44678
|
await sync(root);
|
|
44018
44679
|
} finally {
|
|
44019
44680
|
await handle?.close().catch(() => {
|
|
44020
44681
|
});
|
|
44021
|
-
await
|
|
44682
|
+
await rm15(temporary, { force: true }).catch(() => {
|
|
44022
44683
|
});
|
|
44023
44684
|
}
|
|
44024
44685
|
}
|
|
@@ -44033,8 +44694,8 @@ async function readTerminalOutcomesStrict(root = defaultTerminalOutcomeRoot()) {
|
|
|
44033
44694
|
if (rootStat.isSymbolicLink() || !rootStat.isDirectory()) {
|
|
44034
44695
|
throw new Error("terminal outcome journal root is not a trusted directory");
|
|
44035
44696
|
}
|
|
44036
|
-
await
|
|
44037
|
-
const hostEntries = await
|
|
44697
|
+
await chmod11(root, DIRECTORY_MODE5);
|
|
44698
|
+
const hostEntries = await readdir7(root, { withFileTypes: true });
|
|
44038
44699
|
const outcomes = [];
|
|
44039
44700
|
const resultIds = /* @__PURE__ */ new Set();
|
|
44040
44701
|
for (const hostEntry of hostEntries) {
|
|
@@ -44046,21 +44707,21 @@ async function readTerminalOutcomesStrict(root = defaultTerminalOutcomeRoot()) {
|
|
|
44046
44707
|
if (scopedStat.isSymbolicLink() || !scopedStat.isDirectory()) {
|
|
44047
44708
|
throw new Error("terminal outcome Host scope is not a trusted directory");
|
|
44048
44709
|
}
|
|
44049
|
-
await
|
|
44050
|
-
const entries = await
|
|
44710
|
+
await chmod11(scopedRoot, DIRECTORY_MODE5);
|
|
44711
|
+
const entries = await readdir7(scopedRoot, { withFileTypes: true });
|
|
44051
44712
|
for (const entry of entries) {
|
|
44052
44713
|
if (!entry.name.endsWith(".json")) continue;
|
|
44053
44714
|
const match = OUTCOME_FILE.exec(entry.name);
|
|
44054
44715
|
if (!match || !entry.isFile() || entry.isSymbolicLink()) {
|
|
44055
44716
|
throw new Error("committed terminal outcome is not a trusted regular file");
|
|
44056
44717
|
}
|
|
44057
|
-
const path =
|
|
44718
|
+
const path = join26(scopedRoot, entry.name);
|
|
44058
44719
|
const stat4 = await lstat12(path);
|
|
44059
44720
|
if (!stat4.isFile() || stat4.isSymbolicLink() || stat4.size > MAX_OUTCOME_BYTES) {
|
|
44060
44721
|
throw new Error("committed terminal outcome is not a trusted regular file");
|
|
44061
44722
|
}
|
|
44062
44723
|
const outcome = parseCommittedOutcome(
|
|
44063
|
-
await
|
|
44724
|
+
await readFile13(path, "utf8"),
|
|
44064
44725
|
match[1],
|
|
44065
44726
|
Number(match[2])
|
|
44066
44727
|
);
|
|
@@ -44087,7 +44748,7 @@ async function forgetAcknowledgedTerminalOutcomes(refs, root = defaultTerminalOu
|
|
|
44087
44748
|
if (acknowledged.get(`${hostId}:${outcome.taskId}:${outcome.epoch}`) !== outcome.resultId) {
|
|
44088
44749
|
continue;
|
|
44089
44750
|
}
|
|
44090
|
-
await
|
|
44751
|
+
await rm15(outcomePath(root, hostId, outcome.taskId, outcome.epoch), { force: true });
|
|
44091
44752
|
changedHostRoots.add(hostOutcomeRoot(root, hostId));
|
|
44092
44753
|
}
|
|
44093
44754
|
for (const scopedRoot of changedHostRoots) await syncDirectory6(scopedRoot);
|
|
@@ -44099,22 +44760,22 @@ async function forgetSupersededTerminalOutcomes(hostId, taskId, epoch, root = de
|
|
|
44099
44760
|
if (scoped.hostId !== hostId) continue;
|
|
44100
44761
|
const { outcome } = scoped;
|
|
44101
44762
|
if (outcome.taskId !== taskId || outcome.epoch >= epoch) continue;
|
|
44102
|
-
await
|
|
44763
|
+
await rm15(outcomePath(root, hostId, outcome.taskId, outcome.epoch), { force: true });
|
|
44103
44764
|
removed = true;
|
|
44104
44765
|
}
|
|
44105
44766
|
if (removed) await syncDirectory6(hostOutcomeRoot(root, hostId));
|
|
44106
44767
|
}
|
|
44107
44768
|
|
|
44108
44769
|
// src/accepted-assignments.ts
|
|
44109
|
-
import { chmod as
|
|
44770
|
+
import { chmod as chmod12, lstat as lstat13, mkdir as mkdir20, open as open11, readdir as readdir8, rename as rename12, rm as rm16 } from "node:fs/promises";
|
|
44110
44771
|
import { homedir as homedir15 } from "node:os";
|
|
44111
|
-
import { dirname as dirname15, join as
|
|
44772
|
+
import { dirname as dirname15, join as join27, relative as relative14, resolve as resolve17, sep as sep11 } from "node:path";
|
|
44112
44773
|
var DIRECTORY_MODE6 = 448;
|
|
44113
44774
|
var FILE_MODE5 = 384;
|
|
44114
44775
|
var CLAIM_FILE = /^(tsk_[0-9a-f]{32})\.([1-9][0-9]*)\.json$/;
|
|
44115
44776
|
var TASK_ID = /^tsk_[0-9a-f]{32}$/;
|
|
44116
44777
|
function defaultAcceptedAssignmentRoot() {
|
|
44117
|
-
return
|
|
44778
|
+
return join27(homedir15(), ".zixt", "accepted-assignments");
|
|
44118
44779
|
}
|
|
44119
44780
|
async function syncDirectory7(root) {
|
|
44120
44781
|
if (process.platform === "win32") return;
|
|
@@ -44126,29 +44787,29 @@ async function syncDirectory7(root) {
|
|
|
44126
44787
|
}
|
|
44127
44788
|
}
|
|
44128
44789
|
async function requirePrivateRoot2(root, sync = syncDirectory7) {
|
|
44129
|
-
const firstCreated = await
|
|
44790
|
+
const firstCreated = await mkdir20(root, { recursive: true, mode: DIRECTORY_MODE6 });
|
|
44130
44791
|
if (firstCreated) {
|
|
44131
44792
|
const first = resolve17(firstCreated);
|
|
44132
44793
|
const target = resolve17(root);
|
|
44133
44794
|
await sync(dirname15(first));
|
|
44134
44795
|
let current = first;
|
|
44135
|
-
for (const part of
|
|
44796
|
+
for (const part of relative14(first, target).split(sep11).filter(Boolean)) {
|
|
44136
44797
|
await sync(current);
|
|
44137
|
-
current =
|
|
44798
|
+
current = join27(current, part);
|
|
44138
44799
|
}
|
|
44139
44800
|
}
|
|
44140
44801
|
const stat4 = await lstat13(root);
|
|
44141
44802
|
if (stat4.isSymbolicLink() || !stat4.isDirectory()) {
|
|
44142
44803
|
throw new Error("accepted assignment journal root is not a trusted directory");
|
|
44143
44804
|
}
|
|
44144
|
-
await
|
|
44805
|
+
await chmod12(root, DIRECTORY_MODE6);
|
|
44145
44806
|
}
|
|
44146
44807
|
function claimPath(root, taskId, epoch) {
|
|
44147
44808
|
if (!TASK_ID.test(taskId)) throw new Error("accepted assignment Task identity is malformed");
|
|
44148
44809
|
if (!Number.isSafeInteger(epoch) || epoch < 1) {
|
|
44149
44810
|
throw new Error("accepted assignment epoch is malformed");
|
|
44150
44811
|
}
|
|
44151
|
-
return
|
|
44812
|
+
return join27(root, `${taskId}.${epoch}.json`);
|
|
44152
44813
|
}
|
|
44153
44814
|
async function recordAcceptedAssignment(assignment, root = defaultAcceptedAssignmentRoot(), options = {}) {
|
|
44154
44815
|
const sync = options.syncDirectory ?? syncDirectory7;
|
|
@@ -44158,7 +44819,7 @@ async function recordAcceptedAssignment(assignment, root = defaultAcceptedAssign
|
|
|
44158
44819
|
} catch {
|
|
44159
44820
|
return false;
|
|
44160
44821
|
}
|
|
44161
|
-
const temporary =
|
|
44822
|
+
const temporary = join27(
|
|
44162
44823
|
root,
|
|
44163
44824
|
`.${assignment.taskId}.${assignment.epoch}.${process.pid}.${Date.now()}.tmp`
|
|
44164
44825
|
);
|
|
@@ -44170,7 +44831,7 @@ async function recordAcceptedAssignment(assignment, root = defaultAcceptedAssign
|
|
|
44170
44831
|
await handle.sync();
|
|
44171
44832
|
await handle.close();
|
|
44172
44833
|
handle = void 0;
|
|
44173
|
-
await
|
|
44834
|
+
await rename12(temporary, destination);
|
|
44174
44835
|
if (process.platform !== "win32") await sync(root);
|
|
44175
44836
|
return true;
|
|
44176
44837
|
} catch {
|
|
@@ -44178,7 +44839,7 @@ async function recordAcceptedAssignment(assignment, root = defaultAcceptedAssign
|
|
|
44178
44839
|
} finally {
|
|
44179
44840
|
await handle?.close().catch(() => {
|
|
44180
44841
|
});
|
|
44181
|
-
await
|
|
44842
|
+
await rm16(temporary, { force: true }).catch(() => {
|
|
44182
44843
|
});
|
|
44183
44844
|
}
|
|
44184
44845
|
}
|
|
@@ -44193,9 +44854,9 @@ async function recoverAcceptedAssignments(root = defaultAcceptedAssignmentRoot()
|
|
|
44193
44854
|
if (rootStat.isSymbolicLink() || !rootStat.isDirectory()) {
|
|
44194
44855
|
throw new Error("accepted assignment journal root is not a trusted directory");
|
|
44195
44856
|
}
|
|
44196
|
-
await
|
|
44857
|
+
await chmod12(root, DIRECTORY_MODE6);
|
|
44197
44858
|
const claims = [];
|
|
44198
|
-
for (const entry of await
|
|
44859
|
+
for (const entry of await readdir8(root, { withFileTypes: true })) {
|
|
44199
44860
|
if (!entry.isFile()) continue;
|
|
44200
44861
|
const match = CLAIM_FILE.exec(entry.name);
|
|
44201
44862
|
if (!match) continue;
|
|
@@ -44212,7 +44873,7 @@ async function forgetAcceptedAssignment(assignment, root = defaultAcceptedAssign
|
|
|
44212
44873
|
} catch {
|
|
44213
44874
|
return;
|
|
44214
44875
|
}
|
|
44215
|
-
await
|
|
44876
|
+
await rm16(path, { force: true }).catch(() => {
|
|
44216
44877
|
});
|
|
44217
44878
|
}
|
|
44218
44879
|
async function forgetAcknowledgedAcceptedAssignments(assignments, root = defaultAcceptedAssignmentRoot()) {
|
|
@@ -44220,9 +44881,9 @@ async function forgetAcknowledgedAcceptedAssignments(assignments, root = default
|
|
|
44220
44881
|
}
|
|
44221
44882
|
|
|
44222
44883
|
// src/local-observability.ts
|
|
44223
|
-
import { appendFile, mkdir as
|
|
44884
|
+
import { appendFile, mkdir as mkdir21, open as open12, readdir as readdir9, rename as rename13, rm as rm17, stat as stat3 } from "node:fs/promises";
|
|
44224
44885
|
import { homedir as homedir16 } from "node:os";
|
|
44225
|
-
import { basename as basename7, dirname as dirname16, join as
|
|
44886
|
+
import { basename as basename7, dirname as dirname16, join as join28 } from "node:path";
|
|
44226
44887
|
|
|
44227
44888
|
// src/logger.ts
|
|
44228
44889
|
var ANSI = {
|
|
@@ -44334,11 +44995,11 @@ var LOCAL_STATUS_FILE = "status.json";
|
|
|
44334
44995
|
var LOCAL_REQUESTS_DIR = "requests";
|
|
44335
44996
|
var DEFAULT_CONSOLE_ROTATE_BYTES = 2 * 1024 * 1024;
|
|
44336
44997
|
function defaultLocalObservabilityRoot() {
|
|
44337
|
-
return
|
|
44998
|
+
return join28(homedir16(), ".zixt", "observability");
|
|
44338
44999
|
}
|
|
44339
45000
|
function createLocalConsoleSink(options = {}) {
|
|
44340
45001
|
const root = options.root ?? defaultLocalObservabilityRoot();
|
|
44341
|
-
const consolePath =
|
|
45002
|
+
const consolePath = join28(root, LOCAL_CONSOLE_FILE);
|
|
44342
45003
|
const rotateBytes = options.rotateBytes ?? DEFAULT_CONSOLE_ROTATE_BYTES;
|
|
44343
45004
|
let disabled = false;
|
|
44344
45005
|
let prepared = false;
|
|
@@ -44348,7 +45009,7 @@ function createLocalConsoleSink(options = {}) {
|
|
|
44348
45009
|
if (disabled) return;
|
|
44349
45010
|
try {
|
|
44350
45011
|
if (!prepared) {
|
|
44351
|
-
await
|
|
45012
|
+
await mkdir21(root, { recursive: true, mode: 448 });
|
|
44352
45013
|
approximateBytes = await stat3(consolePath).then(
|
|
44353
45014
|
(existing) => existing.size,
|
|
44354
45015
|
() => 0
|
|
@@ -44356,8 +45017,8 @@ function createLocalConsoleSink(options = {}) {
|
|
|
44356
45017
|
prepared = true;
|
|
44357
45018
|
}
|
|
44358
45019
|
if (approximateBytes >= rotateBytes) {
|
|
44359
|
-
await
|
|
44360
|
-
await
|
|
45020
|
+
await rm17(join28(root, LOCAL_CONSOLE_PREVIOUS_FILE), { force: true });
|
|
45021
|
+
await rename13(consolePath, join28(root, LOCAL_CONSOLE_PREVIOUS_FILE)).catch(
|
|
44361
45022
|
(error52) => {
|
|
44362
45023
|
if (error52.code !== "ENOENT") throw error52;
|
|
44363
45024
|
}
|
|
@@ -44388,11 +45049,11 @@ function createLocalConsoleSink(options = {}) {
|
|
|
44388
45049
|
};
|
|
44389
45050
|
}
|
|
44390
45051
|
async function consumeRunnerInstallRequests(root = defaultLocalObservabilityRoot()) {
|
|
44391
|
-
const directory =
|
|
45052
|
+
const directory = join28(root, LOCAL_REQUESTS_DIR);
|
|
44392
45053
|
const requested = /* @__PURE__ */ new Set();
|
|
44393
45054
|
let names;
|
|
44394
45055
|
try {
|
|
44395
|
-
names = await
|
|
45056
|
+
names = await readdir9(directory);
|
|
44396
45057
|
} catch {
|
|
44397
45058
|
return requested;
|
|
44398
45059
|
}
|
|
@@ -44400,7 +45061,7 @@ async function consumeRunnerInstallRequests(root = defaultLocalObservabilityRoot
|
|
|
44400
45061
|
const name = `install-runner-${type}.json`;
|
|
44401
45062
|
if (!names.includes(name)) continue;
|
|
44402
45063
|
try {
|
|
44403
|
-
await
|
|
45064
|
+
await rm17(join28(directory, name), { force: true });
|
|
44404
45065
|
requested.add(type);
|
|
44405
45066
|
} catch {
|
|
44406
45067
|
}
|
|
@@ -44408,13 +45069,13 @@ async function consumeRunnerInstallRequests(root = defaultLocalObservabilityRoot
|
|
|
44408
45069
|
return requested;
|
|
44409
45070
|
}
|
|
44410
45071
|
async function writeLocalStatus(status, root = defaultLocalObservabilityRoot()) {
|
|
44411
|
-
const destination =
|
|
44412
|
-
const temporary =
|
|
45072
|
+
const destination = join28(root, LOCAL_STATUS_FILE);
|
|
45073
|
+
const temporary = join28(
|
|
44413
45074
|
dirname16(destination),
|
|
44414
45075
|
`.${basename7(destination)}.${process.pid}.${crypto.randomUUID()}.tmp`
|
|
44415
45076
|
);
|
|
44416
45077
|
try {
|
|
44417
|
-
await
|
|
45078
|
+
await mkdir21(root, { recursive: true, mode: 448 });
|
|
44418
45079
|
const handle = await open12(temporary, "wx", 384);
|
|
44419
45080
|
try {
|
|
44420
45081
|
await handle.writeFile(`${JSON.stringify(status)}
|
|
@@ -44422,14 +45083,14 @@ async function writeLocalStatus(status, root = defaultLocalObservabilityRoot())
|
|
|
44422
45083
|
} finally {
|
|
44423
45084
|
await handle.close();
|
|
44424
45085
|
}
|
|
44425
|
-
await
|
|
45086
|
+
await rename13(temporary, destination);
|
|
44426
45087
|
} catch {
|
|
44427
|
-
await
|
|
45088
|
+
await rm17(temporary, { force: true }).catch(() => void 0);
|
|
44428
45089
|
}
|
|
44429
45090
|
}
|
|
44430
45091
|
|
|
44431
45092
|
// src/demo-state.ts
|
|
44432
|
-
import { isAbsolute as isAbsolute19, join as
|
|
45093
|
+
import { isAbsolute as isAbsolute19, join as join29, parse as parse3, resolve as resolve18 } from "node:path";
|
|
44433
45094
|
var DEMO_STATE_ROOT_ENV = "ZIXT_DEMO_STATE_ROOT";
|
|
44434
45095
|
function resolveDemoHostStatePaths(env = process.env) {
|
|
44435
45096
|
const configured = env.ZIXT_RUNNER === "demo" ? env[DEMO_STATE_ROOT_ENV] : void 0;
|
|
@@ -44439,14 +45100,14 @@ function resolveDemoHostStatePaths(env = process.env) {
|
|
|
44439
45100
|
throw new Error(`${DEMO_STATE_ROOT_ENV} must be a dedicated absolute directory`);
|
|
44440
45101
|
}
|
|
44441
45102
|
return {
|
|
44442
|
-
runRegistryRoot:
|
|
44443
|
-
terminalOutcomeRoot:
|
|
44444
|
-
acceptedAssignmentRoot:
|
|
44445
|
-
runArtifactRoot:
|
|
44446
|
-
browserProfileRoot:
|
|
44447
|
-
runnerWorkspaceRoot:
|
|
44448
|
-
codexThreadIndexRoot:
|
|
44449
|
-
localObservabilityRoot:
|
|
45103
|
+
runRegistryRoot: join29(root, "run-registry"),
|
|
45104
|
+
terminalOutcomeRoot: join29(root, "terminal-outcomes"),
|
|
45105
|
+
acceptedAssignmentRoot: join29(root, "accepted-assignments"),
|
|
45106
|
+
runArtifactRoot: join29(root, "run-artifacts"),
|
|
45107
|
+
browserProfileRoot: join29(root, "browser-profiles"),
|
|
45108
|
+
runnerWorkspaceRoot: join29(root, "workspaces"),
|
|
45109
|
+
codexThreadIndexRoot: join29(root, "codex-threads"),
|
|
45110
|
+
localObservabilityRoot: join29(root, "local-observability")
|
|
44450
45111
|
};
|
|
44451
45112
|
}
|
|
44452
45113
|
|