@codexhost/cli-win32-arm64 0.6.0 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/app/codexhost-distribution.json +1 -1
- package/app/desktop-controller.mjs +2 -1
- package/app/host-runtime.mjs +296 -147
- package/app/plugins/antigravity/plugin.mjs +6 -1
- package/app/plugins/claude-code/plugin.mjs +661 -219
- package/app/plugins/deepseek-harness/plugin.mjs +87 -18
- package/app/plugins/enabled.json +2 -1
- package/app/plugins/grok/plugin.mjs +11 -1
- package/app/plugins/kiro-cli/assets/icon.svg +5 -0
- package/app/plugins/kiro-cli/manifest.json +12 -0
- package/app/plugins/kiro-cli/plugin.mjs +23316 -0
- package/app/plugins/omp/plugin.mjs +11 -1
- package/app/plugins/opencode/plugin.mjs +297 -143
- package/app/plugins/pi/plugin.mjs +1489 -1300
- package/app/renderer-extension.js +152 -84
- package/bin/codexhost.exe +0 -0
- package/libexec/codexhost-node-repl.exe +0 -0
- package/libexec/codexhost-shim.exe +0 -0
- package/libexec/codexhost-updater.exe +0 -0
- package/package.json +1 -1
package/app/host-runtime.mjs
CHANGED
|
@@ -4083,7 +4083,8 @@ async function runDelegationCli(input) {
|
|
|
4083
4083
|
|
|
4084
4084
|
// packages/host-runtime/src/run-host-runtime.ts
|
|
4085
4085
|
import { randomBytes } from "node:crypto";
|
|
4086
|
-
import
|
|
4086
|
+
import path20 from "node:path";
|
|
4087
|
+
import { homedir } from "node:os";
|
|
4087
4088
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
4088
4089
|
|
|
4089
4090
|
// packages/update-manager/dist/distribution.js
|
|
@@ -5701,10 +5702,10 @@ function mergeDefs(...defs) {
|
|
|
5701
5702
|
function cloneDef(schema) {
|
|
5702
5703
|
return mergeDefs(schema._zod.def);
|
|
5703
5704
|
}
|
|
5704
|
-
function getElementAtPath(obj,
|
|
5705
|
-
if (!
|
|
5705
|
+
function getElementAtPath(obj, path25) {
|
|
5706
|
+
if (!path25)
|
|
5706
5707
|
return obj;
|
|
5707
|
-
return
|
|
5708
|
+
return path25.reduce((acc, key) => acc?.[key], obj);
|
|
5708
5709
|
}
|
|
5709
5710
|
function promiseAllObject(promisesObj) {
|
|
5710
5711
|
const keys = Object.keys(promisesObj);
|
|
@@ -6113,11 +6114,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
6113
6114
|
}
|
|
6114
6115
|
return false;
|
|
6115
6116
|
}
|
|
6116
|
-
function prefixIssues(
|
|
6117
|
+
function prefixIssues(path25, issues) {
|
|
6117
6118
|
return issues.map((iss) => {
|
|
6118
6119
|
var _a3;
|
|
6119
6120
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
6120
|
-
iss.path.unshift(
|
|
6121
|
+
iss.path.unshift(path25);
|
|
6121
6122
|
return iss;
|
|
6122
6123
|
});
|
|
6123
6124
|
}
|
|
@@ -6264,16 +6265,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
|
|
|
6264
6265
|
}
|
|
6265
6266
|
function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
6266
6267
|
const fieldErrors = { _errors: [] };
|
|
6267
|
-
const processError = (error52,
|
|
6268
|
+
const processError = (error52, path25 = []) => {
|
|
6268
6269
|
for (const issue2 of error52.issues) {
|
|
6269
6270
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
6270
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
6271
|
+
issue2.errors.map((issues) => processError({ issues }, [...path25, ...issue2.path]));
|
|
6271
6272
|
} else if (issue2.code === "invalid_key") {
|
|
6272
|
-
processError({ issues: issue2.issues }, [...
|
|
6273
|
+
processError({ issues: issue2.issues }, [...path25, ...issue2.path]);
|
|
6273
6274
|
} else if (issue2.code === "invalid_element") {
|
|
6274
|
-
processError({ issues: issue2.issues }, [...
|
|
6275
|
+
processError({ issues: issue2.issues }, [...path25, ...issue2.path]);
|
|
6275
6276
|
} else {
|
|
6276
|
-
const fullpath = [...
|
|
6277
|
+
const fullpath = [...path25, ...issue2.path];
|
|
6277
6278
|
if (fullpath.length === 0) {
|
|
6278
6279
|
fieldErrors._errors.push(mapper(issue2));
|
|
6279
6280
|
} else {
|
|
@@ -6300,17 +6301,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
|
6300
6301
|
}
|
|
6301
6302
|
function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
6302
6303
|
const result = { errors: [] };
|
|
6303
|
-
const processError = (error52,
|
|
6304
|
+
const processError = (error52, path25 = []) => {
|
|
6304
6305
|
var _a3, _b;
|
|
6305
6306
|
for (const issue2 of error52.issues) {
|
|
6306
6307
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
6307
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
6308
|
+
issue2.errors.map((issues) => processError({ issues }, [...path25, ...issue2.path]));
|
|
6308
6309
|
} else if (issue2.code === "invalid_key") {
|
|
6309
|
-
processError({ issues: issue2.issues }, [...
|
|
6310
|
+
processError({ issues: issue2.issues }, [...path25, ...issue2.path]);
|
|
6310
6311
|
} else if (issue2.code === "invalid_element") {
|
|
6311
|
-
processError({ issues: issue2.issues }, [...
|
|
6312
|
+
processError({ issues: issue2.issues }, [...path25, ...issue2.path]);
|
|
6312
6313
|
} else {
|
|
6313
|
-
const fullpath = [...
|
|
6314
|
+
const fullpath = [...path25, ...issue2.path];
|
|
6314
6315
|
if (fullpath.length === 0) {
|
|
6315
6316
|
result.errors.push(mapper(issue2));
|
|
6316
6317
|
continue;
|
|
@@ -6342,8 +6343,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
|
6342
6343
|
}
|
|
6343
6344
|
function toDotPath(_path) {
|
|
6344
6345
|
const segs = [];
|
|
6345
|
-
const
|
|
6346
|
-
for (const seg of
|
|
6346
|
+
const path25 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
6347
|
+
for (const seg of path25) {
|
|
6347
6348
|
if (typeof seg === "number")
|
|
6348
6349
|
segs.push(`[${seg}]`);
|
|
6349
6350
|
else if (typeof seg === "symbol")
|
|
@@ -19035,13 +19036,13 @@ function resolveRef(ref, ctx) {
|
|
|
19035
19036
|
if (!ref.startsWith("#")) {
|
|
19036
19037
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
19037
19038
|
}
|
|
19038
|
-
const
|
|
19039
|
-
if (
|
|
19039
|
+
const path25 = ref.slice(1).split("/").filter(Boolean);
|
|
19040
|
+
if (path25.length === 0) {
|
|
19040
19041
|
return ctx.rootSchema;
|
|
19041
19042
|
}
|
|
19042
19043
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
19043
|
-
if (
|
|
19044
|
-
const key =
|
|
19044
|
+
if (path25[0] === defsKey) {
|
|
19045
|
+
const key = path25[1];
|
|
19045
19046
|
if (!key || !ctx.defs[key]) {
|
|
19046
19047
|
throw new Error(`Reference not found: ${ref}`);
|
|
19047
19048
|
}
|
|
@@ -19475,6 +19476,8 @@ var threadUsageSnapshotSchema = external_exports.object({
|
|
|
19475
19476
|
reasoningOutputTokens: nonNegativeSafeIntegerSchema.optional(),
|
|
19476
19477
|
totalTokens: nonNegativeSafeIntegerSchema.optional(),
|
|
19477
19478
|
totalCostUsd: finiteNonNegativeNumberSchema.optional(),
|
|
19479
|
+
totalCredits: finiteNonNegativeNumberSchema.optional(),
|
|
19480
|
+
contextUsagePercent: finiteNonNegativeNumberSchema.optional(),
|
|
19478
19481
|
cacheHitRatePercent: cacheHitRatePercentSchema.optional(),
|
|
19479
19482
|
contextWindowTokens: nonNegativeSafeIntegerSchema.optional(),
|
|
19480
19483
|
contextUsedTokens: nonNegativeSafeIntegerSchema.optional(),
|
|
@@ -20386,7 +20389,9 @@ var usageFields = /* @__PURE__ */ new Set([
|
|
|
20386
20389
|
...tokenFields,
|
|
20387
20390
|
...safeIntegerFields,
|
|
20388
20391
|
...percentFields,
|
|
20389
|
-
"totalCostUsd"
|
|
20392
|
+
"totalCostUsd",
|
|
20393
|
+
"totalCredits",
|
|
20394
|
+
"contextUsagePercent"
|
|
20390
20395
|
]);
|
|
20391
20396
|
function isRecord(value2) {
|
|
20392
20397
|
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
@@ -20402,6 +20407,12 @@ function parseHostUsage(value2) {
|
|
|
20402
20407
|
throw new Error(`Harness Usage contains unknown field '${key}'`);
|
|
20403
20408
|
}
|
|
20404
20409
|
}
|
|
20410
|
+
for (const field of ["totalCredits", "contextUsagePercent"]) {
|
|
20411
|
+
const candidate = value2[field];
|
|
20412
|
+
if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isFinite(candidate) || candidate < 0)) {
|
|
20413
|
+
throw new Error(`Harness Usage '${field}' must be a finite non-negative number`);
|
|
20414
|
+
}
|
|
20415
|
+
}
|
|
20405
20416
|
for (const field of tokenFields) {
|
|
20406
20417
|
const candidate = value2[field];
|
|
20407
20418
|
if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isSafeInteger(candidate) || candidate < 0)) {
|
|
@@ -20726,7 +20737,7 @@ var MappingStore = class {
|
|
|
20726
20737
|
]);
|
|
20727
20738
|
await this.#acquireLock();
|
|
20728
20739
|
try {
|
|
20729
|
-
await this.#
|
|
20740
|
+
await this.#cleanupResidue();
|
|
20730
20741
|
const names = (await readdir2(this.#threadsDirectory)).filter((name) => name.endsWith(".json"));
|
|
20731
20742
|
for (const name of names) {
|
|
20732
20743
|
const primary = path4.join(this.#threadsDirectory, name);
|
|
@@ -21150,14 +21161,17 @@ var MappingStore = class {
|
|
|
21150
21161
|
}
|
|
21151
21162
|
return parsed.data;
|
|
21152
21163
|
}
|
|
21153
|
-
async #
|
|
21154
|
-
const [threadNames, delegationNames] = await Promise.all([
|
|
21164
|
+
async #cleanupResidue() {
|
|
21165
|
+
const [threadNames, delegationNames, rootNames] = await Promise.all([
|
|
21155
21166
|
readdir2(this.#threadsDirectory),
|
|
21156
|
-
readdir2(this.#delegationsDirectory)
|
|
21167
|
+
readdir2(this.#delegationsDirectory),
|
|
21168
|
+
readdir2(this.#directory)
|
|
21157
21169
|
]);
|
|
21158
21170
|
await Promise.all([
|
|
21159
21171
|
...threadNames.filter((name) => name.includes(".tmp-")).map((name) => rm3(path4.join(this.#threadsDirectory, name), { force: true })),
|
|
21160
|
-
...delegationNames.filter((name) => name.includes(".tmp-")).map((name) => rm3(path4.join(this.#delegationsDirectory, name), { force: true }))
|
|
21172
|
+
...delegationNames.filter((name) => name.includes(".tmp-")).map((name) => rm3(path4.join(this.#delegationsDirectory, name), { force: true })),
|
|
21173
|
+
// Renamed aside by #acquireLock; nothing reads them back, and they accumulate one per run.
|
|
21174
|
+
...rootNames.filter((name) => name.startsWith(`${path4.basename(this.#lockPath)}.stale-`)).map((name) => rm3(path4.join(this.#directory, name), { force: true }))
|
|
21161
21175
|
]);
|
|
21162
21176
|
}
|
|
21163
21177
|
async #acquireLock() {
|
|
@@ -21349,6 +21363,9 @@ function projectCodexApprovalRequest(input) {
|
|
|
21349
21363
|
throw new Error("Host Approval subject is unsupported");
|
|
21350
21364
|
}
|
|
21351
21365
|
validateActions(interaction);
|
|
21366
|
+
if (new Set(interaction.actions.map(({ effect }) => effect)).size !== interaction.actions.length) {
|
|
21367
|
+
return projectApprovalChoices(input);
|
|
21368
|
+
}
|
|
21352
21369
|
const allow = requiredActionForEffect(interaction, "allowOnce");
|
|
21353
21370
|
const allowForSession = optionalActionForEffect(interaction, "allowForSession");
|
|
21354
21371
|
const allowAlways = optionalActionForEffect(interaction, "allowAlways");
|
|
@@ -21414,6 +21431,63 @@ function projectCodexApprovalRequest(input) {
|
|
|
21414
21431
|
}
|
|
21415
21432
|
};
|
|
21416
21433
|
}
|
|
21434
|
+
function projectApprovalChoices(input) {
|
|
21435
|
+
const { interaction } = input;
|
|
21436
|
+
const allow = actionsForEffect(interaction, "allowOnce")[0];
|
|
21437
|
+
const deny = actionsForEffect(interaction, "deny")[0];
|
|
21438
|
+
if (!allow || !deny)
|
|
21439
|
+
throw new Error("Host Approval must declare allowOnce and deny actions");
|
|
21440
|
+
const denyResponse = { type: "approval", actionId: deny.id };
|
|
21441
|
+
return {
|
|
21442
|
+
request: {
|
|
21443
|
+
method: "mcpServer/elicitation/request",
|
|
21444
|
+
params: {
|
|
21445
|
+
serverName: boundedText(input.serverName, "server name", SERVER_NAME_MAX_LENGTH),
|
|
21446
|
+
threadId: input.threadId,
|
|
21447
|
+
turnId: interaction.turnId,
|
|
21448
|
+
mode: "form",
|
|
21449
|
+
message: [
|
|
21450
|
+
clampedText(interaction.title, "title", TITLE_MAX_LENGTH),
|
|
21451
|
+
...interaction.description ? [interaction.description] : []
|
|
21452
|
+
].join("\n\n"),
|
|
21453
|
+
requestedSchema: {
|
|
21454
|
+
type: "object",
|
|
21455
|
+
properties: {
|
|
21456
|
+
actionId: {
|
|
21457
|
+
type: "string",
|
|
21458
|
+
title: "Approval",
|
|
21459
|
+
oneOf: interaction.actions.map(({ id: id2, label }) => ({ const: id2, title: label })),
|
|
21460
|
+
default: allow.id
|
|
21461
|
+
}
|
|
21462
|
+
},
|
|
21463
|
+
required: ["actionId"]
|
|
21464
|
+
}
|
|
21465
|
+
}
|
|
21466
|
+
},
|
|
21467
|
+
denyResponse,
|
|
21468
|
+
parseResponse(result) {
|
|
21469
|
+
if (!isRecord2(result) || typeof result.action !== "string")
|
|
21470
|
+
throw responseError("missing action");
|
|
21471
|
+
if (Object.keys(result).some((key) => !["action", "content", "_meta"].includes(key))) {
|
|
21472
|
+
throw responseError("contains unreviewed fields");
|
|
21473
|
+
}
|
|
21474
|
+
if (result._meta !== void 0 && result._meta !== null) {
|
|
21475
|
+
throw responseError("contains unexpected persist metadata");
|
|
21476
|
+
}
|
|
21477
|
+
if (result.action === "decline" || result.action === "cancel") {
|
|
21478
|
+
if (result.content !== void 0 && result.content !== null) {
|
|
21479
|
+
throw responseError("contains fields incompatible with denial");
|
|
21480
|
+
}
|
|
21481
|
+
return denyResponse;
|
|
21482
|
+
}
|
|
21483
|
+
const content = result.content;
|
|
21484
|
+
if (result.action !== "accept" || !isRecord2(content) || Object.keys(content).length !== 1 || !interaction.actions.some(({ id: id2 }) => id2 === content.actionId)) {
|
|
21485
|
+
throw responseError("contains an undeclared approval choice");
|
|
21486
|
+
}
|
|
21487
|
+
return { type: "approval", actionId: content.actionId };
|
|
21488
|
+
}
|
|
21489
|
+
};
|
|
21490
|
+
}
|
|
21417
21491
|
|
|
21418
21492
|
// packages/protocol-core/dist/codex-question.js
|
|
21419
21493
|
function isRecord3(value2) {
|
|
@@ -21957,8 +22031,8 @@ function projectFileChangeKind(kind) {
|
|
|
21957
22031
|
return { type: kind };
|
|
21958
22032
|
}
|
|
21959
22033
|
function projectFileChanges(changes) {
|
|
21960
|
-
return changes.map(({ path:
|
|
21961
|
-
path:
|
|
22034
|
+
return changes.map(({ path: path25, kind, unifiedDiff }) => ({
|
|
22035
|
+
path: path25,
|
|
21962
22036
|
kind: projectFileChangeKind(kind),
|
|
21963
22037
|
diff: unifiedDiff
|
|
21964
22038
|
}));
|
|
@@ -22116,7 +22190,7 @@ function projectItem(item, outcome, defaultCwd, includeCommandOutput = true, sen
|
|
|
22116
22190
|
id: item.itemId,
|
|
22117
22191
|
type: "agentMessage",
|
|
22118
22192
|
text: item.text,
|
|
22119
|
-
phase: null,
|
|
22193
|
+
phase: item.phase ?? null,
|
|
22120
22194
|
memoryCitation: null
|
|
22121
22195
|
};
|
|
22122
22196
|
case "reasoning":
|
|
@@ -22238,6 +22312,9 @@ function historicalStatus(outcome) {
|
|
|
22238
22312
|
}
|
|
22239
22313
|
function projectHistoricalTurn(input) {
|
|
22240
22314
|
const { turnId, cwd, snapshot } = input;
|
|
22315
|
+
const startedAtMs = snapshot.startedAtMs;
|
|
22316
|
+
const completedAtMs = snapshot.completedAtMs;
|
|
22317
|
+
const hasTiming = startedAtMs !== void 0 && completedAtMs !== void 0 && Number.isFinite(startedAtMs) && Number.isFinite(completedAtMs) && startedAtMs >= 0 && completedAtMs >= startedAtMs;
|
|
22241
22318
|
const error51 = snapshot.outcome.status === "failed" ? {
|
|
22242
22319
|
message: snapshot.outcome.error.message,
|
|
22243
22320
|
codexErrorInfo: "other",
|
|
@@ -22273,9 +22350,9 @@ function projectHistoricalTurn(input) {
|
|
|
22273
22350
|
})
|
|
22274
22351
|
],
|
|
22275
22352
|
error: error51,
|
|
22276
|
-
startedAt: null,
|
|
22277
|
-
completedAt: null,
|
|
22278
|
-
durationMs: null,
|
|
22353
|
+
startedAt: hasTiming ? Math.floor(startedAtMs / 1e3) : null,
|
|
22354
|
+
completedAt: hasTiming ? Math.floor(completedAtMs / 1e3) : null,
|
|
22355
|
+
durationMs: hasTiming ? completedAtMs - startedAtMs : null,
|
|
22279
22356
|
itemsView: "full"
|
|
22280
22357
|
};
|
|
22281
22358
|
}
|
|
@@ -22901,13 +22978,13 @@ function decodeThreadForkRequest(request) {
|
|
|
22901
22978
|
if (runtimeWorkspaceRoots !== void 0 && runtimeWorkspaceRoots !== null && (!Array.isArray(runtimeWorkspaceRoots) || runtimeWorkspaceRoots.some((root) => typeof root !== "string" || root.length === 0))) {
|
|
22902
22979
|
throw new Error("thread/fork params.runtimeWorkspaceRoots must be text paths or null");
|
|
22903
22980
|
}
|
|
22904
|
-
const
|
|
22981
|
+
const path25 = optionalText(params, "path", { allowEmpty: true });
|
|
22905
22982
|
const ephemeral = optionalBoolean(params, "ephemeral");
|
|
22906
22983
|
return {
|
|
22907
22984
|
threadId: threadId3,
|
|
22908
22985
|
...lastTurnText ? { lastTurnId: hostTurnIdSchema.parse(lastTurnText) } : {},
|
|
22909
22986
|
...beforeTurnText ? { beforeTurnId: hostTurnIdSchema.parse(beforeTurnText) } : {},
|
|
22910
|
-
...
|
|
22987
|
+
...path25 ? { path: path25 } : {},
|
|
22911
22988
|
...optionalField(params, "model"),
|
|
22912
22989
|
...optionalField(params, "modelProvider"),
|
|
22913
22990
|
...optionalField(params, "cwd"),
|
|
@@ -24862,6 +24939,7 @@ async function executeCurrentLastTurnRollback(input) {
|
|
|
24862
24939
|
error: { code: -32079, message: "External Native Session is unavailable" }
|
|
24863
24940
|
};
|
|
24864
24941
|
}
|
|
24942
|
+
const configuration = currentConfiguration(current);
|
|
24865
24943
|
let opened;
|
|
24866
24944
|
try {
|
|
24867
24945
|
opened = await adapter.open({
|
|
@@ -24871,7 +24949,10 @@ async function executeCurrentLastTurnRollback(input) {
|
|
|
24871
24949
|
...input.environment ?? process.env,
|
|
24872
24950
|
[DELEGATION_THREAD_ID_ENV]: current.id
|
|
24873
24951
|
},
|
|
24874
|
-
sourceRef: currentNativeRef
|
|
24952
|
+
sourceRef: currentNativeRef,
|
|
24953
|
+
...configuration.effectiveModel ? { model: configuration.effectiveModel } : {},
|
|
24954
|
+
...configuration.effectiveThinkingOptionId ? { thinkingOptionId: configuration.effectiveThinkingOptionId } : {},
|
|
24955
|
+
...configuration.effectivePermissionModeId ? { permissionModeId: configuration.effectivePermissionModeId } : {}
|
|
24875
24956
|
});
|
|
24876
24957
|
} catch {
|
|
24877
24958
|
return { ok: false, error: { code: -32076, message: "External Thread rollback failed" } };
|
|
@@ -24888,7 +24969,6 @@ async function executeCurrentLastTurnRollback(input) {
|
|
|
24888
24969
|
error: { code: -32076, message: "External rollback did not return a valid Session" }
|
|
24889
24970
|
};
|
|
24890
24971
|
}
|
|
24891
|
-
const configuration = currentConfiguration(current);
|
|
24892
24972
|
const configurationError = await restoreCurrentConfiguration(session, configuration);
|
|
24893
24973
|
if (configurationError) {
|
|
24894
24974
|
await session.close().catch(() => void 0);
|
|
@@ -25460,6 +25540,8 @@ var ExternalThreadRuntime = class {
|
|
|
25460
25540
|
environment: { ...this.#environment, [DELEGATION_THREAD_ID_ENV]: record3.hostThreadId },
|
|
25461
25541
|
nativeRef: record3.nativeSessionRef,
|
|
25462
25542
|
knownTurnRefs: record3.turnMappings.map(({ nativeTurnRef }) => nativeTurnRef),
|
|
25543
|
+
...restoredSelection?.model ? { model: restoredSelection.model } : {},
|
|
25544
|
+
...restoredSelection?.thinkingOptionId ? { thinkingOptionId: restoredSelection.thinkingOptionId } : {},
|
|
25463
25545
|
...harnessId === "grok" && restoredSelection?.permissionModeId ? { permissionModeId: restoredSelection.permissionModeId } : {}
|
|
25464
25546
|
});
|
|
25465
25547
|
if (!opened.ok) {
|
|
@@ -27355,25 +27437,25 @@ function resolveExternalSessionTreeIds(records) {
|
|
|
27355
27437
|
const resolve = (start) => {
|
|
27356
27438
|
const cached2 = resolved.get(start.hostThreadId);
|
|
27357
27439
|
if (cached2) return cached2;
|
|
27358
|
-
const
|
|
27440
|
+
const path25 = [];
|
|
27359
27441
|
const visited = /* @__PURE__ */ new Set();
|
|
27360
27442
|
let current = start;
|
|
27361
27443
|
while (true) {
|
|
27362
27444
|
const known = resolved.get(current.hostThreadId);
|
|
27363
27445
|
if (known) {
|
|
27364
|
-
for (const record3 of
|
|
27446
|
+
for (const record3 of path25) resolved.set(record3.hostThreadId, known);
|
|
27365
27447
|
return known;
|
|
27366
27448
|
}
|
|
27367
27449
|
if (visited.has(current.hostThreadId)) {
|
|
27368
27450
|
throw new Error("External Thread Fork tree contains a cycle");
|
|
27369
27451
|
}
|
|
27370
27452
|
visited.add(current.hostThreadId);
|
|
27371
|
-
|
|
27453
|
+
path25.push(current);
|
|
27372
27454
|
const sourceId = current.forkSource?.hostThreadId;
|
|
27373
27455
|
const source = sourceId ? byId.get(sourceId) : void 0;
|
|
27374
27456
|
if (!source) {
|
|
27375
27457
|
const root = current.hostThreadId;
|
|
27376
|
-
for (const record3 of
|
|
27458
|
+
for (const record3 of path25) resolved.set(record3.hostThreadId, root);
|
|
27377
27459
|
return root;
|
|
27378
27460
|
}
|
|
27379
27461
|
current = source;
|
|
@@ -27914,6 +27996,8 @@ function approvalServerName(harnessId) {
|
|
|
27914
27996
|
return "Oh My Pi";
|
|
27915
27997
|
case "antigravity":
|
|
27916
27998
|
return "Antigravity CLI";
|
|
27999
|
+
case "kiro-cli":
|
|
28000
|
+
return "Kiro CLI";
|
|
27917
28001
|
default:
|
|
27918
28002
|
return harnessId;
|
|
27919
28003
|
}
|
|
@@ -31523,6 +31607,40 @@ var AppServerHost = class {
|
|
|
31523
31607
|
}
|
|
31524
31608
|
};
|
|
31525
31609
|
|
|
31610
|
+
// packages/host-runtime/src/codex-runtime/account-official-listeners.ts
|
|
31611
|
+
import path12 from "node:path";
|
|
31612
|
+
var AccountOfficialListeners = class {
|
|
31613
|
+
constructor(createListener) {
|
|
31614
|
+
this.createListener = createListener;
|
|
31615
|
+
}
|
|
31616
|
+
createListener;
|
|
31617
|
+
#listeners = /* @__PURE__ */ new Map();
|
|
31618
|
+
#starting = /* @__PURE__ */ new Map();
|
|
31619
|
+
#closed = false;
|
|
31620
|
+
async endpoint(account) {
|
|
31621
|
+
if (this.#closed) throw new Error("Account official listeners are closed");
|
|
31622
|
+
const key = path12.resolve(account.codexHome);
|
|
31623
|
+
const existing = this.#starting.get(key);
|
|
31624
|
+
if (existing) return existing;
|
|
31625
|
+
const listener = this.createListener(account);
|
|
31626
|
+
this.#listeners.set(key, listener);
|
|
31627
|
+
const starting = listener.listen().catch(async (error51) => {
|
|
31628
|
+
await listener.close();
|
|
31629
|
+
this.#listeners.delete(key);
|
|
31630
|
+
this.#starting.delete(key);
|
|
31631
|
+
throw error51;
|
|
31632
|
+
});
|
|
31633
|
+
this.#starting.set(key, starting);
|
|
31634
|
+
return starting;
|
|
31635
|
+
}
|
|
31636
|
+
async close() {
|
|
31637
|
+
this.#closed = true;
|
|
31638
|
+
await Promise.all([...this.#listeners.values()].map((listener) => listener.close()));
|
|
31639
|
+
this.#listeners.clear();
|
|
31640
|
+
this.#starting.clear();
|
|
31641
|
+
}
|
|
31642
|
+
};
|
|
31643
|
+
|
|
31526
31644
|
// packages/host-runtime/src/delegation-control-registry.ts
|
|
31527
31645
|
function only(values, message) {
|
|
31528
31646
|
const value2 = values.length === 1 ? values[0] : void 0;
|
|
@@ -31591,9 +31709,28 @@ var DelegationControlRegistry = class {
|
|
|
31591
31709
|
);
|
|
31592
31710
|
}
|
|
31593
31711
|
async #registrationForThread(threadId3) {
|
|
31594
|
-
|
|
31595
|
-
|
|
31596
|
-
|
|
31712
|
+
const registrations = [...this.#registrations];
|
|
31713
|
+
const matches = await this.#matching((registration) => registration.ownsThread(threadId3));
|
|
31714
|
+
if (matches.length === 1) return matches[0];
|
|
31715
|
+
if (matches.length > 1) {
|
|
31716
|
+
throw new DelegationControlError(
|
|
31717
|
+
"PARENT_THREAD_AMBIGUOUS",
|
|
31718
|
+
"Thread is not owned by exactly one active Host Runtime session",
|
|
31719
|
+
{ matchingRuntimeCount: matches.length }
|
|
31720
|
+
);
|
|
31721
|
+
}
|
|
31722
|
+
if (registrations.length === 0) {
|
|
31723
|
+
throw new DelegationControlError(
|
|
31724
|
+
"PARENT_THREAD_AMBIGUOUS",
|
|
31725
|
+
"Thread is not owned by exactly one active Host Runtime session",
|
|
31726
|
+
{ matchingRuntimeCount: 0 }
|
|
31727
|
+
);
|
|
31728
|
+
}
|
|
31729
|
+
if (registrations.length === 1) return registrations[0];
|
|
31730
|
+
throw new DelegationControlError(
|
|
31731
|
+
"PARENT_THREAD_AMBIGUOUS",
|
|
31732
|
+
"Thread is not owned by exactly one active Host Runtime session",
|
|
31733
|
+
{ matchingRuntimeCount: 0 }
|
|
31597
31734
|
);
|
|
31598
31735
|
}
|
|
31599
31736
|
#compareThreads(left, right, sort) {
|
|
@@ -31612,17 +31749,17 @@ var DelegationControlRegistry = class {
|
|
|
31612
31749
|
|
|
31613
31750
|
// packages/host-runtime/src/installed-harness-plugins.ts
|
|
31614
31751
|
import os3 from "node:os";
|
|
31615
|
-
import
|
|
31752
|
+
import path14 from "node:path";
|
|
31616
31753
|
import { fileURLToPath } from "node:url";
|
|
31617
31754
|
|
|
31618
31755
|
// packages/host-runtime/src/launcher-url-opener.ts
|
|
31619
31756
|
import { spawn as spawn3 } from "node:child_process";
|
|
31620
|
-
import
|
|
31757
|
+
import path13 from "node:path";
|
|
31621
31758
|
var LOOPBACK_HOSTS = /* @__PURE__ */ new Set(["127.0.0.1", "localhost", "[::1]"]);
|
|
31622
31759
|
var OPEN_TIMEOUT_MS = 1e4;
|
|
31623
31760
|
function createLauncherUrlOpener(environment, spawnLauncher = (command, arguments_2, options2) => spawn3(command, arguments_2, options2)) {
|
|
31624
31761
|
const launcher = environment.CODEXHOST_LAUNCHER_EXECUTABLE;
|
|
31625
|
-
if (!launcher || !
|
|
31762
|
+
if (!launcher || !path13.isAbsolute(launcher)) return void 0;
|
|
31626
31763
|
const launcherEnvironment = Object.fromEntries(
|
|
31627
31764
|
Object.entries(environment).filter(([name]) => {
|
|
31628
31765
|
const normalized = name.toUpperCase();
|
|
@@ -31680,9 +31817,9 @@ function installedHarnessPluginOptions(environment, managedRemoteHost = false, h
|
|
|
31680
31817
|
const opener = managedRemoteHost ? void 0 : createLauncherUrlOpener(environment);
|
|
31681
31818
|
return {
|
|
31682
31819
|
pluginRoots: [
|
|
31683
|
-
|
|
31684
|
-
environment[HARNESS_PLUGIN_DIRECTORY_ENV] ??
|
|
31685
|
-
environment.CODEXHOST_DATA_DIR ?
|
|
31820
|
+
path14.join(path14.dirname(fileURLToPath(hostRuntimeUrl)), "plugins"),
|
|
31821
|
+
environment[HARNESS_PLUGIN_DIRECTORY_ENV] ?? path14.join(
|
|
31822
|
+
environment.CODEXHOST_DATA_DIR ? path14.resolve(environment.CODEXHOST_DATA_DIR) : path14.join(os3.homedir(), ".codexhost"),
|
|
31686
31823
|
"plugins"
|
|
31687
31824
|
)
|
|
31688
31825
|
],
|
|
@@ -31807,10 +31944,11 @@ async function startDelegationControlServer(input) {
|
|
|
31807
31944
|
import { createHash as createHash6, randomUUID as randomUUID9 } from "node:crypto";
|
|
31808
31945
|
import { mkdir as mkdir7, open as open5, readFile as readFile7, rename as rename5, rm as rm5, stat as stat3 } from "node:fs/promises";
|
|
31809
31946
|
import os4 from "node:os";
|
|
31810
|
-
import
|
|
31811
|
-
var SKILL_VERSION =
|
|
31812
|
-
var SKILL_RELATIVE_PATH =
|
|
31947
|
+
import path15 from "node:path";
|
|
31948
|
+
var SKILL_VERSION = 5;
|
|
31949
|
+
var SKILL_RELATIVE_PATH = path15.join("skills", "codexhost-delegation", "SKILL.md");
|
|
31813
31950
|
var PREVIOUS_MANAGED_DIGESTS = [
|
|
31951
|
+
"aff258622dc8ff321f32b15620d081e578cb9c9ed1134d6a57f35ca8e7762c0a",
|
|
31814
31952
|
"ba509f57e5448e796b3dfdd5031dcb08672eded50b61c0a54de84cfa02c49dd3",
|
|
31815
31953
|
"d3ddf6db9bc5c5df825479c885bbbf0ca08da66f7057a12e02e1fdf57525149e",
|
|
31816
31954
|
"15eb63519ff867e1536c97188a0c43738d7a49d38d4d6adeb7a1036726e7246d"
|
|
@@ -31819,12 +31957,12 @@ var CODEXHOST_DELEGATION_SKILL = `---
|
|
|
31819
31957
|
name: codexhost-delegation
|
|
31820
31958
|
version: ${SKILL_VERSION}
|
|
31821
31959
|
description: >
|
|
31822
|
-
Delegate
|
|
31823
|
-
|
|
31824
|
-
|
|
31825
|
-
|
|
31826
|
-
|
|
31827
|
-
|
|
31960
|
+
Delegate tasks to other coding agents, or read and follow up on existing
|
|
31961
|
+
external agent sessions. Use when the user asks another agent (including
|
|
31962
|
+
@agent) to independently perform a task, or asks to view a specified external
|
|
31963
|
+
session's content, progress, or results, send follow-up messages, wait, or
|
|
31964
|
+
cancel a task. Not for recapping the current conversation, discussing or
|
|
31965
|
+
configuring agents, or role-playing.
|
|
31828
31966
|
---
|
|
31829
31967
|
|
|
31830
31968
|
# Execute the task
|
|
@@ -31849,9 +31987,14 @@ When the user asks for a specific Model or Thinking level, inspect the target
|
|
|
31849
31987
|
Harness first and use the exact opaque IDs returned by the authoritative CLI.
|
|
31850
31988
|
When they do not specify either setting, omit it so the target keeps its default.
|
|
31851
31989
|
|
|
31852
|
-
|
|
31990
|
+
For a new delegation, create an independent child session and submit the
|
|
31991
|
+
requested task. For an existing external session, resolve the target from the
|
|
31992
|
+
user-provided session link, identifier, or context and operate on that Thread
|
|
31993
|
+
directly; it need not have been created by the current assistant. If the target
|
|
31994
|
+
is ambiguous, ask the user to identify it. Keep requests to view or summarize a
|
|
31995
|
+
session read-only.
|
|
31853
31996
|
|
|
31854
|
-
|
|
31997
|
+
For a new or existing task, choose the appropriate next action based on the
|
|
31855
31998
|
user’s request and the task:
|
|
31856
31999
|
|
|
31857
32000
|
- send a follow-up message to the same Thread;
|
|
@@ -31861,10 +32004,11 @@ user’s request and the task:
|
|
|
31861
32004
|
- check it again later;
|
|
31862
32005
|
- leave it running in the background.
|
|
31863
32006
|
|
|
31864
|
-
When the result is needed, explicitly read the
|
|
32007
|
+
When the result is needed, explicitly read the target Thread. Report only the
|
|
31865
32008
|
visible result returned by that Thread.
|
|
31866
32009
|
|
|
31867
|
-
Provide the user with the necessary tracking information
|
|
32010
|
+
Provide the user with the necessary tracking information available from the
|
|
32011
|
+
CLI; omit unavailable fields rather than inventing them:
|
|
31868
32012
|
|
|
31869
32013
|
- target agent;
|
|
31870
32014
|
- \`delegationId\`;
|
|
@@ -31890,8 +32034,8 @@ async function readOptional(filePath) {
|
|
|
31890
32034
|
}
|
|
31891
32035
|
}
|
|
31892
32036
|
async function atomicWrite(filePath, content) {
|
|
31893
|
-
await mkdir7(
|
|
31894
|
-
const temporaryPath =
|
|
32037
|
+
await mkdir7(path15.dirname(filePath), { recursive: true, mode: 448 });
|
|
32038
|
+
const temporaryPath = path15.join(path15.dirname(filePath), `.SKILL.md.${randomUUID9()}.tmp`);
|
|
31895
32039
|
const handle = await open5(temporaryPath, "wx", 384);
|
|
31896
32040
|
try {
|
|
31897
32041
|
await handle.writeFile(content, "utf8");
|
|
@@ -31908,8 +32052,8 @@ async function atomicWrite(filePath, content) {
|
|
|
31908
32052
|
async function installDelegationSkills(input = {}) {
|
|
31909
32053
|
const home = input.homeDirectory ?? os4.homedir();
|
|
31910
32054
|
const destinations = [
|
|
31911
|
-
|
|
31912
|
-
|
|
32055
|
+
path15.join(home, ".agents", SKILL_RELATIVE_PATH),
|
|
32056
|
+
path15.join(home, ".claude", SKILL_RELATIVE_PATH)
|
|
31913
32057
|
];
|
|
31914
32058
|
const knownDigests = /* @__PURE__ */ new Set([
|
|
31915
32059
|
CURRENT_DIGEST,
|
|
@@ -31976,7 +32120,7 @@ async function installDelegationSkills(input = {}) {
|
|
|
31976
32120
|
// packages/host-runtime/src/remote-control-app-server.ts
|
|
31977
32121
|
import { randomUUID as randomUUID10 } from "node:crypto";
|
|
31978
32122
|
import { mkdir as mkdir8, open as open6, rename as rename6, rm as rm6 } from "node:fs/promises";
|
|
31979
|
-
import
|
|
32123
|
+
import path16 from "node:path";
|
|
31980
32124
|
|
|
31981
32125
|
// packages/host-runtime/src/remote-official-connection.ts
|
|
31982
32126
|
import net from "node:net";
|
|
@@ -32166,8 +32310,8 @@ var BRIDGE_READY_METHOD = "codexhost/remote-control-bridge/ready";
|
|
|
32166
32310
|
function absoluteEnvironmentPath2(environment, name, fallback, platform = process.platform) {
|
|
32167
32311
|
const value2 = environment[name] ?? fallback;
|
|
32168
32312
|
if (!value2) return null;
|
|
32169
|
-
if (
|
|
32170
|
-
return platform === "win32" &&
|
|
32313
|
+
if (path16.isAbsolute(value2)) return path16.normalize(value2);
|
|
32314
|
+
return platform === "win32" && path16.win32.isAbsolute(value2) ? path16.win32.normalize(value2) : null;
|
|
32171
32315
|
}
|
|
32172
32316
|
function nodeCompatibleWindowsPath(value2) {
|
|
32173
32317
|
if (value2.startsWith("\\\\?\\UNC\\")) return `\\\\${value2.slice(8)}`;
|
|
@@ -32181,13 +32325,13 @@ function remoteControlBridgePipePath(processId = process.pid, instanceId = rando
|
|
|
32181
32325
|
}
|
|
32182
32326
|
function remoteControlBridgeDescriptorPath(environment) {
|
|
32183
32327
|
const root = environment.LOCALAPPDATA;
|
|
32184
|
-
if (!root || !
|
|
32185
|
-
return
|
|
32328
|
+
if (!root || !path16.isAbsolute(root)) return null;
|
|
32329
|
+
return path16.join(path16.normalize(root), "codexhost", REMOTE_CONTROL_BRIDGE_DESCRIPTOR_FILE);
|
|
32186
32330
|
}
|
|
32187
32331
|
async function publishRemoteControlAppServerDescriptor(plan) {
|
|
32188
|
-
const directory =
|
|
32332
|
+
const directory = path16.dirname(plan.descriptorPath);
|
|
32189
32333
|
await mkdir8(directory, { recursive: true, mode: 448 });
|
|
32190
|
-
const temporaryPath =
|
|
32334
|
+
const temporaryPath = path16.join(
|
|
32191
32335
|
directory,
|
|
32192
32336
|
`.${REMOTE_CONTROL_BRIDGE_DESCRIPTOR_FILE}.${plan.descriptor.ownerPid}.${randomUUID10()}.tmp`
|
|
32193
32337
|
);
|
|
@@ -32280,14 +32424,14 @@ async function runRemoteControlAppServerBridge(input = {}) {
|
|
|
32280
32424
|
import { createServer as createServer2 } from "node:http";
|
|
32281
32425
|
import net2 from "node:net";
|
|
32282
32426
|
import { chmod as chmod3, lstat as lstat6, mkdir as mkdir10, rm as rm8 } from "node:fs/promises";
|
|
32283
|
-
import
|
|
32427
|
+
import path18 from "node:path";
|
|
32284
32428
|
import { PassThrough as PassThrough2 } from "node:stream";
|
|
32285
32429
|
|
|
32286
32430
|
// packages/host-runtime/src/remote-socket-lock.ts
|
|
32287
32431
|
import { randomUUID as randomUUID11 } from "node:crypto";
|
|
32288
32432
|
import { chmod as chmod2, lstat as lstat5, mkdir as mkdir9, open as open7, readFile as readFile8, readdir as readdir4, rename as rename7, rm as rm7 } from "node:fs/promises";
|
|
32289
32433
|
import { uptime } from "node:os";
|
|
32290
|
-
import
|
|
32434
|
+
import path17 from "node:path";
|
|
32291
32435
|
import { setTimeout as delay4 } from "node:timers/promises";
|
|
32292
32436
|
var LOCK_RETRY_COUNT = 200;
|
|
32293
32437
|
var LOCK_RETRY_DELAY_MS = 25;
|
|
@@ -32361,7 +32505,7 @@ async function readLockEntrySnapshot(filePath) {
|
|
|
32361
32505
|
source,
|
|
32362
32506
|
identity: { dev: metadata.dev, ino: metadata.ino },
|
|
32363
32507
|
mtimeMs: metadata.mtimeMs,
|
|
32364
|
-
record: record3 &&
|
|
32508
|
+
record: record3 && path17.basename(filePath) === lockEntryName(record3.ownerToken) ? record3 : null
|
|
32365
32509
|
};
|
|
32366
32510
|
}
|
|
32367
32511
|
function lockEntryIsAbandoned(snapshot) {
|
|
@@ -32382,7 +32526,7 @@ async function readLockEntryCatalog(lockDirectory) {
|
|
|
32382
32526
|
let unsettled = false;
|
|
32383
32527
|
for (const name of names) {
|
|
32384
32528
|
if (!name.startsWith(LOCK_ENTRY_PREFIX) || !name.endsWith(LOCK_ENTRY_SUFFIX)) continue;
|
|
32385
|
-
const snapshot = await readLockEntrySnapshot(
|
|
32529
|
+
const snapshot = await readLockEntrySnapshot(path17.join(lockDirectory, name));
|
|
32386
32530
|
if (snapshot === null) continue;
|
|
32387
32531
|
if (lockEntryIsAbandoned(snapshot)) {
|
|
32388
32532
|
if (!await removeAbandonedLockEntry(snapshot)) unsettled = true;
|
|
@@ -32410,7 +32554,7 @@ async function preparePrivateLockDirectory(lockDirectory) {
|
|
|
32410
32554
|
await chmod2(lockDirectory, 448);
|
|
32411
32555
|
}
|
|
32412
32556
|
async function writeLockRecordAtomic(lockDirectory, entryPath, record3) {
|
|
32413
|
-
const temporary =
|
|
32557
|
+
const temporary = path17.join(lockDirectory, `.tmp-${record3.ownerToken}-${randomUUID11()}`);
|
|
32414
32558
|
const handle = await open7(temporary, "wx", 384);
|
|
32415
32559
|
try {
|
|
32416
32560
|
await handle.writeFile(`${JSON.stringify(record3)}
|
|
@@ -32486,7 +32630,7 @@ async function withRemoteAppServerSocketInitializationLock(socketPath, action) {
|
|
|
32486
32630
|
const lockDirectory = `${socketPath}.initializers`;
|
|
32487
32631
|
await preparePrivateLockDirectory(lockDirectory);
|
|
32488
32632
|
const ownerToken = randomUUID11();
|
|
32489
|
-
const entryPath =
|
|
32633
|
+
const entryPath = path17.join(lockDirectory, lockEntryName(ownerToken));
|
|
32490
32634
|
const baseRecord = {
|
|
32491
32635
|
version: 2,
|
|
32492
32636
|
ownerToken,
|
|
@@ -32660,14 +32804,14 @@ function remoteAppServerSocketPath(environment, listenUrl = "unix://") {
|
|
|
32660
32804
|
throw new Error("Remote app-server listener must use a Unix URL");
|
|
32661
32805
|
}
|
|
32662
32806
|
const explicit = listenUrl.slice("unix://".length);
|
|
32663
|
-
if (explicit.length > 0) return
|
|
32664
|
-
const codexHome = environment.CODEX_HOME ?? (environment.HOME ?
|
|
32807
|
+
if (explicit.length > 0) return path18.posix.resolve(decodeURIComponent(explicit));
|
|
32808
|
+
const codexHome = environment.CODEX_HOME ?? (environment.HOME ? path18.posix.join(environment.HOME, ".codex") : void 0);
|
|
32665
32809
|
if (!codexHome)
|
|
32666
32810
|
throw new Error("CODEX_HOME or HOME is required for the remote app-server socket");
|
|
32667
|
-
return
|
|
32811
|
+
return path18.posix.join(codexHome, "app-server-control", "app-server-control.sock");
|
|
32668
32812
|
}
|
|
32669
32813
|
function officialListenerArgumentsForRemoteListener(arguments_2, socketPath) {
|
|
32670
|
-
if (!
|
|
32814
|
+
if (!path18.posix.isAbsolute(socketPath)) {
|
|
32671
32815
|
throw new Error("Shared official app-server socket path must be absolute");
|
|
32672
32816
|
}
|
|
32673
32817
|
if (remoteUnixListenerUrl(arguments_2) === null) {
|
|
@@ -32778,7 +32922,7 @@ async function removeStaleSocket(socketPath) {
|
|
|
32778
32922
|
await rm8(socketPath, { force: true });
|
|
32779
32923
|
}
|
|
32780
32924
|
async function prepareRemoteAppServerSocketDirectory(socketPath) {
|
|
32781
|
-
const socketDirectory =
|
|
32925
|
+
const socketDirectory = path18.dirname(socketPath);
|
|
32782
32926
|
const existing = await lstat6(socketDirectory).catch((error51) => {
|
|
32783
32927
|
if (error51.code === "ENOENT") return null;
|
|
32784
32928
|
throw error51;
|
|
@@ -32985,18 +33129,18 @@ function createRemoteAppServerWebSocketListener(input) {
|
|
|
32985
33129
|
import { spawn as spawn4 } from "node:child_process";
|
|
32986
33130
|
import { randomUUID as randomUUID12 } from "node:crypto";
|
|
32987
33131
|
import { lstat as lstat7, rm as rm9 } from "node:fs/promises";
|
|
32988
|
-
import
|
|
33132
|
+
import path19 from "node:path";
|
|
32989
33133
|
var DEFAULT_CLOSE_TIMEOUT_MS = 2e3;
|
|
32990
33134
|
var DEFAULT_LISTEN_TIMEOUT_MS = 1e4;
|
|
32991
33135
|
function remoteOfficialAppServerSocketPath(desktopControlSocketPath, token = randomUUID12()) {
|
|
32992
|
-
if (!
|
|
33136
|
+
if (!path19.posix.isAbsolute(desktopControlSocketPath)) {
|
|
32993
33137
|
throw new Error("Desktop control socket path must be absolute");
|
|
32994
33138
|
}
|
|
32995
33139
|
if (!/^[A-Za-z0-9-]+$/u.test(token) || !/[A-Za-z0-9]/u.test(token)) {
|
|
32996
33140
|
throw new Error("Shared official app-server socket token is invalid");
|
|
32997
33141
|
}
|
|
32998
33142
|
const compactToken = token.replaceAll("-", "").slice(0, 15);
|
|
32999
|
-
return
|
|
33143
|
+
return path19.posix.join(path19.posix.dirname(desktopControlSocketPath), `.c-${compactToken}.sock`);
|
|
33000
33144
|
}
|
|
33001
33145
|
function errorMessage5(error51) {
|
|
33002
33146
|
return error51 instanceof Error ? error51.message : String(error51);
|
|
@@ -33463,9 +33607,9 @@ function hasLauncherManagedUpdateRuntime(environment, hostRuntimePath) {
|
|
|
33463
33607
|
if (!environment[UPDATE_RUNTIME_ENV.launcherPid]) return false;
|
|
33464
33608
|
const npmPackageRoot = environment[UPDATE_RUNTIME_ENV.npmPackageRoot];
|
|
33465
33609
|
if (!npmPackageRoot || !hostRuntimePath) return true;
|
|
33466
|
-
if (!
|
|
33467
|
-
const runtimePackageRoot =
|
|
33468
|
-
return
|
|
33610
|
+
if (!path20.isAbsolute(npmPackageRoot) || !path20.isAbsolute(hostRuntimePath)) return false;
|
|
33611
|
+
const runtimePackageRoot = path20.dirname(path20.dirname(path20.normalize(hostRuntimePath)));
|
|
33612
|
+
return path20.relative(path20.normalize(npmPackageRoot), runtimePackageRoot) === "";
|
|
33469
33613
|
}
|
|
33470
33614
|
function requiredRuntimeConfiguration(environment) {
|
|
33471
33615
|
const stockCodexPath = environment[STOCK_CODEX_PATH_ENV];
|
|
@@ -33546,19 +33690,15 @@ async function runHostRuntime(input) {
|
|
|
33546
33690
|
const officialPlan = createRemoteControlOfficialAppServerPlan(
|
|
33547
33691
|
remoteControlPlan.officialArguments
|
|
33548
33692
|
);
|
|
33549
|
-
const
|
|
33550
|
-
|
|
33551
|
-
|
|
33552
|
-
|
|
33553
|
-
|
|
33554
|
-
|
|
33555
|
-
|
|
33556
|
-
|
|
33557
|
-
|
|
33558
|
-
throw new Error("Shared official app-server endpoint is unavailable");
|
|
33559
|
-
}
|
|
33560
|
-
return createRemoteOfficialAppServerConnection(officialEndpoint);
|
|
33561
|
-
};
|
|
33693
|
+
const officialListeners = new AccountOfficialListeners(
|
|
33694
|
+
(account) => createLoopbackOfficialAppServerListener({
|
|
33695
|
+
stockCodexPath,
|
|
33696
|
+
arguments: officialPlan.listenerArguments,
|
|
33697
|
+
environment: officialAccountEnvironment(delegationEnvironment, account),
|
|
33698
|
+
diagnosticOutput: process.stderr
|
|
33699
|
+
})
|
|
33700
|
+
);
|
|
33701
|
+
const createOfficialConnection = async (account) => createRemoteOfficialAppServerConnection(await officialListeners.endpoint(account));
|
|
33562
33702
|
const mappingStore = createProductionExternalThreadStore(delegationEnvironment);
|
|
33563
33703
|
await mappingStore.initialize();
|
|
33564
33704
|
const host = new AppServerHost({
|
|
@@ -33595,7 +33735,11 @@ async function runHostRuntime(input) {
|
|
|
33595
33735
|
}
|
|
33596
33736
|
});
|
|
33597
33737
|
try {
|
|
33598
|
-
|
|
33738
|
+
await officialListeners.endpoint({
|
|
33739
|
+
codexHome: path20.resolve(
|
|
33740
|
+
delegationEnvironment.CODEX_HOME ?? path20.join(homedir(), ".codex")
|
|
33741
|
+
)
|
|
33742
|
+
});
|
|
33599
33743
|
await listener.listen();
|
|
33600
33744
|
await publishRemoteControlAppServerDescriptor(remoteControlPlan);
|
|
33601
33745
|
return await host.run();
|
|
@@ -33604,7 +33748,7 @@ async function runHostRuntime(input) {
|
|
|
33604
33748
|
await listener.close();
|
|
33605
33749
|
} finally {
|
|
33606
33750
|
try {
|
|
33607
|
-
await
|
|
33751
|
+
await officialListeners.close();
|
|
33608
33752
|
} finally {
|
|
33609
33753
|
await mappingStore.close();
|
|
33610
33754
|
}
|
|
@@ -33709,7 +33853,7 @@ import {
|
|
|
33709
33853
|
stat as stat4,
|
|
33710
33854
|
writeFile as writeFile5
|
|
33711
33855
|
} from "node:fs/promises";
|
|
33712
|
-
import
|
|
33856
|
+
import path21 from "node:path";
|
|
33713
33857
|
var MANIFEST_FORMAT = 1;
|
|
33714
33858
|
var WRAPPER_MARKER = "# codexhost remote SSH wrapper v1";
|
|
33715
33859
|
var PROFILE_START = "# >>> codexhost remote SSH >>>";
|
|
@@ -33720,25 +33864,25 @@ function resolvePaths(options2) {
|
|
|
33720
33864
|
if (!configuredHome) {
|
|
33721
33865
|
throw new Error("A non-root HOME is required for remote Host installation");
|
|
33722
33866
|
}
|
|
33723
|
-
const home =
|
|
33724
|
-
if (!home || home ===
|
|
33867
|
+
const home = path21.resolve(configuredHome);
|
|
33868
|
+
if (!home || home === path21.parse(home).root) {
|
|
33725
33869
|
throw new Error("A non-root HOME is required for remote Host installation");
|
|
33726
33870
|
}
|
|
33727
|
-
const installRoot =
|
|
33728
|
-
const profilePath =
|
|
33729
|
-
options2.profilePath ??
|
|
33871
|
+
const installRoot = path21.resolve(options2.installRoot ?? path21.join(home, ".codexhost", "remote"));
|
|
33872
|
+
const profilePath = path21.resolve(
|
|
33873
|
+
options2.profilePath ?? path21.join(
|
|
33730
33874
|
home,
|
|
33731
|
-
|
|
33875
|
+
path21.basename(environment.SHELL ?? "") === "zsh" ? ".zshenv" : path21.basename(environment.SHELL ?? "") === "bash" ? ".bashrc" : ".profile"
|
|
33732
33876
|
)
|
|
33733
33877
|
);
|
|
33734
|
-
const binDirectory =
|
|
33878
|
+
const binDirectory = path21.join(installRoot, "bin");
|
|
33735
33879
|
return {
|
|
33736
33880
|
home,
|
|
33737
33881
|
installRoot,
|
|
33738
33882
|
binDirectory,
|
|
33739
|
-
wrapperPath:
|
|
33740
|
-
manifestPath:
|
|
33741
|
-
dataDirectory:
|
|
33883
|
+
wrapperPath: path21.join(binDirectory, "codex"),
|
|
33884
|
+
manifestPath: path21.join(installRoot, "manifest.json"),
|
|
33885
|
+
dataDirectory: path21.join(installRoot, "data"),
|
|
33742
33886
|
profilePath
|
|
33743
33887
|
};
|
|
33744
33888
|
}
|
|
@@ -33757,7 +33901,7 @@ async function fileSha256(filePath) {
|
|
|
33757
33901
|
return createHash7("sha256").update(await readFile9(filePath)).digest("hex");
|
|
33758
33902
|
}
|
|
33759
33903
|
async function executable(filePath, label) {
|
|
33760
|
-
const absolute =
|
|
33904
|
+
const absolute = path21.resolve(filePath);
|
|
33761
33905
|
try {
|
|
33762
33906
|
if (!(await stat4(absolute)).isFile()) throw new Error("not a regular file");
|
|
33763
33907
|
await access(absolute, fsConstants.X_OK);
|
|
@@ -33767,7 +33911,7 @@ async function executable(filePath, label) {
|
|
|
33767
33911
|
return absolute;
|
|
33768
33912
|
}
|
|
33769
33913
|
async function existingFile(filePath, label) {
|
|
33770
|
-
const absolute =
|
|
33914
|
+
const absolute = path21.resolve(filePath);
|
|
33771
33915
|
try {
|
|
33772
33916
|
const metadata = await stat4(absolute);
|
|
33773
33917
|
if (!metadata.isFile()) throw new Error("not a regular file");
|
|
@@ -33777,9 +33921,9 @@ async function existingFile(filePath, label) {
|
|
|
33777
33921
|
return absolute;
|
|
33778
33922
|
}
|
|
33779
33923
|
async function discoverExecutable(name, environment) {
|
|
33780
|
-
for (const directory of (environment.PATH ?? "").split(
|
|
33924
|
+
for (const directory of (environment.PATH ?? "").split(path21.delimiter)) {
|
|
33781
33925
|
if (!directory) continue;
|
|
33782
|
-
const candidate =
|
|
33926
|
+
const candidate = path21.resolve(directory, name);
|
|
33783
33927
|
try {
|
|
33784
33928
|
await access(candidate, fsConstants.X_OK);
|
|
33785
33929
|
return candidate;
|
|
@@ -33790,10 +33934,10 @@ async function discoverExecutable(name, environment) {
|
|
|
33790
33934
|
return null;
|
|
33791
33935
|
}
|
|
33792
33936
|
async function writeAtomic(filePath, contents, mode) {
|
|
33793
|
-
await mkdir11(
|
|
33794
|
-
const temporary =
|
|
33795
|
-
|
|
33796
|
-
`.${
|
|
33937
|
+
await mkdir11(path21.dirname(filePath), { recursive: true, mode: 448 });
|
|
33938
|
+
const temporary = path21.join(
|
|
33939
|
+
path21.dirname(filePath),
|
|
33940
|
+
`.${path21.basename(filePath)}.${process.pid}.${randomUUID13()}.tmp`
|
|
33797
33941
|
);
|
|
33798
33942
|
try {
|
|
33799
33943
|
if (typeof contents === "string") {
|
|
@@ -33814,10 +33958,10 @@ async function writeAtomic(filePath, contents, mode) {
|
|
|
33814
33958
|
}
|
|
33815
33959
|
}
|
|
33816
33960
|
async function writeAtomicExecutable(filePath, sourcePath) {
|
|
33817
|
-
await mkdir11(
|
|
33818
|
-
const temporary =
|
|
33819
|
-
|
|
33820
|
-
`.${
|
|
33961
|
+
await mkdir11(path21.dirname(filePath), { recursive: true, mode: 448 });
|
|
33962
|
+
const temporary = path21.join(
|
|
33963
|
+
path21.dirname(filePath),
|
|
33964
|
+
`.${path21.basename(filePath)}.${process.pid}.${randomUUID13()}.tmp`
|
|
33821
33965
|
);
|
|
33822
33966
|
try {
|
|
33823
33967
|
await copyFile3(sourcePath, temporary);
|
|
@@ -33858,8 +34002,8 @@ function removeManagedProfileBlock(contents) {
|
|
|
33858
34002
|
function installManagedProfileBlock(contents, manifest) {
|
|
33859
34003
|
const base = removeManagedProfileBlock(contents);
|
|
33860
34004
|
const environment = [
|
|
33861
|
-
`export CODEX_INSTALL_DIR=${shellQuote(
|
|
33862
|
-
`export PATH=${shellQuote(
|
|
34005
|
+
`export CODEX_INSTALL_DIR=${shellQuote(path21.dirname(manifest.wrapperPath))}`,
|
|
34006
|
+
`export PATH=${shellQuote(path21.dirname(manifest.wrapperPath))}:${shellQuote(path21.dirname(manifest.nodePath))}:${shellQuote(path21.dirname(manifest.stockCodexPath))}:"\${PATH:-/usr/local/bin:/usr/bin:/bin}"`,
|
|
33863
34007
|
`export CODEXHOST_STOCK_CODEX_PATH=${shellQuote(manifest.stockCodexPath)}`,
|
|
33864
34008
|
`export CODEXHOST_HOST_NODE_PATH=${shellQuote(manifest.nodePath)}`,
|
|
33865
34009
|
`export CODEXHOST_HOST_RUNTIME_PATH=${shellQuote(manifest.hostRuntimePath)}`,
|
|
@@ -33876,7 +34020,7 @@ function installManagedProfileBlock(contents, manifest) {
|
|
|
33876
34020
|
PROFILE_END,
|
|
33877
34021
|
""
|
|
33878
34022
|
].join("\n");
|
|
33879
|
-
if (
|
|
34023
|
+
if (path21.basename(manifest.profilePath) === ".bashrc") return `${block}${base}`;
|
|
33880
34024
|
const separator = base.length > 0 && !base.endsWith("\n") ? "\n" : "";
|
|
33881
34025
|
return `${base}${separator}${block}`;
|
|
33882
34026
|
}
|
|
@@ -33941,9 +34085,9 @@ async function readManifest(filePath) {
|
|
|
33941
34085
|
];
|
|
33942
34086
|
const optionalPaths = ["claudeCommand", "profileBackupPath"];
|
|
33943
34087
|
if (manifest.format !== MANIFEST_FORMAT || Object.keys(manifest).some((key) => !allowed.has(key)) || requiredPaths.some(
|
|
33944
|
-
(key) => typeof manifest[key] !== "string" || !
|
|
34088
|
+
(key) => typeof manifest[key] !== "string" || !path21.isAbsolute(manifest[key])
|
|
33945
34089
|
) || optionalPaths.some(
|
|
33946
|
-
(key) => manifest[key] !== void 0 && (typeof manifest[key] !== "string" || !
|
|
34090
|
+
(key) => manifest[key] !== void 0 && (typeof manifest[key] !== "string" || !path21.isAbsolute(manifest[key]))
|
|
33947
34091
|
) || manifest.entrypointSha256 !== void 0 && (typeof manifest.entrypointSha256 !== "string" || !/^[a-f0-9]{64}$/u.test(manifest.entrypointSha256))) {
|
|
33948
34092
|
throw new Error("Remote Host manifest has an unsupported format");
|
|
33949
34093
|
}
|
|
@@ -34172,7 +34316,7 @@ async function uninstallRemoteHost(options2) {
|
|
|
34172
34316
|
import { spawn as spawn5 } from "node:child_process";
|
|
34173
34317
|
import { stat as stat5 } from "node:fs/promises";
|
|
34174
34318
|
import net3 from "node:net";
|
|
34175
|
-
import
|
|
34319
|
+
import path22 from "node:path";
|
|
34176
34320
|
import { Duplex } from "node:stream";
|
|
34177
34321
|
var CODEXHOST_STATUS_METHOD = "codexhost/update/status";
|
|
34178
34322
|
var DIRECT_PROBE_TIMEOUT_MS = 5e3;
|
|
@@ -34191,9 +34335,9 @@ function classifyRemoteHostProbeResponse(response, socketPath) {
|
|
|
34191
34335
|
}
|
|
34192
34336
|
var lifecycleDependencyOverrides = {};
|
|
34193
34337
|
function socketPathFor(environment) {
|
|
34194
|
-
const codexHome = environment.CODEX_HOME ?? (environment.HOME ?
|
|
34338
|
+
const codexHome = environment.CODEX_HOME ?? (environment.HOME ? path22.join(environment.HOME, ".codex") : void 0);
|
|
34195
34339
|
if (!codexHome) throw new Error("CODEX_HOME or HOME is required for remote Host lifecycle");
|
|
34196
|
-
return
|
|
34340
|
+
return path22.join(codexHome, "app-server-control", "app-server-control.sock");
|
|
34197
34341
|
}
|
|
34198
34342
|
async function defaultSocketExists(socketPath) {
|
|
34199
34343
|
const metadata = await stat5(socketPath).catch((error51) => {
|
|
@@ -34320,7 +34464,7 @@ function installedManifest(status) {
|
|
|
34320
34464
|
function managedEnvironment(manifest, environment) {
|
|
34321
34465
|
return {
|
|
34322
34466
|
...environment,
|
|
34323
|
-
CODEX_INSTALL_DIR:
|
|
34467
|
+
CODEX_INSTALL_DIR: path22.dirname(manifest.wrapperPath),
|
|
34324
34468
|
CODEXHOST_STOCK_CODEX_PATH: manifest.stockCodexPath,
|
|
34325
34469
|
CODEXHOST_HOST_NODE_PATH: manifest.nodePath,
|
|
34326
34470
|
CODEXHOST_HOST_RUNTIME_PATH: manifest.hostRuntimePath,
|
|
@@ -34328,7 +34472,7 @@ function managedEnvironment(manifest, environment) {
|
|
|
34328
34472
|
CODEXHOST_DEFAULT_AGENT: "codex",
|
|
34329
34473
|
CODEXHOST_REMOTE_SSH_MANAGED: "1",
|
|
34330
34474
|
...manifest.claudeCommand ? { CODEXHOST_CLAUDE_COMMAND: manifest.claudeCommand } : {},
|
|
34331
|
-
PATH: `${
|
|
34475
|
+
PATH: `${path22.dirname(manifest.wrapperPath)}${path22.delimiter}${path22.dirname(manifest.stockCodexPath)}${path22.delimiter}${environment.PATH ?? "/usr/bin:/bin"}`
|
|
34332
34476
|
};
|
|
34333
34477
|
}
|
|
34334
34478
|
async function defaultRunTerminator(manifest, socketPath, role, environment) {
|
|
@@ -34667,19 +34811,19 @@ function consumeBrokerFrames(socket, onFrame, onError) {
|
|
|
34667
34811
|
|
|
34668
34812
|
// packages/harness-broker/dist/paths.js
|
|
34669
34813
|
import os5 from "node:os";
|
|
34670
|
-
import
|
|
34814
|
+
import path23 from "node:path";
|
|
34671
34815
|
var HARNESS_BROKER_DESCRIPTOR_ENV = "CODEXHOST_CLAUDE_BROKER_DESCRIPTOR";
|
|
34672
34816
|
var HARNESS_BROKER_DESCRIPTOR_FILE = "claude-code-broker-v1.json";
|
|
34673
34817
|
var HARNESS_BROKER_SOCKET_FILE = "claude-code-broker-v1.sock";
|
|
34674
34818
|
function defaultHarnessBrokerDirectory(environment = process.env) {
|
|
34675
34819
|
const home = environment.HOME || os5.homedir();
|
|
34676
|
-
return
|
|
34820
|
+
return path23.join(home, ".codexhost", "harness-broker");
|
|
34677
34821
|
}
|
|
34678
34822
|
function defaultHarnessBrokerDescriptorPath(environment = process.env) {
|
|
34679
|
-
return environment[HARNESS_BROKER_DESCRIPTOR_ENV] ??
|
|
34823
|
+
return environment[HARNESS_BROKER_DESCRIPTOR_ENV] ?? path23.join(defaultHarnessBrokerDirectory(environment), HARNESS_BROKER_DESCRIPTOR_FILE);
|
|
34680
34824
|
}
|
|
34681
34825
|
function defaultHarnessBrokerSocketPath(environment = process.env) {
|
|
34682
|
-
return
|
|
34826
|
+
return path23.join(defaultHarnessBrokerDirectory(environment), HARNESS_BROKER_SOCKET_FILE);
|
|
34683
34827
|
}
|
|
34684
34828
|
|
|
34685
34829
|
// packages/harness-broker/dist/validation.js
|
|
@@ -34694,6 +34838,8 @@ var createSchema = external_exports.object({
|
|
|
34694
34838
|
}).strict();
|
|
34695
34839
|
var resumeSchema = external_exports.object({
|
|
34696
34840
|
kind: external_exports.literal("resume"),
|
|
34841
|
+
model: harnessModelRefSchema.optional(),
|
|
34842
|
+
thinkingOptionId: harnessThinkingOptionIdSchema.optional(),
|
|
34697
34843
|
nativeRef: nativeSessionRefSchema,
|
|
34698
34844
|
cwd: cwdSchema,
|
|
34699
34845
|
knownTurnRefs: external_exports.array(nativeTurnRefSchema).max(1e5).optional()
|
|
@@ -34706,6 +34852,9 @@ var forkSchema = external_exports.object({
|
|
|
34706
34852
|
}).strict();
|
|
34707
34853
|
var rollbackSchema = external_exports.object({
|
|
34708
34854
|
kind: external_exports.literal("rollbackLastTurn"),
|
|
34855
|
+
model: harnessModelRefSchema.optional(),
|
|
34856
|
+
thinkingOptionId: harnessThinkingOptionIdSchema.optional(),
|
|
34857
|
+
permissionModeId: harnessPermissionModeIdSchema.optional(),
|
|
34709
34858
|
sourceRef: nativeSessionRefSchema,
|
|
34710
34859
|
cwd: cwdSchema
|
|
34711
34860
|
}).strict();
|
|
@@ -34879,7 +35028,7 @@ var harnessOutputSchema = external_exports.custom((value2) => {
|
|
|
34879
35028
|
import { randomBytes as randomBytes2, randomUUID as randomUUID14 } from "node:crypto";
|
|
34880
35029
|
import { chmod as chmod5, lstat as lstat9, mkdir as mkdir12, open as open8, readFile as readFile10, rename as rename9, rm as rm11 } from "node:fs/promises";
|
|
34881
35030
|
import net4, {} from "node:net";
|
|
34882
|
-
import
|
|
35031
|
+
import path24 from "node:path";
|
|
34883
35032
|
function harnessError(message, retryable = true) {
|
|
34884
35033
|
return { code: "unavailable", message, retryable, stage: "harnessBroker" };
|
|
34885
35034
|
}
|
|
@@ -35004,13 +35153,13 @@ async function startHarnessBrokerServer(input) {
|
|
|
35004
35153
|
if (input.adapter.harnessId !== "claude-code") {
|
|
35005
35154
|
throw new Error("Harness broker accepts only the claude-code adapter");
|
|
35006
35155
|
}
|
|
35007
|
-
if (process.platform !== "win32" &&
|
|
35156
|
+
if (process.platform !== "win32" && path24.dirname(input.descriptorPath) !== path24.dirname(input.socketPath)) {
|
|
35008
35157
|
throw new Error("Harness broker descriptor and socket must share one private directory");
|
|
35009
35158
|
}
|
|
35010
35159
|
if (process.platform === "darwin" && Buffer.byteLength(input.socketPath) > 103) {
|
|
35011
35160
|
throw new Error("Harness broker Unix socket path is too long for macOS");
|
|
35012
35161
|
}
|
|
35013
|
-
await privateDirectory(
|
|
35162
|
+
await privateDirectory(path24.dirname(input.descriptorPath));
|
|
35014
35163
|
await assertNoLiveDescriptor(input.descriptorPath);
|
|
35015
35164
|
if (process.platform !== "win32")
|
|
35016
35165
|
await prepareUnixSocketPath(input.socketPath);
|