@codexhost/cli-win32-arm64 0.2.0 → 0.2.2
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 +2 -2
- package/app/codexhost-distribution.json +1 -1
- package/app/desktop-controller.mjs +2 -24
- package/app/host-runtime.mjs +583 -397
- package/app/renderer-extension.js +487 -35
- package/bin/codexhost.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
|
@@ -773,10 +773,10 @@ function mergeDefs(...defs) {
|
|
|
773
773
|
function cloneDef(schema) {
|
|
774
774
|
return mergeDefs(schema._zod.def);
|
|
775
775
|
}
|
|
776
|
-
function getElementAtPath(obj,
|
|
777
|
-
if (!
|
|
776
|
+
function getElementAtPath(obj, path18) {
|
|
777
|
+
if (!path18)
|
|
778
778
|
return obj;
|
|
779
|
-
return
|
|
779
|
+
return path18.reduce((acc, key) => acc?.[key], obj);
|
|
780
780
|
}
|
|
781
781
|
function promiseAllObject(promisesObj) {
|
|
782
782
|
const keys = Object.keys(promisesObj);
|
|
@@ -1185,11 +1185,11 @@ function explicitlyAborted(x2, startIndex = 0) {
|
|
|
1185
1185
|
}
|
|
1186
1186
|
return false;
|
|
1187
1187
|
}
|
|
1188
|
-
function prefixIssues(
|
|
1188
|
+
function prefixIssues(path18, issues) {
|
|
1189
1189
|
return issues.map((iss) => {
|
|
1190
1190
|
var _a4;
|
|
1191
1191
|
(_a4 = iss).path ?? (_a4.path = []);
|
|
1192
|
-
iss.path.unshift(
|
|
1192
|
+
iss.path.unshift(path18);
|
|
1193
1193
|
return iss;
|
|
1194
1194
|
});
|
|
1195
1195
|
}
|
|
@@ -1336,16 +1336,16 @@ function flattenError(error52, mapper = (issue2) => issue2.message) {
|
|
|
1336
1336
|
}
|
|
1337
1337
|
function formatError(error52, mapper = (issue2) => issue2.message) {
|
|
1338
1338
|
const fieldErrors = { _errors: [] };
|
|
1339
|
-
const processError = (error53,
|
|
1339
|
+
const processError = (error53, path18 = []) => {
|
|
1340
1340
|
for (const issue2 of error53.issues) {
|
|
1341
1341
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
1342
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
1342
|
+
issue2.errors.map((issues) => processError({ issues }, [...path18, ...issue2.path]));
|
|
1343
1343
|
} else if (issue2.code === "invalid_key") {
|
|
1344
|
-
processError({ issues: issue2.issues }, [...
|
|
1344
|
+
processError({ issues: issue2.issues }, [...path18, ...issue2.path]);
|
|
1345
1345
|
} else if (issue2.code === "invalid_element") {
|
|
1346
|
-
processError({ issues: issue2.issues }, [...
|
|
1346
|
+
processError({ issues: issue2.issues }, [...path18, ...issue2.path]);
|
|
1347
1347
|
} else {
|
|
1348
|
-
const fullpath = [...
|
|
1348
|
+
const fullpath = [...path18, ...issue2.path];
|
|
1349
1349
|
if (fullpath.length === 0) {
|
|
1350
1350
|
fieldErrors._errors.push(mapper(issue2));
|
|
1351
1351
|
} else {
|
|
@@ -1372,17 +1372,17 @@ function formatError(error52, mapper = (issue2) => issue2.message) {
|
|
|
1372
1372
|
}
|
|
1373
1373
|
function treeifyError(error52, mapper = (issue2) => issue2.message) {
|
|
1374
1374
|
const result = { errors: [] };
|
|
1375
|
-
const processError = (error53,
|
|
1375
|
+
const processError = (error53, path18 = []) => {
|
|
1376
1376
|
var _a4, _b2;
|
|
1377
1377
|
for (const issue2 of error53.issues) {
|
|
1378
1378
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
1379
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
1379
|
+
issue2.errors.map((issues) => processError({ issues }, [...path18, ...issue2.path]));
|
|
1380
1380
|
} else if (issue2.code === "invalid_key") {
|
|
1381
|
-
processError({ issues: issue2.issues }, [...
|
|
1381
|
+
processError({ issues: issue2.issues }, [...path18, ...issue2.path]);
|
|
1382
1382
|
} else if (issue2.code === "invalid_element") {
|
|
1383
|
-
processError({ issues: issue2.issues }, [...
|
|
1383
|
+
processError({ issues: issue2.issues }, [...path18, ...issue2.path]);
|
|
1384
1384
|
} else {
|
|
1385
|
-
const fullpath = [...
|
|
1385
|
+
const fullpath = [...path18, ...issue2.path];
|
|
1386
1386
|
if (fullpath.length === 0) {
|
|
1387
1387
|
result.errors.push(mapper(issue2));
|
|
1388
1388
|
continue;
|
|
@@ -1414,8 +1414,8 @@ function treeifyError(error52, mapper = (issue2) => issue2.message) {
|
|
|
1414
1414
|
}
|
|
1415
1415
|
function toDotPath(_path) {
|
|
1416
1416
|
const segs = [];
|
|
1417
|
-
const
|
|
1418
|
-
for (const seg of
|
|
1417
|
+
const path18 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
1418
|
+
for (const seg of path18) {
|
|
1419
1419
|
if (typeof seg === "number")
|
|
1420
1420
|
segs.push(`[${seg}]`);
|
|
1421
1421
|
else if (typeof seg === "symbol")
|
|
@@ -14107,13 +14107,13 @@ function resolveRef(ref, ctx) {
|
|
|
14107
14107
|
if (!ref.startsWith("#")) {
|
|
14108
14108
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
14109
14109
|
}
|
|
14110
|
-
const
|
|
14111
|
-
if (
|
|
14110
|
+
const path18 = ref.slice(1).split("/").filter(Boolean);
|
|
14111
|
+
if (path18.length === 0) {
|
|
14112
14112
|
return ctx.rootSchema;
|
|
14113
14113
|
}
|
|
14114
14114
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
14115
|
-
if (
|
|
14116
|
-
const key =
|
|
14115
|
+
if (path18[0] === defsKey) {
|
|
14116
|
+
const key = path18[1];
|
|
14117
14117
|
if (!key || !ctx.defs[key]) {
|
|
14118
14118
|
throw new Error(`Reference not found: ${ref}`);
|
|
14119
14119
|
}
|
|
@@ -14690,12 +14690,24 @@ var threadUsageSnapshotSchema = external_exports.object({
|
|
|
14690
14690
|
});
|
|
14691
14691
|
}
|
|
14692
14692
|
});
|
|
14693
|
+
var usagePercentSchema = external_exports.number().finite().min(0).max(100);
|
|
14694
|
+
var accountCreditsProductUsageSchema = external_exports.object({
|
|
14695
|
+
product: external_exports.string().min(1),
|
|
14696
|
+
usagePercent: usagePercentSchema
|
|
14697
|
+
}).strict();
|
|
14698
|
+
var accountCreditsSnapshotSchema = external_exports.object({
|
|
14699
|
+
usedPercent: usagePercentSchema,
|
|
14700
|
+
resetsAt: external_exports.string().min(1).optional(),
|
|
14701
|
+
periodType: external_exports.enum(["weekly", "monthly", "unknown"]),
|
|
14702
|
+
productUsage: external_exports.array(accountCreditsProductUsageSchema).min(1).optional()
|
|
14703
|
+
}).strict();
|
|
14693
14704
|
var threadUsageInspectionParamsSchema = external_exports.object({
|
|
14694
14705
|
threadId: hostThreadIdSchema
|
|
14695
14706
|
}).strict();
|
|
14696
14707
|
var threadUsageInspectionSchema = external_exports.object({
|
|
14697
14708
|
threadId: hostThreadIdSchema,
|
|
14698
|
-
usage: threadUsageSnapshotSchema.nullable()
|
|
14709
|
+
usage: threadUsageSnapshotSchema.nullable(),
|
|
14710
|
+
accountCredits: accountCreditsSnapshotSchema.optional()
|
|
14699
14711
|
}).strict();
|
|
14700
14712
|
|
|
14701
14713
|
// packages/shared-contracts/dist/harness-models.js
|
|
@@ -19116,8 +19128,8 @@ var qU = v(function(BU) {
|
|
|
19116
19128
|
BU._globalThis = void 0;
|
|
19117
19129
|
BU._globalThis = typeof globalThis === "object" ? globalThis : global;
|
|
19118
19130
|
});
|
|
19119
|
-
var GU = v(function(
|
|
19120
|
-
var Axe =
|
|
19131
|
+
var GU = v(function(os7) {
|
|
19132
|
+
var Axe = os7 && os7.__createBinding || (Object.create ? function(e, t, r, n) {
|
|
19121
19133
|
if (n === void 0) n = r;
|
|
19122
19134
|
Object.defineProperty(e, n, { enumerable: true, get: function() {
|
|
19123
19135
|
return t[r];
|
|
@@ -19125,11 +19137,11 @@ var GU = v(function(os6) {
|
|
|
19125
19137
|
} : function(e, t, r, n) {
|
|
19126
19138
|
if (n === void 0) n = r;
|
|
19127
19139
|
e[n] = t[r];
|
|
19128
|
-
}), kxe =
|
|
19140
|
+
}), kxe = os7 && os7.__exportStar || function(e, t) {
|
|
19129
19141
|
for (var r in e) if (r !== "default" && !Object.prototype.hasOwnProperty.call(t, r)) Axe(t, e, r);
|
|
19130
19142
|
};
|
|
19131
|
-
Object.defineProperty(
|
|
19132
|
-
kxe(qU(),
|
|
19143
|
+
Object.defineProperty(os7, "__esModule", { value: true });
|
|
19144
|
+
kxe(qU(), os7);
|
|
19133
19145
|
});
|
|
19134
19146
|
var WU = v(function(is) {
|
|
19135
19147
|
var Oxe = is && is.__createBinding || (Object.create ? function(e, t, r, n) {
|
|
@@ -44826,16 +44838,16 @@ var AbstractApiClient = class {
|
|
|
44826
44838
|
* Shared POST leg of both C→S carriers (callUnary/respond): JSON body,
|
|
44827
44839
|
* optional default timeout merged with the caller's external signal, non-2xx → transport throw.
|
|
44828
44840
|
*/
|
|
44829
|
-
async postJson(
|
|
44841
|
+
async postJson(path18, body, signal, timeoutPolicy = "default") {
|
|
44830
44842
|
const requestSignal = timeoutPolicy === "default" ? signal === void 0 ? AbortSignal.timeout(this.timeoutMs) : AbortSignal.any([AbortSignal.timeout(this.timeoutMs), signal]) : signal;
|
|
44831
|
-
const response = await this.doFetch(new URL(
|
|
44843
|
+
const response = await this.doFetch(new URL(path18, this.resolveBase()), {
|
|
44832
44844
|
method: "POST",
|
|
44833
44845
|
headers: { "content-type": "application/json" },
|
|
44834
44846
|
body: JSON.stringify(body),
|
|
44835
44847
|
...requestSignal === void 0 ? {} : { signal: requestSignal }
|
|
44836
44848
|
});
|
|
44837
44849
|
if (!response.ok)
|
|
44838
|
-
throw new Error(`transport failure for ${
|
|
44850
|
+
throw new Error(`transport failure for ${path18}: HTTP ${response.status}`);
|
|
44839
44851
|
return response;
|
|
44840
44852
|
}
|
|
44841
44853
|
/**
|
|
@@ -44871,10 +44883,10 @@ var AbstractApiClient = class {
|
|
|
44871
44883
|
* either parse level is reported and skipped (one corrupt frame must not kill the stream; the
|
|
44872
44884
|
* client's gap detection covers whatever the frame carried).
|
|
44873
44885
|
*/
|
|
44874
|
-
async *readSse(
|
|
44875
|
-
const response = await this.doFetch(new URL(
|
|
44886
|
+
async *readSse(path18, signal, frameSchema, onOpen) {
|
|
44887
|
+
const response = await this.doFetch(new URL(path18, this.resolveBase()), { signal });
|
|
44876
44888
|
if (!response.ok || response.body === null)
|
|
44877
|
-
throw new Error(`transport failure for ${
|
|
44889
|
+
throw new Error(`transport failure for ${path18}: HTTP ${response.status}`);
|
|
44878
44890
|
onOpen?.();
|
|
44879
44891
|
const reader = response.body.getReader();
|
|
44880
44892
|
const decoder2 = new TextDecoder();
|
|
@@ -44898,7 +44910,7 @@ var AbstractApiClient = class {
|
|
|
44898
44910
|
full = serverRequestSchema.parse(JSON.parse(data));
|
|
44899
44911
|
frame = frameSchema.parse(full.payload);
|
|
44900
44912
|
} catch (error52) {
|
|
44901
|
-
console.error(`[apiproxy] dropping malformed SSE frame on ${
|
|
44913
|
+
console.error(`[apiproxy] dropping malformed SSE frame on ${path18}:`, error52);
|
|
44902
44914
|
continue;
|
|
44903
44915
|
}
|
|
44904
44916
|
this.onEnvelope(full);
|
|
@@ -45473,16 +45485,16 @@ var Diff = class {
|
|
|
45473
45485
|
}
|
|
45474
45486
|
}
|
|
45475
45487
|
}
|
|
45476
|
-
addToPath(
|
|
45477
|
-
const last =
|
|
45488
|
+
addToPath(path18, added, removed, oldPosInc, options) {
|
|
45489
|
+
const last = path18.lastComponent;
|
|
45478
45490
|
if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
|
|
45479
45491
|
return {
|
|
45480
|
-
oldPos:
|
|
45492
|
+
oldPos: path18.oldPos + oldPosInc,
|
|
45481
45493
|
lastComponent: { count: last.count + 1, added, removed, previousComponent: last.previousComponent }
|
|
45482
45494
|
};
|
|
45483
45495
|
} else {
|
|
45484
45496
|
return {
|
|
45485
|
-
oldPos:
|
|
45497
|
+
oldPos: path18.oldPos + oldPosInc,
|
|
45486
45498
|
lastComponent: { count: 1, added, removed, previousComponent: last }
|
|
45487
45499
|
};
|
|
45488
45500
|
}
|
|
@@ -46657,13 +46669,7 @@ var DeepSeekHarnessSession = class {
|
|
|
46657
46669
|
error: invalidState2(`DeepSeek Harness rejected Interaction: ${receipt.reason}`)
|
|
46658
46670
|
};
|
|
46659
46671
|
}
|
|
46660
|
-
active
|
|
46661
|
-
this.#emit({
|
|
46662
|
-
type: "interaction.closed",
|
|
46663
|
-
interactionId: command.interactionId,
|
|
46664
|
-
turnId: active.command.turnId,
|
|
46665
|
-
reason: "responded"
|
|
46666
|
-
});
|
|
46672
|
+
this.#closeHostInteraction(active, command.interactionId, "responded");
|
|
46667
46673
|
return { ok: true, value: { accepted: true } };
|
|
46668
46674
|
} catch (error52) {
|
|
46669
46675
|
return { ok: false, error: normalizedError(error52, "nativeFailure") };
|
|
@@ -46945,15 +46951,19 @@ var DeepSeekHarnessSession = class {
|
|
|
46945
46951
|
const matches = type === "approval" ? pending.type === "approval" && pending.approvalId === nativeId : pending.type === "question" && pending.rpcId === nativeId;
|
|
46946
46952
|
if (!matches)
|
|
46947
46953
|
continue;
|
|
46948
|
-
active
|
|
46949
|
-
this.#emit({
|
|
46950
|
-
type: "interaction.closed",
|
|
46951
|
-
interactionId,
|
|
46952
|
-
turnId: active.command.turnId,
|
|
46953
|
-
reason: "responded"
|
|
46954
|
-
});
|
|
46954
|
+
this.#closeHostInteraction(active, interactionId, "responded");
|
|
46955
46955
|
}
|
|
46956
46956
|
}
|
|
46957
|
+
#closeHostInteraction(active, interactionId, reason) {
|
|
46958
|
+
if (!active.interactions.delete(interactionId))
|
|
46959
|
+
return;
|
|
46960
|
+
this.#emit({
|
|
46961
|
+
type: "interaction.closed",
|
|
46962
|
+
interactionId,
|
|
46963
|
+
turnId: active.command.turnId,
|
|
46964
|
+
reason
|
|
46965
|
+
});
|
|
46966
|
+
}
|
|
46957
46967
|
#finishTurn(active, reason) {
|
|
46958
46968
|
const terminal = projectTurnReason(reason);
|
|
46959
46969
|
const itemOutcome3 = terminal.outcome.status === "succeeded" ? { status: "succeeded" } : terminal.outcome.status === "cancelled" ? {
|
|
@@ -46965,15 +46975,9 @@ var DeepSeekHarnessSession = class {
|
|
|
46965
46975
|
for (const tool of active.tools.values())
|
|
46966
46976
|
this.#completeItem(active, tool.item, itemOutcome3);
|
|
46967
46977
|
active.tools.clear();
|
|
46968
|
-
for (const
|
|
46969
|
-
this.#
|
|
46970
|
-
type: "interaction.closed",
|
|
46971
|
-
interactionId,
|
|
46972
|
-
turnId: active.command.turnId,
|
|
46973
|
-
reason: "cancelled"
|
|
46974
|
-
});
|
|
46978
|
+
for (const interactionId of [...active.interactions.keys()]) {
|
|
46979
|
+
this.#closeHostInteraction(active, interactionId, "cancelled");
|
|
46975
46980
|
}
|
|
46976
|
-
active.interactions.clear();
|
|
46977
46981
|
const nativeTurnRef2 = this.#nativeTurnRef(active.nativeTurn);
|
|
46978
46982
|
this.#turns.push({
|
|
46979
46983
|
nativeTurnRef: nativeTurnRef2,
|
|
@@ -47046,15 +47050,9 @@ var DeepSeekHarnessSession = class {
|
|
|
47046
47050
|
for (const tool of active.tools.values())
|
|
47047
47051
|
this.#completeItem(active, tool.item, outcome);
|
|
47048
47052
|
active.tools.clear();
|
|
47049
|
-
for (const
|
|
47050
|
-
this.#
|
|
47051
|
-
type: "interaction.closed",
|
|
47052
|
-
interactionId,
|
|
47053
|
-
turnId: active.command.turnId,
|
|
47054
|
-
reason: "cancelled"
|
|
47055
|
-
});
|
|
47053
|
+
for (const interactionId of [...active.interactions.keys()]) {
|
|
47054
|
+
this.#closeHostInteraction(active, interactionId, "cancelled");
|
|
47056
47055
|
}
|
|
47057
|
-
active.interactions.clear();
|
|
47058
47056
|
this.#emit({
|
|
47059
47057
|
type: "turn.completed",
|
|
47060
47058
|
turnId: active.command.turnId,
|
|
@@ -47248,7 +47246,7 @@ var packageMetadata3 = {
|
|
|
47248
47246
|
|
|
47249
47247
|
// packages/adapters/grok/dist/grok-adapter.js
|
|
47250
47248
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
47251
|
-
import
|
|
47249
|
+
import path10 from "node:path";
|
|
47252
47250
|
|
|
47253
47251
|
// packages/adapters/grok/dist/acp-transport.js
|
|
47254
47252
|
import { spawn as spawn3, spawnSync } from "node:child_process";
|
|
@@ -51605,8 +51603,8 @@ function transportEvent(update, metadata) {
|
|
|
51605
51603
|
function nativeSessionFile(options, sessionId, fileName) {
|
|
51606
51604
|
const environment = { ...process.env, ...options.environment };
|
|
51607
51605
|
const home = environment.HOME ?? environment.USERPROFILE ?? os3.homedir();
|
|
51608
|
-
const
|
|
51609
|
-
return path8.join(
|
|
51606
|
+
const grokHome2 = environment.GROK_HOME ?? path8.join(home, ".grok");
|
|
51607
|
+
return path8.join(grokHome2, "sessions", encodeURIComponent(path8.resolve(options.cwd)), sessionId, fileName);
|
|
51610
51608
|
}
|
|
51611
51609
|
function nativeHistoryPath(options, sessionId) {
|
|
51612
51610
|
return nativeSessionFile(options, sessionId, "updates.jsonl");
|
|
@@ -51904,7 +51902,16 @@ function terminalOutcome(stopReason) {
|
|
|
51904
51902
|
}
|
|
51905
51903
|
};
|
|
51906
51904
|
}
|
|
51905
|
+
var systemReminderPattern = /^\s*<system-reminder>[\s\S]*$/u;
|
|
51906
|
+
var taskCompletedTurnKeyPattern = /^task-completed-/u;
|
|
51907
|
+
function isSyntheticGrokUserText(text) {
|
|
51908
|
+
return systemReminderPattern.test(text);
|
|
51909
|
+
}
|
|
51910
|
+
function isSyntheticGrokTurnKey(nativeTurnKey3) {
|
|
51911
|
+
return taskCompletedTurnKeyPattern.test(nativeTurnKey3);
|
|
51912
|
+
}
|
|
51907
51913
|
function mapGrokReplay(replay, harnessId, sessionId, knownTurnRefs = []) {
|
|
51914
|
+
const knownByNativeKey = new Map(knownTurnRefs.filter((ref) => ref.harnessId === harnessId && ref.nativeSessionId === sessionId).map((ref) => [ref.nativeTurnKey, ref]));
|
|
51908
51915
|
const turns = [];
|
|
51909
51916
|
let input = "";
|
|
51910
51917
|
let items = [];
|
|
@@ -51935,13 +51942,11 @@ function mapGrokReplay(replay, harnessId, sessionId, knownTurnRefs = []) {
|
|
|
51935
51942
|
const completeTurn = (outcome, terminalKey) => {
|
|
51936
51943
|
if (input.length === 0)
|
|
51937
51944
|
return;
|
|
51938
|
-
const
|
|
51939
|
-
if (
|
|
51940
|
-
throw new Error("Known Grok Turn identity does not belong to the Native Session");
|
|
51941
|
-
}
|
|
51942
|
-
const stableKey = known?.nativeTurnKey ?? terminalKey ?? nativeTurnKey3;
|
|
51943
|
-
if (!stableKey)
|
|
51945
|
+
const reconstructedKey = terminalKey ?? nativeTurnKey3;
|
|
51946
|
+
if (!reconstructedKey)
|
|
51944
51947
|
throw new Error("Grok Native history Turn has no stable identity");
|
|
51948
|
+
const known = knownByNativeKey.get(reconstructedKey);
|
|
51949
|
+
const stableKey = known?.nativeTurnKey ?? reconstructedKey;
|
|
51945
51950
|
completeReasoning();
|
|
51946
51951
|
completeAgent();
|
|
51947
51952
|
completeTools();
|
|
@@ -51964,6 +51969,8 @@ function mapGrokReplay(replay, harnessId, sessionId, knownTurnRefs = []) {
|
|
|
51964
51969
|
};
|
|
51965
51970
|
for (const event of replay) {
|
|
51966
51971
|
if (event.type === "user.text") {
|
|
51972
|
+
if (isSyntheticGrokUserText(event.text))
|
|
51973
|
+
continue;
|
|
51967
51974
|
if (input.length > 0) {
|
|
51968
51975
|
completeTurn({
|
|
51969
51976
|
status: "unknown",
|
|
@@ -51982,6 +51989,8 @@ function mapGrokReplay(replay, harnessId, sessionId, knownTurnRefs = []) {
|
|
|
51982
51989
|
if (input.length === 0)
|
|
51983
51990
|
continue;
|
|
51984
51991
|
if (event.type === "turn.completed") {
|
|
51992
|
+
if (isSyntheticGrokTurnKey(event.nativeTurnKey))
|
|
51993
|
+
continue;
|
|
51985
51994
|
completeTurn(terminalOutcome(event.stopReason), event.nativeTurnKey);
|
|
51986
51995
|
} else if (event.type === "agent.text") {
|
|
51987
51996
|
if (!agent) {
|
|
@@ -52023,9 +52032,6 @@ function mapGrokReplay(replay, harnessId, sessionId, knownTurnRefs = []) {
|
|
|
52023
52032
|
}
|
|
52024
52033
|
}
|
|
52025
52034
|
completeTurn({ status: "unknown", reason: "Grok Native history has no terminal signal" });
|
|
52026
|
-
if (knownTurnRefs.length > turns.length) {
|
|
52027
|
-
throw new Error("Grok Native history is missing persisted Turns");
|
|
52028
|
-
}
|
|
52029
52035
|
return { turns };
|
|
52030
52036
|
}
|
|
52031
52037
|
|
|
@@ -52124,9 +52130,115 @@ function stateForGrokModel(modelState, nativeState, model = modelState.currentMo
|
|
|
52124
52130
|
};
|
|
52125
52131
|
}
|
|
52126
52132
|
|
|
52133
|
+
// packages/adapters/grok/dist/grok-credits.js
|
|
52134
|
+
import { readFile as readFile2 } from "node:fs/promises";
|
|
52135
|
+
import os4 from "node:os";
|
|
52136
|
+
import path9 from "node:path";
|
|
52137
|
+
var GROK_CREDITS_ENDPOINT = "https://cli-chat-proxy.grok.com/v1/billing?format=credits";
|
|
52138
|
+
var REQUEST_TIMEOUT_MS = 15e3;
|
|
52139
|
+
function isRecord11(value) {
|
|
52140
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
52141
|
+
}
|
|
52142
|
+
function finitePercent(value) {
|
|
52143
|
+
if (typeof value !== "number" || !Number.isFinite(value))
|
|
52144
|
+
return void 0;
|
|
52145
|
+
return Math.min(100, Math.max(0, value));
|
|
52146
|
+
}
|
|
52147
|
+
function nonNegativeNumber(value) {
|
|
52148
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value < 0)
|
|
52149
|
+
return void 0;
|
|
52150
|
+
return value;
|
|
52151
|
+
}
|
|
52152
|
+
function grokHome(environment) {
|
|
52153
|
+
return environment.GROK_HOME ?? path9.join(environment.HOME ?? environment.USERPROFILE ?? os4.homedir(), ".grok");
|
|
52154
|
+
}
|
|
52155
|
+
function periodTypeFrom(value) {
|
|
52156
|
+
if (typeof value !== "string")
|
|
52157
|
+
return "unknown";
|
|
52158
|
+
const normalized = value.toUpperCase();
|
|
52159
|
+
if (normalized.includes("WEEKLY"))
|
|
52160
|
+
return "weekly";
|
|
52161
|
+
if (normalized.includes("MONTHLY"))
|
|
52162
|
+
return "monthly";
|
|
52163
|
+
return "unknown";
|
|
52164
|
+
}
|
|
52165
|
+
function productUsageFrom(value) {
|
|
52166
|
+
if (!Array.isArray(value))
|
|
52167
|
+
return void 0;
|
|
52168
|
+
const products = value.flatMap((entry) => {
|
|
52169
|
+
if (!isRecord11(entry) || typeof entry.product !== "string")
|
|
52170
|
+
return [];
|
|
52171
|
+
const usagePercent = finitePercent(entry.usagePercent);
|
|
52172
|
+
return usagePercent === void 0 ? [] : [{ product: entry.product, usagePercent }];
|
|
52173
|
+
});
|
|
52174
|
+
return products.length > 0 ? products : void 0;
|
|
52175
|
+
}
|
|
52176
|
+
function parseGrokCreditsResponse(value, fetchedAt = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
52177
|
+
if (!isRecord11(value) || !isRecord11(value.config))
|
|
52178
|
+
return null;
|
|
52179
|
+
const config2 = value.config;
|
|
52180
|
+
const period = isRecord11(config2.currentPeriod) ? config2.currentPeriod : void 0;
|
|
52181
|
+
const resetsAt = (typeof period?.end === "string" && period.end.length > 0 ? period.end : void 0) ?? (typeof config2.billingPeriodEnd === "string" && config2.billingPeriodEnd.length > 0 ? config2.billingPeriodEnd : void 0);
|
|
52182
|
+
const onDemandCap = isRecord11(config2.onDemandCap) ? nonNegativeNumber(config2.onDemandCap.val) : void 0;
|
|
52183
|
+
const onDemandUsed = isRecord11(config2.onDemandUsed) ? nonNegativeNumber(config2.onDemandUsed.val) : void 0;
|
|
52184
|
+
const usedPercent = finitePercent(config2.creditUsagePercent) ?? (onDemandCap !== void 0 && onDemandCap > 0 && onDemandUsed !== void 0 ? Math.min(100, Math.max(0, onDemandUsed / onDemandCap * 100)) : resetsAt ? 0 : void 0);
|
|
52185
|
+
if (usedPercent === void 0)
|
|
52186
|
+
return null;
|
|
52187
|
+
const productUsage = productUsageFrom(config2.productUsage);
|
|
52188
|
+
return {
|
|
52189
|
+
usedPercent,
|
|
52190
|
+
periodType: periodTypeFrom(period?.type),
|
|
52191
|
+
fetchedAt,
|
|
52192
|
+
...resetsAt ? { resetsAt } : {},
|
|
52193
|
+
...productUsage ? { productUsage } : {}
|
|
52194
|
+
};
|
|
52195
|
+
}
|
|
52196
|
+
function selectAccessToken(auth, now) {
|
|
52197
|
+
if (!isRecord11(auth))
|
|
52198
|
+
return null;
|
|
52199
|
+
const entries = Object.entries(auth).filter(([, value]) => isRecord11(value) && typeof value.key === "string" && value.key.length > 0).sort(([left], [right]) => Number(right.startsWith("https://auth.x.ai")) - Number(left.startsWith("https://auth.x.ai")));
|
|
52200
|
+
for (const [, value] of entries) {
|
|
52201
|
+
if (!isRecord11(value) || typeof value.key !== "string")
|
|
52202
|
+
continue;
|
|
52203
|
+
if (typeof value.expires_at === "string") {
|
|
52204
|
+
const expiresAt = Date.parse(value.expires_at);
|
|
52205
|
+
if (Number.isFinite(expiresAt) && expiresAt <= now.getTime())
|
|
52206
|
+
continue;
|
|
52207
|
+
}
|
|
52208
|
+
return value.key;
|
|
52209
|
+
}
|
|
52210
|
+
return null;
|
|
52211
|
+
}
|
|
52212
|
+
async function fetchGrokCredits(input = {}) {
|
|
52213
|
+
try {
|
|
52214
|
+
const environment = input.environment ?? process.env;
|
|
52215
|
+
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
52216
|
+
const authPath = path9.join(grokHome(environment), "auth.json");
|
|
52217
|
+
const raw = input.readAuthFile ? await input.readAuthFile(authPath) : await readFile2(authPath, "utf8");
|
|
52218
|
+
const token = selectAccessToken(JSON.parse(raw), now);
|
|
52219
|
+
if (!token)
|
|
52220
|
+
return null;
|
|
52221
|
+
const fetchImpl = input.fetch ?? fetch;
|
|
52222
|
+
const response = await fetchImpl(GROK_CREDITS_ENDPOINT, {
|
|
52223
|
+
method: "GET",
|
|
52224
|
+
headers: {
|
|
52225
|
+
Authorization: `Bearer ${token}`,
|
|
52226
|
+
"x-xai-token-auth": "xai-grok-cli",
|
|
52227
|
+
Accept: "application/json"
|
|
52228
|
+
},
|
|
52229
|
+
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS)
|
|
52230
|
+
});
|
|
52231
|
+
if (!response.ok)
|
|
52232
|
+
return null;
|
|
52233
|
+
return parseGrokCreditsResponse(await response.json(), now.toISOString());
|
|
52234
|
+
} catch {
|
|
52235
|
+
return null;
|
|
52236
|
+
}
|
|
52237
|
+
}
|
|
52238
|
+
|
|
52127
52239
|
// packages/adapters/grok/dist/grok-usage.js
|
|
52128
52240
|
var USD_TICKS_PER_DOLLAR = 1e10;
|
|
52129
|
-
function
|
|
52241
|
+
function isRecord12(value) {
|
|
52130
52242
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
52131
52243
|
}
|
|
52132
52244
|
function optionalToken(value) {
|
|
@@ -52143,7 +52255,7 @@ function combineUsage(base, next) {
|
|
|
52143
52255
|
return base === null ? next : parseHostUsage({ ...base, ...next });
|
|
52144
52256
|
}
|
|
52145
52257
|
function usageFromNative(value) {
|
|
52146
|
-
if (!
|
|
52258
|
+
if (!isRecord12(value))
|
|
52147
52259
|
return null;
|
|
52148
52260
|
const inputTokens = optionalToken(value.inputTokens);
|
|
52149
52261
|
const cachedRead = optionalToken(value.cachedReadTokens);
|
|
@@ -52170,7 +52282,7 @@ function usageFromPrompt(response) {
|
|
|
52170
52282
|
return response.usage ? usageFromNative(response.usage) : null;
|
|
52171
52283
|
}
|
|
52172
52284
|
function usageFromSignals(value) {
|
|
52173
|
-
if (!
|
|
52285
|
+
if (!isRecord12(value))
|
|
52174
52286
|
return null;
|
|
52175
52287
|
try {
|
|
52176
52288
|
return parseHostUsage({
|
|
@@ -52181,21 +52293,80 @@ function usageFromSignals(value) {
|
|
|
52181
52293
|
return null;
|
|
52182
52294
|
}
|
|
52183
52295
|
}
|
|
52184
|
-
|
|
52185
|
-
|
|
52186
|
-
|
|
52296
|
+
var summedUsageFields = [
|
|
52297
|
+
"inputTokens",
|
|
52298
|
+
"cachedInputTokens",
|
|
52299
|
+
"cacheWriteInputTokens",
|
|
52300
|
+
"outputTokens",
|
|
52301
|
+
"reasoningOutputTokens",
|
|
52302
|
+
"totalTokens"
|
|
52303
|
+
];
|
|
52304
|
+
function nativeCostTicks(value) {
|
|
52305
|
+
if (!isRecord12(value))
|
|
52306
|
+
return void 0;
|
|
52307
|
+
const ticks = value.costUsdTicks;
|
|
52308
|
+
if (typeof ticks !== "number" || !Number.isSafeInteger(ticks) || ticks < 0)
|
|
52309
|
+
return void 0;
|
|
52310
|
+
return ticks;
|
|
52311
|
+
}
|
|
52312
|
+
function historyTurnKey(event, index) {
|
|
52313
|
+
const key = event.nativeTurnKey;
|
|
52314
|
+
if (typeof key === "string" && key.startsWith("task-completed-"))
|
|
52315
|
+
return null;
|
|
52316
|
+
return typeof key === "string" && key.length > 0 ? key : `anon-${index}`;
|
|
52317
|
+
}
|
|
52318
|
+
function sessionUsageFromHistory(events) {
|
|
52319
|
+
const latestByKey = /* @__PURE__ */ new Map();
|
|
52320
|
+
let lastCacheHitRatePercent;
|
|
52321
|
+
let index = 0;
|
|
52322
|
+
for (const event of events) {
|
|
52187
52323
|
if (event?.type !== "turn.completed")
|
|
52188
52324
|
continue;
|
|
52325
|
+
const key = historyTurnKey(event, index);
|
|
52326
|
+
index += 1;
|
|
52327
|
+
if (key === null)
|
|
52328
|
+
continue;
|
|
52189
52329
|
const usage = usageFromNative(event.usage);
|
|
52190
|
-
if (usage)
|
|
52191
|
-
|
|
52330
|
+
if (!usage)
|
|
52331
|
+
continue;
|
|
52332
|
+
const ticks2 = nativeCostTicks(event.usage);
|
|
52333
|
+
latestByKey.set(key, ticks2 === void 0 ? { usage } : { usage, ticks: ticks2 });
|
|
52334
|
+
if (usage.cacheHitRatePercent !== void 0) {
|
|
52335
|
+
lastCacheHitRatePercent = usage.cacheHitRatePercent;
|
|
52336
|
+
}
|
|
52337
|
+
}
|
|
52338
|
+
if (latestByKey.size === 0)
|
|
52339
|
+
return null;
|
|
52340
|
+
const totals = {};
|
|
52341
|
+
let ticks = 0;
|
|
52342
|
+
let hasTicks = false;
|
|
52343
|
+
for (const entry of latestByKey.values()) {
|
|
52344
|
+
for (const field of summedUsageFields) {
|
|
52345
|
+
const value = entry.usage[field];
|
|
52346
|
+
if (value === void 0)
|
|
52347
|
+
continue;
|
|
52348
|
+
totals[field] = (totals[field] ?? 0) + value;
|
|
52349
|
+
}
|
|
52350
|
+
if (entry.ticks === void 0)
|
|
52351
|
+
continue;
|
|
52352
|
+
ticks += entry.ticks;
|
|
52353
|
+
hasTicks = true;
|
|
52354
|
+
}
|
|
52355
|
+
const totalCostUsd = hasTicks ? optionalCostUsd(ticks) : void 0;
|
|
52356
|
+
try {
|
|
52357
|
+
return parseHostUsage({
|
|
52358
|
+
...totals,
|
|
52359
|
+
...totalCostUsd !== void 0 ? { totalCostUsd } : {},
|
|
52360
|
+
...lastCacheHitRatePercent !== void 0 ? { cacheHitRatePercent: lastCacheHitRatePercent } : {}
|
|
52361
|
+
});
|
|
52362
|
+
} catch {
|
|
52363
|
+
return null;
|
|
52192
52364
|
}
|
|
52193
|
-
return null;
|
|
52194
52365
|
}
|
|
52195
52366
|
function usageFromUpdate(update, metadata, contextWindowTokens) {
|
|
52196
52367
|
try {
|
|
52197
52368
|
if (update?.sessionUpdate === "usage_update") {
|
|
52198
|
-
const cost =
|
|
52369
|
+
const cost = isRecord12(update.cost) ? update.cost : null;
|
|
52199
52370
|
return parseHostUsage({
|
|
52200
52371
|
contextUsedTokens: update.used,
|
|
52201
52372
|
contextWindowTokens: update.size,
|
|
@@ -52229,7 +52400,7 @@ function capabilitiesForModels(modelState) {
|
|
|
52229
52400
|
}
|
|
52230
52401
|
var DEFAULT_CLOSE_TIMEOUT_MS3 = 2e3;
|
|
52231
52402
|
var DEFAULT_TOOL_OUTPUT_LIMIT3 = 64e3;
|
|
52232
|
-
function
|
|
52403
|
+
function isRecord13(value) {
|
|
52233
52404
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
52234
52405
|
}
|
|
52235
52406
|
function invalidState3(message3) {
|
|
@@ -52264,7 +52435,7 @@ function contentText2(content) {
|
|
|
52264
52435
|
if (!content)
|
|
52265
52436
|
return "";
|
|
52266
52437
|
return content.flatMap((entry) => {
|
|
52267
|
-
if (!
|
|
52438
|
+
if (!isRecord13(entry) || entry.type !== "content" || !isRecord13(entry.content))
|
|
52268
52439
|
return [];
|
|
52269
52440
|
return entry.content.type === "text" && typeof entry.content.text === "string" ? [entry.content.text] : [];
|
|
52270
52441
|
}).join("\n");
|
|
@@ -52318,6 +52489,7 @@ var GrokHarnessSession = class {
|
|
|
52318
52489
|
#cwd;
|
|
52319
52490
|
#modelState;
|
|
52320
52491
|
#onClosed;
|
|
52492
|
+
#refreshCredits;
|
|
52321
52493
|
#randomUUID;
|
|
52322
52494
|
#snapshot;
|
|
52323
52495
|
#toolOutputLimit;
|
|
@@ -52333,6 +52505,7 @@ var GrokHarnessSession = class {
|
|
|
52333
52505
|
this.#transport = transport;
|
|
52334
52506
|
this.#modelState = modelState;
|
|
52335
52507
|
this.#onClosed = onClosed;
|
|
52508
|
+
this.#refreshCredits = options.refreshCredits;
|
|
52336
52509
|
this.#closeTimeoutMs = options.closeTimeoutMs;
|
|
52337
52510
|
this.#randomUUID = options.randomUUID;
|
|
52338
52511
|
this.#toolOutputLimit = options.toolOutputLimit;
|
|
@@ -52599,11 +52772,7 @@ var GrokHarnessSession = class {
|
|
|
52599
52772
|
this.#startTool(active, event);
|
|
52600
52773
|
else if (event.type === "tool.update")
|
|
52601
52774
|
this.#updateTool(active, event);
|
|
52602
|
-
else if (event.type === "turn.completed")
|
|
52603
|
-
const usage = usageFromNative(event.usage);
|
|
52604
|
-
if (usage)
|
|
52605
|
-
this.#publishUsage(usage, active.command.turnId);
|
|
52606
|
-
} else if (event.type === "usage")
|
|
52775
|
+
else if (event.type === "usage" || event.type === "turn.completed")
|
|
52607
52776
|
return;
|
|
52608
52777
|
}
|
|
52609
52778
|
#appendAgent(active, text, messageId) {
|
|
@@ -52740,7 +52909,8 @@ var GrokHarnessSession = class {
|
|
|
52740
52909
|
outcome = { status: "failed", error: normalizeError(error52, "protocolError") };
|
|
52741
52910
|
}
|
|
52742
52911
|
}
|
|
52743
|
-
this.#
|
|
52912
|
+
await this.#refreshCredits().catch(() => void 0);
|
|
52913
|
+
this.#finish(active, outcome, sessionUsageFromHistory(history) ?? (response ? usageFromPrompt(response) : null), nativeTurnRef2);
|
|
52744
52914
|
}
|
|
52745
52915
|
#finish(active, outcome, usage = null, nativeTurnRef2) {
|
|
52746
52916
|
if (this.#active !== active)
|
|
@@ -52827,22 +52997,53 @@ var GrokAdapter = class {
|
|
|
52827
52997
|
harnessId = grokHarnessId;
|
|
52828
52998
|
#closeTimeoutMs;
|
|
52829
52999
|
#dependencies;
|
|
53000
|
+
#environment;
|
|
53001
|
+
#fetchCredits;
|
|
52830
53002
|
#inspectionCache = /* @__PURE__ */ new Map();
|
|
52831
53003
|
#sessions = /* @__PURE__ */ new Set();
|
|
52832
53004
|
#toolOutputLimit;
|
|
52833
53005
|
#closePromise = null;
|
|
53006
|
+
#credits = null;
|
|
53007
|
+
#creditsRefresh = null;
|
|
52834
53008
|
constructor(options = {}, dependencies) {
|
|
52835
53009
|
this.#closeTimeoutMs = options.closeTimeoutMs ?? DEFAULT_CLOSE_TIMEOUT_MS3;
|
|
53010
|
+
this.#environment = options.environment;
|
|
52836
53011
|
this.#toolOutputLimit = options.toolOutputLimit ?? DEFAULT_TOOL_OUTPUT_LIMIT3;
|
|
52837
53012
|
this.#dependencies = dependencies ?? {
|
|
52838
53013
|
randomUUID: randomUUID3,
|
|
52839
53014
|
createTransport: (transportOptions) => new GrokAcpTransport({ ...options, ...transportOptions })
|
|
52840
53015
|
};
|
|
53016
|
+
this.#fetchCredits = this.#dependencies.fetchCredits ?? ((input) => fetchGrokCredits(input.environment ? { environment: input.environment } : this.#environment ? { environment: this.#environment } : {}));
|
|
53017
|
+
}
|
|
53018
|
+
credits() {
|
|
53019
|
+
return this.#credits;
|
|
53020
|
+
}
|
|
53021
|
+
refreshCredits() {
|
|
53022
|
+
if (this.#closePromise)
|
|
53023
|
+
return Promise.resolve(this.#credits);
|
|
53024
|
+
if (this.#creditsRefresh)
|
|
53025
|
+
return this.#creditsRefresh;
|
|
53026
|
+
this.#creditsRefresh = this.#loadCredits().finally(() => {
|
|
53027
|
+
this.#creditsRefresh = null;
|
|
53028
|
+
});
|
|
53029
|
+
return this.#creditsRefresh;
|
|
53030
|
+
}
|
|
53031
|
+
#scheduleCreditsRefresh() {
|
|
53032
|
+
void this.refreshCredits();
|
|
53033
|
+
}
|
|
53034
|
+
async #loadCredits() {
|
|
53035
|
+
try {
|
|
53036
|
+
const snapshot = await this.#fetchCredits(this.#environment ? { environment: this.#environment } : {});
|
|
53037
|
+
if (snapshot)
|
|
53038
|
+
this.#credits = snapshot;
|
|
53039
|
+
} catch {
|
|
53040
|
+
}
|
|
53041
|
+
return this.#credits;
|
|
52841
53042
|
}
|
|
52842
53043
|
async inspect(input = {}) {
|
|
52843
53044
|
if (this.#closePromise)
|
|
52844
53045
|
return { status: "unavailable", error: invalidState3("Grok Adapter is closed") };
|
|
52845
|
-
const cwd =
|
|
53046
|
+
const cwd = path10.resolve(input.cwd ?? process.cwd());
|
|
52846
53047
|
if (!input.refresh) {
|
|
52847
53048
|
const cached2 = this.#inspectionCache.get(cwd);
|
|
52848
53049
|
if (cached2)
|
|
@@ -52862,6 +53063,7 @@ var GrokAdapter = class {
|
|
|
52862
53063
|
capabilities: capabilitiesForModels(modelState)
|
|
52863
53064
|
};
|
|
52864
53065
|
this.#inspectionCache.set(cwd, ready);
|
|
53066
|
+
this.#scheduleCreditsRefresh();
|
|
52865
53067
|
return ready;
|
|
52866
53068
|
} catch (error52) {
|
|
52867
53069
|
await transport?.close().catch(() => void 0);
|
|
@@ -52900,7 +53102,7 @@ var GrokAdapter = class {
|
|
|
52900
53102
|
}
|
|
52901
53103
|
};
|
|
52902
53104
|
}
|
|
52903
|
-
const cwd =
|
|
53105
|
+
const cwd = path10.resolve(input.cwd);
|
|
52904
53106
|
const parsedRef = input.kind === "resume" ? nativeSessionRefSchema.safeParse(input.nativeRef) : null;
|
|
52905
53107
|
if (parsedRef && (!parsedRef.success || parsedRef.data.harnessId !== this.harnessId)) {
|
|
52906
53108
|
return {
|
|
@@ -52938,17 +53140,19 @@ var GrokAdapter = class {
|
|
|
52938
53140
|
}
|
|
52939
53141
|
}
|
|
52940
53142
|
const history = await transport.getHistory();
|
|
52941
|
-
const initialUsage = input.kind === "resume" ? combineUsage(
|
|
53143
|
+
const initialUsage = input.kind === "resume" ? combineUsage(sessionUsageFromHistory(history), usageFromSignals(opened.signals)) : null;
|
|
52942
53144
|
const openedSession = new GrokHarnessSession(cwd, transport, opened, modelState, () => this.#sessions.delete(openedSession), {
|
|
52943
53145
|
closeTimeoutMs: this.#closeTimeoutMs,
|
|
52944
53146
|
history,
|
|
52945
53147
|
initialUsage,
|
|
52946
53148
|
...input.kind === "resume" && input.knownTurnRefs ? { knownTurnRefs: input.knownTurnRefs } : {},
|
|
52947
53149
|
randomUUID: this.#dependencies.randomUUID,
|
|
53150
|
+
refreshCredits: () => this.refreshCredits(),
|
|
52948
53151
|
toolOutputLimit: this.#toolOutputLimit
|
|
52949
53152
|
});
|
|
52950
53153
|
session = openedSession;
|
|
52951
53154
|
this.#sessions.add(openedSession);
|
|
53155
|
+
this.#scheduleCreditsRefresh();
|
|
52952
53156
|
return { ok: true, value: openedSession };
|
|
52953
53157
|
} catch (error52) {
|
|
52954
53158
|
await transport.close().catch(() => void 0);
|
|
@@ -53086,7 +53290,7 @@ function normalizePiModelCatalog(nativeModels, effectiveModel, thinkingLevels, e
|
|
|
53086
53290
|
|
|
53087
53291
|
// packages/adapters/pi/dist/pi-history.js
|
|
53088
53292
|
var piHarnessId = harnessIdSchema.parse("pi");
|
|
53089
|
-
function
|
|
53293
|
+
function isRecord14(value) {
|
|
53090
53294
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
53091
53295
|
}
|
|
53092
53296
|
function textContent(value) {
|
|
@@ -53094,12 +53298,12 @@ function textContent(value) {
|
|
|
53094
53298
|
return value;
|
|
53095
53299
|
if (!Array.isArray(value))
|
|
53096
53300
|
return "";
|
|
53097
|
-
return value.filter((part) =>
|
|
53301
|
+
return value.filter((part) => isRecord14(part) && part.type === "text" && typeof part.text === "string").map((part) => part.text).join("");
|
|
53098
53302
|
}
|
|
53099
53303
|
function thinkingContent(value) {
|
|
53100
53304
|
if (!Array.isArray(value))
|
|
53101
53305
|
return "";
|
|
53102
|
-
return value.filter((part) =>
|
|
53306
|
+
return value.filter((part) => isRecord14(part) && part.type === "thinking" && typeof part.thinking === "string").map((part) => part.thinking).join("");
|
|
53103
53307
|
}
|
|
53104
53308
|
function validatedEntry(value) {
|
|
53105
53309
|
if (typeof value.id !== "string" || value.id.length === 0 || value.parentId !== null && typeof value.parentId !== "string" || typeof value.type !== "string") {
|
|
@@ -53130,7 +53334,7 @@ function activePiEntries(history) {
|
|
|
53130
53334
|
return reversed.reverse();
|
|
53131
53335
|
}
|
|
53132
53336
|
function message(entry) {
|
|
53133
|
-
return entry.type === "message" &&
|
|
53337
|
+
return entry.type === "message" && isRecord14(entry.message) ? entry.message : null;
|
|
53134
53338
|
}
|
|
53135
53339
|
function messageRole(entry) {
|
|
53136
53340
|
const value = message(entry)?.role;
|
|
@@ -53192,7 +53396,7 @@ function snapshotItems(entries, outcome) {
|
|
|
53192
53396
|
let projectedText = false;
|
|
53193
53397
|
let projectedReasoning = false;
|
|
53194
53398
|
for (const [ordinal, part] of content.entries()) {
|
|
53195
|
-
if (!
|
|
53399
|
+
if (!isRecord14(part))
|
|
53196
53400
|
continue;
|
|
53197
53401
|
if (part.type === "thinking" && !projectedReasoning && reasoning.length > 0) {
|
|
53198
53402
|
const item2 = {
|
|
@@ -53384,12 +53588,12 @@ async function rollbackPiLastTurn(transport, sourceSessionId, cwd) {
|
|
|
53384
53588
|
// packages/adapters/pi/dist/pi-rpc-session.js
|
|
53385
53589
|
import { spawn as spawn4, spawnSync as spawnSync2 } from "node:child_process";
|
|
53386
53590
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
53387
|
-
import
|
|
53591
|
+
import path12 from "node:path";
|
|
53388
53592
|
|
|
53389
53593
|
// packages/adapters/pi/dist/command.js
|
|
53390
53594
|
import { accessSync as accessSync2, constants as constants2, readdirSync as readdirSync2, statSync as statSync3 } from "node:fs";
|
|
53391
|
-
import
|
|
53392
|
-
import
|
|
53595
|
+
import os5 from "node:os";
|
|
53596
|
+
import path11 from "node:path";
|
|
53393
53597
|
function environmentValue2(environment, name) {
|
|
53394
53598
|
return Object.entries(environment).find(([key]) => key.toLowerCase() === name.toLowerCase())?.[1];
|
|
53395
53599
|
}
|
|
@@ -53402,34 +53606,35 @@ function isExecutable3(filePath, platform) {
|
|
|
53402
53606
|
}
|
|
53403
53607
|
}
|
|
53404
53608
|
function pathCandidates(command, platform, environment) {
|
|
53405
|
-
const targetPath = platform === "win32" ?
|
|
53609
|
+
const targetPath = platform === "win32" ? path11.win32 : path11.posix;
|
|
53406
53610
|
if (targetPath.isAbsolute(command) || command.includes("/") || command.includes("\\")) {
|
|
53407
53611
|
return [command];
|
|
53408
53612
|
}
|
|
53409
53613
|
const extensions = platform === "win32" && targetPath.extname(command) === "" ? (environmentValue2(environment, "PATHEXT") ?? ".COM;.EXE;.BAT;.CMD").split(";").map((extension) => extension.trim()).filter(Boolean) : [""];
|
|
53410
53614
|
return (environmentValue2(environment, "PATH") ?? "").split(targetPath.delimiter).map((directory) => directory.trim().replace(/^"|"$/gu, "")).filter(Boolean).flatMap((directory) => extensions.map((extension) => targetPath.join(directory, command + extension)));
|
|
53411
53615
|
}
|
|
53412
|
-
function nvmCandidates2(homeDirectory, executableName) {
|
|
53413
|
-
const versionsDirectory =
|
|
53616
|
+
function nvmCandidates2(homeDirectory, executableName, targetPath) {
|
|
53617
|
+
const versionsDirectory = targetPath.join(homeDirectory, ".nvm", "versions", "node");
|
|
53414
53618
|
try {
|
|
53415
|
-
return readdirSync2(versionsDirectory, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort((left, right) => right.localeCompare(left, void 0, { numeric: true })).map((version2) =>
|
|
53619
|
+
return readdirSync2(versionsDirectory, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort((left, right) => right.localeCompare(left, void 0, { numeric: true })).map((version2) => targetPath.join(versionsDirectory, version2, "bin", executableName));
|
|
53416
53620
|
} catch {
|
|
53417
53621
|
return [];
|
|
53418
53622
|
}
|
|
53419
53623
|
}
|
|
53420
53624
|
function userInstallCandidates2(platform, environment, homeDirectory) {
|
|
53625
|
+
const targetPath = platform === "win32" ? path11.win32 : path11.posix;
|
|
53421
53626
|
if (platform === "win32") {
|
|
53422
|
-
const appData = environment.APPDATA ??
|
|
53627
|
+
const appData = environment.APPDATA ?? targetPath.join(homeDirectory, "AppData", "Roaming");
|
|
53423
53628
|
return [
|
|
53424
|
-
|
|
53425
|
-
|
|
53426
|
-
|
|
53629
|
+
targetPath.join(appData, "npm", "pi.cmd"),
|
|
53630
|
+
targetPath.join(homeDirectory, ".local", "bin", "pi.exe"),
|
|
53631
|
+
targetPath.join(homeDirectory, ".local", "bin", "pi.cmd")
|
|
53427
53632
|
];
|
|
53428
53633
|
}
|
|
53429
53634
|
return [
|
|
53430
|
-
|
|
53431
|
-
|
|
53432
|
-
...nvmCandidates2(homeDirectory, "pi"),
|
|
53635
|
+
targetPath.join(homeDirectory, ".npm-global", "bin", "pi"),
|
|
53636
|
+
targetPath.join(homeDirectory, ".local", "bin", "pi"),
|
|
53637
|
+
...nvmCandidates2(homeDirectory, "pi", targetPath),
|
|
53433
53638
|
"/opt/homebrew/bin/pi",
|
|
53434
53639
|
"/usr/local/bin/pi"
|
|
53435
53640
|
];
|
|
@@ -53438,7 +53643,7 @@ function resolvePiExecutable(input, dependencies = {}) {
|
|
|
53438
53643
|
const platform = dependencies.platform ?? process.platform;
|
|
53439
53644
|
const configuredCommand = input.command ?? input.environment.PI_COMMAND;
|
|
53440
53645
|
const command = configuredCommand ?? "pi";
|
|
53441
|
-
const homeDirectory = dependencies.homeDirectory ?? input.environment.HOME ?? input.environment.USERPROFILE ??
|
|
53646
|
+
const homeDirectory = dependencies.homeDirectory ?? input.environment.HOME ?? input.environment.USERPROFILE ?? os5.homedir();
|
|
53442
53647
|
const candidates2 = [
|
|
53443
53648
|
...pathCandidates(command, platform, input.environment),
|
|
53444
53649
|
...configuredCommand ? [] : userInstallCandidates2(platform, input.environment, homeDirectory)
|
|
@@ -53449,7 +53654,7 @@ function resolvePiExecutable(input, dependencies = {}) {
|
|
|
53449
53654
|
function withNodeRuntimeOnPath2(environment, runtimeExecutable = process.execPath, platform = process.platform) {
|
|
53450
53655
|
const pathKey = Object.keys(environment).find((name) => name.toLowerCase() === "path") ?? "PATH";
|
|
53451
53656
|
const delimiter = platform === "win32" ? ";" : ":";
|
|
53452
|
-
const runtimeDirectory =
|
|
53657
|
+
const runtimeDirectory = path11.dirname(runtimeExecutable);
|
|
53453
53658
|
const directories = (environment[pathKey] ?? "").split(delimiter).filter(Boolean);
|
|
53454
53659
|
const equal = platform === "win32" ? (value) => value.toLowerCase() : (value) => value;
|
|
53455
53660
|
if (!directories.some((directory) => equal(directory) === equal(runtimeDirectory))) {
|
|
@@ -53459,14 +53664,14 @@ function withNodeRuntimeOnPath2(environment, runtimeExecutable = process.execPat
|
|
|
53459
53664
|
}
|
|
53460
53665
|
|
|
53461
53666
|
// packages/adapters/pi/dist/pi-usage.js
|
|
53462
|
-
function
|
|
53667
|
+
function isRecord15(value) {
|
|
53463
53668
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
53464
53669
|
}
|
|
53465
53670
|
function nonNegativeSafeInteger2(value) {
|
|
53466
53671
|
return typeof value === "number" && Number.isSafeInteger(value) && value >= 0 ? value : null;
|
|
53467
53672
|
}
|
|
53468
53673
|
function optionalPiCacheHitRatePercent(value) {
|
|
53469
|
-
if (!
|
|
53674
|
+
if (!isRecord15(value) || value.role !== "assistant" || !isRecord15(value.usage))
|
|
53470
53675
|
return null;
|
|
53471
53676
|
const input = nonNegativeSafeInteger2(value.usage.input);
|
|
53472
53677
|
const cacheRead = nonNegativeSafeInteger2(value.usage.cacheRead);
|
|
@@ -53479,20 +53684,20 @@ function optionalPiCacheHitRatePercent(value) {
|
|
|
53479
53684
|
function latestPiCacheHitRatePercent(history) {
|
|
53480
53685
|
let latest = null;
|
|
53481
53686
|
for (const entry of activePiEntries(history)) {
|
|
53482
|
-
if (entry.type === "message" &&
|
|
53687
|
+
if (entry.type === "message" && isRecord15(entry.message) && entry.message.role === "assistant") {
|
|
53483
53688
|
latest = optionalPiCacheHitRatePercent(entry.message);
|
|
53484
53689
|
}
|
|
53485
53690
|
}
|
|
53486
53691
|
return latest;
|
|
53487
53692
|
}
|
|
53488
53693
|
function responseData(response, operation) {
|
|
53489
|
-
if (!
|
|
53694
|
+
if (!isRecord15(response.data)) {
|
|
53490
53695
|
throw new Error(`Pi RPC ${operation} response has no data`);
|
|
53491
53696
|
}
|
|
53492
53697
|
return response.data;
|
|
53493
53698
|
}
|
|
53494
53699
|
function contextUsage(value) {
|
|
53495
|
-
if (!
|
|
53700
|
+
if (!isRecord15(value))
|
|
53496
53701
|
throw new Error("Pi RPC context Usage is invalid");
|
|
53497
53702
|
return parseHostUsage({
|
|
53498
53703
|
contextUsedTokens: value.tokens,
|
|
@@ -53502,15 +53707,15 @@ function contextUsage(value) {
|
|
|
53502
53707
|
function parsePiSessionUsage(response) {
|
|
53503
53708
|
const data = responseData(response, "Session stats");
|
|
53504
53709
|
const tokens = data.tokens;
|
|
53505
|
-
if (tokens !== void 0 && !
|
|
53710
|
+
if (tokens !== void 0 && !isRecord15(tokens)) {
|
|
53506
53711
|
throw new Error("Pi RPC Session stats tokens are invalid");
|
|
53507
53712
|
}
|
|
53508
53713
|
return parseHostUsage({
|
|
53509
|
-
...
|
|
53510
|
-
...
|
|
53511
|
-
...
|
|
53512
|
-
...
|
|
53513
|
-
...
|
|
53714
|
+
...isRecord15(tokens) && tokens.input !== void 0 ? { inputTokens: tokens.input } : {},
|
|
53715
|
+
...isRecord15(tokens) && tokens.cacheRead !== void 0 ? { cachedInputTokens: tokens.cacheRead } : {},
|
|
53716
|
+
...isRecord15(tokens) && tokens.cacheWrite !== void 0 ? { cacheWriteInputTokens: tokens.cacheWrite } : {},
|
|
53717
|
+
...isRecord15(tokens) && tokens.output !== void 0 ? { outputTokens: tokens.output } : {},
|
|
53718
|
+
...isRecord15(tokens) && tokens.total !== void 0 ? { totalTokens: tokens.total } : {},
|
|
53514
53719
|
...data.cost !== void 0 ? { totalCostUsd: data.cost } : {},
|
|
53515
53720
|
...data.contextUsage !== void 0 ? contextUsage(data.contextUsage) : {}
|
|
53516
53721
|
});
|
|
@@ -53533,7 +53738,7 @@ function optionalPiStateContextUsage(value) {
|
|
|
53533
53738
|
import { open, realpath } from "node:fs/promises";
|
|
53534
53739
|
var MAX_SESSION_HEADER_BYTES = 64 * 1024;
|
|
53535
53740
|
var utf8Decoder = new TextDecoder("utf-8", { fatal: true });
|
|
53536
|
-
function
|
|
53741
|
+
function isRecord16(value) {
|
|
53537
53742
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
53538
53743
|
}
|
|
53539
53744
|
async function readPiSessionHeader(sessionFile) {
|
|
@@ -53553,7 +53758,7 @@ async function readPiSessionHeader(sessionFile) {
|
|
|
53553
53758
|
} catch {
|
|
53554
53759
|
throw new Error("Pi Session header is not valid JSON");
|
|
53555
53760
|
}
|
|
53556
|
-
if (!
|
|
53761
|
+
if (!isRecord16(parsed) || parsed.type !== "session" || typeof parsed.id !== "string" || parsed.id.length === 0 || typeof parsed.cwd !== "string" || parsed.cwd.length === 0) {
|
|
53557
53762
|
throw new Error("Pi Session header is invalid");
|
|
53558
53763
|
}
|
|
53559
53764
|
return { type: "session", id: parsed.id, cwd: parsed.cwd };
|
|
@@ -53595,7 +53800,7 @@ var PiRpcUnsupportedCommandError = class extends Error {
|
|
|
53595
53800
|
}
|
|
53596
53801
|
};
|
|
53597
53802
|
var textDecoder = new TextDecoder("utf-8", { fatal: true });
|
|
53598
|
-
function
|
|
53803
|
+
function isRecord17(value) {
|
|
53599
53804
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
53600
53805
|
}
|
|
53601
53806
|
function message2(value) {
|
|
@@ -53607,13 +53812,13 @@ function nonBlankString2(value) {
|
|
|
53607
53812
|
function parseNativeModel(value, context) {
|
|
53608
53813
|
if (value === null || value === void 0)
|
|
53609
53814
|
return null;
|
|
53610
|
-
if (!
|
|
53815
|
+
if (!isRecord17(value) || !nonBlankString2(value.provider) || !nonBlankString2(value.id)) {
|
|
53611
53816
|
throw new PiRpcFaultError("protocolError", `Pi RPC returned an invalid ${context} Model`);
|
|
53612
53817
|
}
|
|
53613
53818
|
return { provider: value.provider, id: value.id };
|
|
53614
53819
|
}
|
|
53615
53820
|
function sessionStateData(response) {
|
|
53616
|
-
const data =
|
|
53821
|
+
const data = isRecord17(response.data) ? response.data : null;
|
|
53617
53822
|
if (!data)
|
|
53618
53823
|
throw new PiRpcFaultError("protocolError", "Pi RPC state response has no data");
|
|
53619
53824
|
return data;
|
|
@@ -53645,13 +53850,13 @@ function parseSessionStreaming(response) {
|
|
|
53645
53850
|
return isStreaming;
|
|
53646
53851
|
}
|
|
53647
53852
|
function parseSessionHistory(response) {
|
|
53648
|
-
const data =
|
|
53853
|
+
const data = isRecord17(response.data) ? response.data : null;
|
|
53649
53854
|
if (!data || !Array.isArray(data.entries)) {
|
|
53650
53855
|
throw new PiRpcFaultError("protocolError", "Pi RPC entries response has no Entries");
|
|
53651
53856
|
}
|
|
53652
53857
|
const entries = data.entries.map((entry) => {
|
|
53653
53858
|
const parsed = jsonValueSchema.safeParse(entry);
|
|
53654
|
-
if (!parsed.success || !
|
|
53859
|
+
if (!parsed.success || !isRecord17(parsed.data)) {
|
|
53655
53860
|
throw new PiRpcFaultError("protocolError", "Pi RPC entries response contains an invalid Entry");
|
|
53656
53861
|
}
|
|
53657
53862
|
return parsed.data;
|
|
@@ -53662,7 +53867,7 @@ function parseSessionHistory(response) {
|
|
|
53662
53867
|
return { entries, leafId: data.leafId };
|
|
53663
53868
|
}
|
|
53664
53869
|
function parseAvailableThinkingLevels(response) {
|
|
53665
|
-
const data =
|
|
53870
|
+
const data = isRecord17(response.data) ? response.data : null;
|
|
53666
53871
|
if (!data || !Array.isArray(data.levels) || data.levels.length === 0) {
|
|
53667
53872
|
throw new PiRpcFaultError("protocolError", "Pi RPC Thinking catalog response has no levels");
|
|
53668
53873
|
}
|
|
@@ -53679,35 +53884,35 @@ function parseAvailableThinkingLevels(response) {
|
|
|
53679
53884
|
return levels;
|
|
53680
53885
|
}
|
|
53681
53886
|
function parseAvailableModels(response) {
|
|
53682
|
-
const data =
|
|
53887
|
+
const data = isRecord17(response.data) ? response.data : null;
|
|
53683
53888
|
if (!data || !Array.isArray(data.models)) {
|
|
53684
53889
|
throw new PiRpcFaultError("protocolError", "Pi RPC Model catalog response has no models");
|
|
53685
53890
|
}
|
|
53686
53891
|
return data.models.map((model) => {
|
|
53687
53892
|
const parsed = parseNativeModel(model, "catalog");
|
|
53688
|
-
if (!parsed || !
|
|
53893
|
+
if (!parsed || !isRecord17(model) || typeof model.reasoning !== "boolean") {
|
|
53689
53894
|
throw new PiRpcFaultError("protocolError", "Pi RPC catalog contains a Model without reasoning capability");
|
|
53690
53895
|
}
|
|
53691
53896
|
return { ...parsed, reasoning: model.reasoning };
|
|
53692
53897
|
});
|
|
53693
53898
|
}
|
|
53694
53899
|
function assistantText2(value) {
|
|
53695
|
-
if (!
|
|
53900
|
+
if (!isRecord17(value) || value.role !== "assistant" || !Array.isArray(value.content))
|
|
53696
53901
|
return null;
|
|
53697
|
-
return value.content.filter((content) =>
|
|
53902
|
+
return value.content.filter((content) => isRecord17(content) && content.type === "text" && typeof content.text === "string").map((content) => content.text).join("");
|
|
53698
53903
|
}
|
|
53699
53904
|
function assistantMessageId(value) {
|
|
53700
|
-
if (!
|
|
53905
|
+
if (!isRecord17(value) || value.role !== "assistant")
|
|
53701
53906
|
return null;
|
|
53702
53907
|
return nonBlankString2(value.responseId) ? value.responseId : null;
|
|
53703
53908
|
}
|
|
53704
53909
|
function assistantReasoning(value) {
|
|
53705
|
-
if (!
|
|
53910
|
+
if (!isRecord17(value) || value.role !== "assistant" || !Array.isArray(value.content))
|
|
53706
53911
|
return null;
|
|
53707
|
-
return value.content.filter((content) =>
|
|
53912
|
+
return value.content.filter((content) => isRecord17(content) && content.type === "thinking" && typeof content.thinking === "string").map((content) => content.thinking).join("");
|
|
53708
53913
|
}
|
|
53709
53914
|
function assistantFailure(value) {
|
|
53710
|
-
if (!
|
|
53915
|
+
if (!isRecord17(value) || value.role !== "assistant")
|
|
53711
53916
|
return void 0;
|
|
53712
53917
|
if (value.stopReason !== "error" && value.stopReason !== "aborted")
|
|
53713
53918
|
return null;
|
|
@@ -53727,7 +53932,7 @@ function signalProcessTree2(child, signal) {
|
|
|
53727
53932
|
try {
|
|
53728
53933
|
process.kill(-child.pid, signal);
|
|
53729
53934
|
} catch (error52) {
|
|
53730
|
-
if (!
|
|
53935
|
+
if (!isRecord17(error52) || error52.code !== "ESRCH")
|
|
53731
53936
|
throw error52;
|
|
53732
53937
|
}
|
|
53733
53938
|
}
|
|
@@ -53758,7 +53963,7 @@ function piRpcProcessCommand(options, dependencies = {}) {
|
|
|
53758
53963
|
const sessionArguments = options.forkSessionFile ? ["--fork", options.forkSessionFile] : options.sessionFile ? ["--session", options.sessionFile] : [];
|
|
53759
53964
|
const modelArguments = options.model ? ["--provider", options.model.provider, "--model", options.model.id] : [];
|
|
53760
53965
|
const arguments_2 = ["--mode", "rpc", ...modelArguments, ...sessionArguments];
|
|
53761
|
-
const extension =
|
|
53966
|
+
const extension = path12.win32.extname(command).toLowerCase();
|
|
53762
53967
|
if (platform !== "win32" || ![".cmd", ".bat"].includes(extension)) {
|
|
53763
53968
|
return { command, arguments: arguments_2, windowsVerbatimArguments: false };
|
|
53764
53969
|
}
|
|
@@ -53841,7 +54046,7 @@ var PiRpcSession = class {
|
|
|
53841
54046
|
});
|
|
53842
54047
|
child.stderr.resume();
|
|
53843
54048
|
child.once("error", (error52) => {
|
|
53844
|
-
const kind =
|
|
54049
|
+
const kind = isRecord17(error52) && error52.code === "ENOENT" ? "notInstalled" : "unavailable";
|
|
53845
54050
|
this.#fail(new PiRpcFaultError(kind, `Pi RPC failed to start: ${error52.message}`));
|
|
53846
54051
|
});
|
|
53847
54052
|
child.once("exit", (code, signal) => {
|
|
@@ -54093,7 +54298,7 @@ var PiRpcSession = class {
|
|
|
54093
54298
|
this.#buffer = this.#buffer.subarray(newline3 + 1);
|
|
54094
54299
|
try {
|
|
54095
54300
|
const value = JSON.parse(textDecoder.decode(frame));
|
|
54096
|
-
if (!
|
|
54301
|
+
if (!isRecord17(value) || typeof value.type !== "string") {
|
|
54097
54302
|
throw new PiRpcFaultError("protocolError", "Pi RPC returned an invalid envelope");
|
|
54098
54303
|
}
|
|
54099
54304
|
this.#handle(value);
|
|
@@ -54132,7 +54337,7 @@ var PiRpcSession = class {
|
|
|
54132
54337
|
}
|
|
54133
54338
|
compactionTurn?.onEvent({
|
|
54134
54339
|
type: "compaction.completed",
|
|
54135
|
-
outcome: value.aborted === true ? "cancelled" :
|
|
54340
|
+
outcome: value.aborted === true ? "cancelled" : isRecord17(value.result) ? "succeeded" : "failed",
|
|
54136
54341
|
...nonBlankString2(value.errorMessage) ? { errorMessage: value.errorMessage } : {}
|
|
54137
54342
|
});
|
|
54138
54343
|
return;
|
|
@@ -54152,7 +54357,7 @@ var PiRpcSession = class {
|
|
|
54152
54357
|
this.#startAssistantMessage(active, value.message);
|
|
54153
54358
|
return;
|
|
54154
54359
|
}
|
|
54155
|
-
if (value.type === "message_update" &&
|
|
54360
|
+
if (value.type === "message_update" && isRecord17(value.assistantMessageEvent)) {
|
|
54156
54361
|
const event = value.assistantMessageEvent;
|
|
54157
54362
|
if (event.type === "text_delta" && typeof event.delta === "string") {
|
|
54158
54363
|
const messageId = this.#ensureAssistantMessage(active, value.message);
|
|
@@ -54546,7 +54751,7 @@ var PiRpcSession = class {
|
|
|
54546
54751
|
// packages/adapters/pi/dist/pi-adapter.js
|
|
54547
54752
|
var piHarnessId2 = harnessIdSchema.parse("pi");
|
|
54548
54753
|
var DEFAULT_TOOL_OUTPUT_LIMIT4 = 64e3;
|
|
54549
|
-
function
|
|
54754
|
+
function isRecord18(value) {
|
|
54550
54755
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
54551
54756
|
}
|
|
54552
54757
|
function errorMessage(error52) {
|
|
@@ -54620,7 +54825,7 @@ function nativeModelForHistory(state) {
|
|
|
54620
54825
|
return nativeModelFromState(state);
|
|
54621
54826
|
}
|
|
54622
54827
|
function sessionFileFromRef(ref) {
|
|
54623
|
-
if (ref.harnessId !== piHarnessId2 || !
|
|
54828
|
+
if (ref.harnessId !== piHarnessId2 || !isRecord18(ref.locator) || typeof ref.locator.sessionFile !== "string" || ref.locator.sessionFile.length === 0) {
|
|
54624
54829
|
throw new Error("Pi Native Session Ref has no resumable Session file");
|
|
54625
54830
|
}
|
|
54626
54831
|
return ref.locator.sessionFile;
|
|
@@ -54635,9 +54840,9 @@ function toolFailure2(toolName) {
|
|
|
54635
54840
|
function nativeText(value) {
|
|
54636
54841
|
if (typeof value === "string")
|
|
54637
54842
|
return value;
|
|
54638
|
-
if (!
|
|
54843
|
+
if (!isRecord18(value) || !Array.isArray(value.content))
|
|
54639
54844
|
return "";
|
|
54640
|
-
return value.content.filter((content) =>
|
|
54845
|
+
return value.content.filter((content) => isRecord18(content) && content.type === "text" && typeof content.text === "string").map(({ text }) => text).join("");
|
|
54641
54846
|
}
|
|
54642
54847
|
function boundedOutput(value, limit) {
|
|
54643
54848
|
const text = nativeText(value);
|
|
@@ -54653,19 +54858,19 @@ function outputText2(output) {
|
|
|
54653
54858
|
return output?.content.filter((content) => content.type === "text").map(({ text }) => text).join("") ?? "";
|
|
54654
54859
|
}
|
|
54655
54860
|
function stringField2(value, key) {
|
|
54656
|
-
return
|
|
54861
|
+
return isRecord18(value) && typeof value[key] === "string" ? value[key] : void 0;
|
|
54657
54862
|
}
|
|
54658
54863
|
function numberField(value, key) {
|
|
54659
|
-
if (!
|
|
54864
|
+
if (!isRecord18(value))
|
|
54660
54865
|
return void 0;
|
|
54661
54866
|
const field = value[key];
|
|
54662
54867
|
return typeof field === "number" || field === null ? field : void 0;
|
|
54663
54868
|
}
|
|
54664
|
-
function stripDiffPrefix(
|
|
54665
|
-
return
|
|
54869
|
+
function stripDiffPrefix(path18) {
|
|
54870
|
+
return path18.startsWith("a/") || path18.startsWith("b/") ? path18.slice(2) : path18;
|
|
54666
54871
|
}
|
|
54667
54872
|
function reliableFileChange(result) {
|
|
54668
|
-
if (!
|
|
54873
|
+
if (!isRecord18(result) || !isRecord18(result.details) || typeof result.details.patch !== "string") {
|
|
54669
54874
|
return null;
|
|
54670
54875
|
}
|
|
54671
54876
|
const patch = result.details.patch;
|
|
@@ -54681,10 +54886,10 @@ function reliableFileChange(result) {
|
|
|
54681
54886
|
const oldFile = file2.oldFileName;
|
|
54682
54887
|
const newFile = file2.newFileName;
|
|
54683
54888
|
const kind = oldFile === "/dev/null" ? "add" : newFile === "/dev/null" ? "delete" : "update";
|
|
54684
|
-
const
|
|
54685
|
-
if (!
|
|
54889
|
+
const path18 = stripDiffPrefix(kind === "delete" ? oldFile : newFile);
|
|
54890
|
+
if (!path18 || path18 === "/dev/null")
|
|
54686
54891
|
return null;
|
|
54687
|
-
return [{ path:
|
|
54892
|
+
return [{ path: path18, kind, unifiedDiff: patch }];
|
|
54688
54893
|
}
|
|
54689
54894
|
function delay3(milliseconds) {
|
|
54690
54895
|
return new Promise((resolve2) => setTimeout(resolve2, milliseconds));
|
|
@@ -55927,8 +56132,8 @@ import nodePath from "node:path";
|
|
|
55927
56132
|
import { execFileSync } from "node:child_process";
|
|
55928
56133
|
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
55929
56134
|
import { constants as constants3 } from "node:fs";
|
|
55930
|
-
import { copyFile, mkdir, open as open2, readFile as
|
|
55931
|
-
import
|
|
56135
|
+
import { copyFile, mkdir, open as open2, readFile as readFile3, readdir, rename, rm as rm2, stat } from "node:fs/promises";
|
|
56136
|
+
import path13 from "node:path";
|
|
55932
56137
|
|
|
55933
56138
|
// packages/mapping-store/dist/records.js
|
|
55934
56139
|
var nonBlankTextSchema3 = external_exports.string().refine((value) => value.trim().length > 0, {
|
|
@@ -56095,6 +56300,18 @@ function isNodeExecutable(value) {
|
|
|
56095
56300
|
function lockOwnerIsLive(lock) {
|
|
56096
56301
|
if (typeof lock.pid !== "number")
|
|
56097
56302
|
return false;
|
|
56303
|
+
if (lock.pid === process.pid) {
|
|
56304
|
+
if (lock.executablePath && normalizeExecutablePath(lock.executablePath) !== normalizeExecutablePath(process.execPath)) {
|
|
56305
|
+
return false;
|
|
56306
|
+
}
|
|
56307
|
+
if (lock.processStartedAt) {
|
|
56308
|
+
const expected = Date.parse(lock.processStartedAt);
|
|
56309
|
+
const actual = Date.now() - process.uptime() * 1e3;
|
|
56310
|
+
if (Number.isFinite(expected) && Math.abs(actual - expected) > 5e3)
|
|
56311
|
+
return false;
|
|
56312
|
+
}
|
|
56313
|
+
return true;
|
|
56314
|
+
}
|
|
56098
56315
|
const identity = processIdentity(lock.pid);
|
|
56099
56316
|
if (!identity)
|
|
56100
56317
|
return false;
|
|
@@ -56133,11 +56350,11 @@ var MappingStore = class {
|
|
|
56133
56350
|
#initialized = false;
|
|
56134
56351
|
#lockHandle = null;
|
|
56135
56352
|
constructor(options) {
|
|
56136
|
-
this.#directory =
|
|
56137
|
-
this.#threadsDirectory =
|
|
56138
|
-
this.#backupsDirectory =
|
|
56139
|
-
this.#quarantineDirectory =
|
|
56140
|
-
this.#lockPath =
|
|
56353
|
+
this.#directory = path13.resolve(options.directory);
|
|
56354
|
+
this.#threadsDirectory = path13.join(this.#directory, "threads");
|
|
56355
|
+
this.#backupsDirectory = path13.join(this.#directory, "backups");
|
|
56356
|
+
this.#quarantineDirectory = path13.join(this.#directory, "quarantine");
|
|
56357
|
+
this.#lockPath = path13.join(this.#directory, "store.lock");
|
|
56141
56358
|
this.#instanceId = options.instanceId ?? randomUUID6();
|
|
56142
56359
|
this.#now = options.now ?? (() => /* @__PURE__ */ new Date());
|
|
56143
56360
|
this.#beforeReplace = options.beforeReplace;
|
|
@@ -56155,8 +56372,8 @@ var MappingStore = class {
|
|
|
56155
56372
|
await this.#cleanupTemps();
|
|
56156
56373
|
const names = (await readdir(this.#threadsDirectory)).filter((name) => name.endsWith(".json"));
|
|
56157
56374
|
for (const name of names) {
|
|
56158
|
-
const primary =
|
|
56159
|
-
const backup =
|
|
56375
|
+
const primary = path13.join(this.#threadsDirectory, name);
|
|
56376
|
+
const backup = path13.join(this.#backupsDirectory, name);
|
|
56160
56377
|
let record3 = null;
|
|
56161
56378
|
try {
|
|
56162
56379
|
record3 = await this.#readRecord(primary, name);
|
|
@@ -56165,7 +56382,7 @@ var MappingStore = class {
|
|
|
56165
56382
|
record3 = await this.#readRecord(backup, name);
|
|
56166
56383
|
await this.#replaceFile(primary, record3, false);
|
|
56167
56384
|
} catch (backupError) {
|
|
56168
|
-
const quarantine =
|
|
56385
|
+
const quarantine = path13.join(this.#quarantineDirectory, `${name}.${this.#now().getTime()}.invalid`);
|
|
56169
56386
|
await rename(primary, quarantine).catch(() => void 0);
|
|
56170
56387
|
void primaryError;
|
|
56171
56388
|
void backupError;
|
|
@@ -56274,27 +56491,29 @@ var MappingStore = class {
|
|
|
56274
56491
|
if (current.state !== "ready" || !current.nativeSessionRef) {
|
|
56275
56492
|
throw new MappingStoreError("MAPPING_CONFLICT", "Only a ready Thread can reconcile Snapshot mappings");
|
|
56276
56493
|
}
|
|
56277
|
-
const
|
|
56278
|
-
|
|
56279
|
-
|
|
56280
|
-
|
|
56281
|
-
const
|
|
56282
|
-
|
|
56283
|
-
const
|
|
56284
|
-
if (
|
|
56494
|
+
const byHost = new Map(current.turnMappings.map((mapping) => [mapping.hostTurnId, mapping]));
|
|
56495
|
+
const byNative = new Map(current.turnMappings.map((mapping) => [nativeTurnKey(mapping), mapping]));
|
|
56496
|
+
const seenHost = /* @__PURE__ */ new Set();
|
|
56497
|
+
const seenNative = /* @__PURE__ */ new Set();
|
|
56498
|
+
const ordered = mappings.map((update) => {
|
|
56499
|
+
const hostMatch = byHost.get(update.hostTurnId);
|
|
56500
|
+
const nativeMatch = byNative.get(nativeTurnKey(update));
|
|
56501
|
+
if (hostMatch && nativeMatch && hostMatch !== nativeMatch) {
|
|
56502
|
+
throw new MappingStoreError("MAPPING_CONFLICT", "Turn identity mapping conflicts");
|
|
56503
|
+
}
|
|
56504
|
+
if (hostMatch && !sameJson(hostMatch.nativeTurnRef, update.nativeTurnRef)) {
|
|
56505
|
+
throw new MappingStoreError("MAPPING_CONFLICT", "Host Turn maps to another Native Turn");
|
|
56506
|
+
}
|
|
56507
|
+
if (nativeMatch && nativeMatch.hostTurnId !== update.hostTurnId) {
|
|
56508
|
+
throw new MappingStoreError("MAPPING_CONFLICT", "Native Turn maps to another Host Turn");
|
|
56509
|
+
}
|
|
56510
|
+
if (seenHost.has(update.hostTurnId) || seenNative.has(nativeTurnKey(update))) {
|
|
56285
56511
|
throw new MappingStoreError("MAPPING_CONFLICT", "Snapshot reconciliation contains a duplicate Turn mapping");
|
|
56286
56512
|
}
|
|
56287
|
-
|
|
56513
|
+
seenHost.add(update.hostTurnId);
|
|
56514
|
+
seenNative.add(nativeTurnKey(update));
|
|
56515
|
+
return { ...update };
|
|
56288
56516
|
});
|
|
56289
|
-
const orderedIndexByHost = new Map(ordered.map(({ hostTurnId }, index) => [hostTurnId, index]));
|
|
56290
|
-
let previousIndex = -1;
|
|
56291
|
-
for (const existing of current.turnMappings) {
|
|
56292
|
-
const nextIndex = orderedIndexByHost.get(existing.hostTurnId);
|
|
56293
|
-
if (nextIndex === void 0 || nextIndex <= previousIndex) {
|
|
56294
|
-
throw new MappingStoreError("MAPPING_CONFLICT", "Snapshot reconciliation reordered an existing Turn mapping");
|
|
56295
|
-
}
|
|
56296
|
-
previousIndex = nextIndex;
|
|
56297
|
-
}
|
|
56298
56517
|
return sameJson(current.turnMappings, ordered) ? null : { ...current, turnMappings: ordered };
|
|
56299
56518
|
});
|
|
56300
56519
|
}
|
|
@@ -56339,7 +56558,7 @@ var MappingStore = class {
|
|
|
56339
56558
|
if (handle)
|
|
56340
56559
|
await handle.close().catch(() => void 0);
|
|
56341
56560
|
try {
|
|
56342
|
-
const current = JSON.parse(await
|
|
56561
|
+
const current = JSON.parse(await readFile3(this.#lockPath, "utf8"));
|
|
56343
56562
|
if (current.instanceId === this.#instanceId)
|
|
56344
56563
|
await rm2(this.#lockPath, { force: true });
|
|
56345
56564
|
} catch {
|
|
@@ -56433,7 +56652,7 @@ var MappingStore = class {
|
|
|
56433
56652
|
}
|
|
56434
56653
|
}
|
|
56435
56654
|
async #readRecord(file2, expectedName) {
|
|
56436
|
-
const parsed = storedThreadRecordV1Schema.safeParse(JSON.parse(await
|
|
56655
|
+
const parsed = storedThreadRecordV1Schema.safeParse(JSON.parse(await readFile3(file2, "utf8")));
|
|
56437
56656
|
if (!parsed.success) {
|
|
56438
56657
|
throw new MappingStoreError("INVALID_RECORD", "Mapping Store record is invalid", {
|
|
56439
56658
|
cause: parsed.error
|
|
@@ -56446,7 +56665,7 @@ var MappingStore = class {
|
|
|
56446
56665
|
}
|
|
56447
56666
|
async #cleanupTemps() {
|
|
56448
56667
|
const names = await readdir(this.#threadsDirectory);
|
|
56449
|
-
await Promise.all(names.filter((name) => name.includes(".tmp-")).map((name) => rm2(
|
|
56668
|
+
await Promise.all(names.filter((name) => name.includes(".tmp-")).map((name) => rm2(path13.join(this.#threadsDirectory, name), { force: true })));
|
|
56450
56669
|
}
|
|
56451
56670
|
async #acquireLock() {
|
|
56452
56671
|
const attempt = async () => {
|
|
@@ -56472,7 +56691,7 @@ var MappingStore = class {
|
|
|
56472
56691
|
}
|
|
56473
56692
|
let existing = {};
|
|
56474
56693
|
try {
|
|
56475
|
-
existing = JSON.parse(await
|
|
56694
|
+
existing = JSON.parse(await readFile3(this.#lockPath, "utf8"));
|
|
56476
56695
|
} catch {
|
|
56477
56696
|
}
|
|
56478
56697
|
if (typeof existing.pid === "number" && lockOwnerIsLive(existing)) {
|
|
@@ -56539,10 +56758,10 @@ var MappingStore = class {
|
|
|
56539
56758
|
}
|
|
56540
56759
|
}
|
|
56541
56760
|
#recordPath(hostThreadId) {
|
|
56542
|
-
return
|
|
56761
|
+
return path13.join(this.#threadsDirectory, `${hostThreadId}.json`);
|
|
56543
56762
|
}
|
|
56544
56763
|
#backupPath(hostThreadId) {
|
|
56545
|
-
return
|
|
56764
|
+
return path13.join(this.#backupsDirectory, `${hostThreadId}.json`);
|
|
56546
56765
|
}
|
|
56547
56766
|
#requireInitialized() {
|
|
56548
56767
|
if (!this.#initialized) {
|
|
@@ -56561,7 +56780,7 @@ var packageMetadata5 = {
|
|
|
56561
56780
|
var TITLE_MAX_LENGTH = 120;
|
|
56562
56781
|
var DESCRIPTION_MAX_LENGTH = 500;
|
|
56563
56782
|
var SERVER_NAME_MAX_LENGTH = 80;
|
|
56564
|
-
function
|
|
56783
|
+
function isRecord19(value) {
|
|
56565
56784
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
56566
56785
|
}
|
|
56567
56786
|
function boundedText(value, field, maxLength) {
|
|
@@ -56605,7 +56824,7 @@ function responseError(message3) {
|
|
|
56605
56824
|
function responsePersist(value) {
|
|
56606
56825
|
if (value === void 0 || value === null)
|
|
56607
56826
|
return null;
|
|
56608
|
-
if (!
|
|
56827
|
+
if (!isRecord19(value) || Object.keys(value).length !== 1 || value.persist !== "session" && value.persist !== "always") {
|
|
56609
56828
|
throw responseError("contains malformed persist metadata");
|
|
56610
56829
|
}
|
|
56611
56830
|
return value.persist;
|
|
@@ -56648,7 +56867,7 @@ function projectCodexApprovalRequest(input) {
|
|
|
56648
56867
|
},
|
|
56649
56868
|
denyResponse,
|
|
56650
56869
|
parseResponse(result) {
|
|
56651
|
-
if (!
|
|
56870
|
+
if (!isRecord19(result) || typeof result.action !== "string") {
|
|
56652
56871
|
throw responseError("missing action");
|
|
56653
56872
|
}
|
|
56654
56873
|
if (Object.keys(result).some((key) => key !== "action" && key !== "content" && key !== "_meta")) {
|
|
@@ -56656,7 +56875,7 @@ function projectCodexApprovalRequest(input) {
|
|
|
56656
56875
|
}
|
|
56657
56876
|
const selectedPersist = responsePersist(result._meta);
|
|
56658
56877
|
if (result.action === "accept") {
|
|
56659
|
-
if ("content" in result && (!
|
|
56878
|
+
if ("content" in result && (!isRecord19(result.content) || Object.keys(result.content).length !== 0)) {
|
|
56660
56879
|
throw responseError("contains non-empty accepted content");
|
|
56661
56880
|
}
|
|
56662
56881
|
if (selectedPersist === "session") {
|
|
@@ -56683,7 +56902,7 @@ function projectCodexApprovalRequest(input) {
|
|
|
56683
56902
|
}
|
|
56684
56903
|
|
|
56685
56904
|
// packages/protocol-core/dist/codex-question.js
|
|
56686
|
-
function
|
|
56905
|
+
function isRecord20(value) {
|
|
56687
56906
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
56688
56907
|
}
|
|
56689
56908
|
function responseError2(message3) {
|
|
@@ -56752,7 +56971,7 @@ function projectCodexQuestionRequest(input) {
|
|
|
56752
56971
|
}
|
|
56753
56972
|
},
|
|
56754
56973
|
parseResponse(result) {
|
|
56755
|
-
if (!
|
|
56974
|
+
if (!isRecord20(result) || !isRecord20(result.answers)) {
|
|
56756
56975
|
throw responseError2("missing answers object");
|
|
56757
56976
|
}
|
|
56758
56977
|
const rawAnswers = result.answers;
|
|
@@ -56765,7 +56984,7 @@ function projectCodexQuestionRequest(input) {
|
|
|
56765
56984
|
const question = interaction.questions.find(({ id: id2 }) => id2 === questionId);
|
|
56766
56985
|
if (!question)
|
|
56767
56986
|
throw responseError2("contains an unknown Question ID");
|
|
56768
|
-
if (!
|
|
56987
|
+
if (!isRecord20(answerValue) || !Array.isArray(answerValue.answers)) {
|
|
56769
56988
|
throw responseError2("answer entry has no answers array");
|
|
56770
56989
|
}
|
|
56771
56990
|
const values = answerValue.answers;
|
|
@@ -56911,8 +57130,8 @@ function projectItem(item, outcome, defaultCwd, includeCommandOutput = true) {
|
|
|
56911
57130
|
return {
|
|
56912
57131
|
id: item.itemId,
|
|
56913
57132
|
type: "fileChange",
|
|
56914
|
-
changes: item.changes.map(({ path:
|
|
56915
|
-
path:
|
|
57133
|
+
changes: item.changes.map(({ path: path18, kind, unifiedDiff }) => ({
|
|
57134
|
+
path: path18,
|
|
56916
57135
|
kind,
|
|
56917
57136
|
diff: unifiedDiff
|
|
56918
57137
|
})),
|
|
@@ -57329,8 +57548,8 @@ var CodexTurnProjector = class {
|
|
|
57329
57548
|
return messages;
|
|
57330
57549
|
}
|
|
57331
57550
|
#fileChangeUpdates(itemId3, changes) {
|
|
57332
|
-
const projectedChanges = changes.map(({ path:
|
|
57333
|
-
path:
|
|
57551
|
+
const projectedChanges = changes.map(({ path: path18, kind, unifiedDiff }) => ({
|
|
57552
|
+
path: path18,
|
|
57334
57553
|
kind,
|
|
57335
57554
|
diff: unifiedDiff
|
|
57336
57555
|
}));
|
|
@@ -57375,7 +57594,7 @@ var CodexTurnProjector = class {
|
|
|
57375
57594
|
};
|
|
57376
57595
|
|
|
57377
57596
|
// packages/protocol-core/dist/thread-fork.js
|
|
57378
|
-
function
|
|
57597
|
+
function isRecord21(value) {
|
|
57379
57598
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
57380
57599
|
}
|
|
57381
57600
|
function optionalText(params, name, options = {}) {
|
|
@@ -57398,7 +57617,7 @@ function optionalBoolean(params, name) {
|
|
|
57398
57617
|
function decodeThreadForkRequest(request) {
|
|
57399
57618
|
if (request.method !== "thread/fork")
|
|
57400
57619
|
return null;
|
|
57401
|
-
if (!
|
|
57620
|
+
if (!isRecord21(request.params))
|
|
57402
57621
|
throw new Error("thread/fork params must be an object");
|
|
57403
57622
|
const params = request.params;
|
|
57404
57623
|
const threadId2 = optionalText(params, "threadId");
|
|
@@ -57413,13 +57632,13 @@ function decodeThreadForkRequest(request) {
|
|
|
57413
57632
|
if (runtimeWorkspaceRoots !== void 0 && runtimeWorkspaceRoots !== null && (!Array.isArray(runtimeWorkspaceRoots) || runtimeWorkspaceRoots.some((root) => typeof root !== "string" || root.length === 0))) {
|
|
57414
57633
|
throw new Error("thread/fork params.runtimeWorkspaceRoots must be text paths or null");
|
|
57415
57634
|
}
|
|
57416
|
-
const
|
|
57635
|
+
const path18 = optionalText(params, "path", { allowEmpty: true });
|
|
57417
57636
|
const ephemeral = optionalBoolean(params, "ephemeral");
|
|
57418
57637
|
return {
|
|
57419
57638
|
threadId: threadId2,
|
|
57420
57639
|
...lastTurnText ? { lastTurnId: hostTurnIdSchema.parse(lastTurnText) } : {},
|
|
57421
57640
|
...beforeTurnText ? { beforeTurnId: hostTurnIdSchema.parse(beforeTurnText) } : {},
|
|
57422
|
-
...
|
|
57641
|
+
...path18 ? { path: path18 } : {},
|
|
57423
57642
|
...optionalField(params, "model"),
|
|
57424
57643
|
...optionalField(params, "modelProvider"),
|
|
57425
57644
|
...optionalField(params, "cwd"),
|
|
@@ -57434,7 +57653,7 @@ function decodeThreadForkRequest(request) {
|
|
|
57434
57653
|
function decodeThreadRollbackRequest(request) {
|
|
57435
57654
|
if (request.method !== "thread/rollback")
|
|
57436
57655
|
return null;
|
|
57437
|
-
if (!
|
|
57656
|
+
if (!isRecord21(request.params))
|
|
57438
57657
|
throw new Error("thread/rollback params must be an object");
|
|
57439
57658
|
const { threadId: threadId2, numTurns } = request.params;
|
|
57440
57659
|
if (typeof threadId2 !== "string" || threadId2.length === 0) {
|
|
@@ -57528,13 +57747,13 @@ var THREAD_SOURCE_KINDS = /* @__PURE__ */ new Set([
|
|
|
57528
57747
|
"subAgentOther",
|
|
57529
57748
|
"unknown"
|
|
57530
57749
|
]);
|
|
57531
|
-
function
|
|
57750
|
+
function isRecord22(value) {
|
|
57532
57751
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
57533
57752
|
}
|
|
57534
57753
|
function paramsObject(request, method) {
|
|
57535
57754
|
if (request.params === void 0 && method === "thread/list")
|
|
57536
57755
|
return {};
|
|
57537
|
-
if (!
|
|
57756
|
+
if (!isRecord22(request.params))
|
|
57538
57757
|
throw new Error(`${method} params must be an object`);
|
|
57539
57758
|
return request.params;
|
|
57540
57759
|
}
|
|
@@ -57606,7 +57825,7 @@ function cursorPayload(value) {
|
|
|
57606
57825
|
};
|
|
57607
57826
|
}
|
|
57608
57827
|
function parseCursorPayload(value) {
|
|
57609
|
-
if (!
|
|
57828
|
+
if (!isRecord22(value) || value.formatVersion !== 1)
|
|
57610
57829
|
throw new Error("Host cursor is invalid");
|
|
57611
57830
|
const { queryFingerprint: fingerprint, sortDirection: sortDirection2, officialCursor, officialDone } = value;
|
|
57612
57831
|
const { externalAnchor: externalAnchor2, externalDone } = value;
|
|
@@ -57615,7 +57834,7 @@ function parseCursorPayload(value) {
|
|
|
57615
57834
|
}
|
|
57616
57835
|
let anchor = null;
|
|
57617
57836
|
if (externalAnchor2 !== null) {
|
|
57618
|
-
if (!
|
|
57837
|
+
if (!isRecord22(externalAnchor2) || !Number.isSafeInteger(externalAnchor2.timestamp) || typeof externalAnchor2.threadId !== "string" || externalAnchor2.threadId.length === 0) {
|
|
57619
57838
|
throw new Error("Host cursor is invalid");
|
|
57620
57839
|
}
|
|
57621
57840
|
anchor = {
|
|
@@ -57735,7 +57954,7 @@ function decodeThreadMetadataUpdateRequest(request) {
|
|
|
57735
57954
|
if (params.gitInfo === null) {
|
|
57736
57955
|
gitInfo = null;
|
|
57737
57956
|
} else if (params.gitInfo !== void 0) {
|
|
57738
|
-
if (!
|
|
57957
|
+
if (!isRecord22(params.gitInfo)) {
|
|
57739
57958
|
throw new Error("thread/metadata/update params.gitInfo must be an object or null");
|
|
57740
57959
|
}
|
|
57741
57960
|
gitInfo = {};
|
|
@@ -57763,7 +57982,7 @@ function optionalCursor(value, name) {
|
|
|
57763
57982
|
return value;
|
|
57764
57983
|
}
|
|
57765
57984
|
function decodeOfficialThreadListPage(value) {
|
|
57766
|
-
if (!
|
|
57985
|
+
if (!isRecord22(value) || !Array.isArray(value.data) || value.data.some((row) => !isRecord22(row))) {
|
|
57767
57986
|
throw new Error("Official thread/list response is invalid");
|
|
57768
57987
|
}
|
|
57769
57988
|
return {
|
|
@@ -58084,8 +58303,8 @@ var packageMetadata6 = {
|
|
|
58084
58303
|
|
|
58085
58304
|
// packages/host-runtime/src/external-thread-repository.ts
|
|
58086
58305
|
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
58087
|
-
import
|
|
58088
|
-
import
|
|
58306
|
+
import os6 from "node:os";
|
|
58307
|
+
import path14 from "node:path";
|
|
58089
58308
|
function nativeTurnKey2(ref) {
|
|
58090
58309
|
return `${ref.harnessId}\0${ref.nativeSessionId}\0${ref.nativeTurnKey}\0${ref.formatVersion}`;
|
|
58091
58310
|
}
|
|
@@ -58094,8 +58313,8 @@ function sameMapping(left, right) {
|
|
|
58094
58313
|
}
|
|
58095
58314
|
function defaultMappingStoreDirectory(environment) {
|
|
58096
58315
|
const dataDirectory = environment.CODEXHOST_DATA_DIR;
|
|
58097
|
-
return
|
|
58098
|
-
dataDirectory ?
|
|
58316
|
+
return path14.join(
|
|
58317
|
+
dataDirectory ? path14.resolve(dataDirectory) : path14.join(os6.homedir(), ".codexhost"),
|
|
58099
58318
|
"mapping-store"
|
|
58100
58319
|
);
|
|
58101
58320
|
}
|
|
@@ -58305,25 +58524,14 @@ var ExternalThreadRepository = class {
|
|
|
58305
58524
|
...turn.checkpoint ? { nativeCheckpointRef: turn.checkpoint } : {}
|
|
58306
58525
|
};
|
|
58307
58526
|
return {
|
|
58308
|
-
existing,
|
|
58309
58527
|
snapshot: turn,
|
|
58310
58528
|
mapping: {
|
|
58311
58529
|
...mapping,
|
|
58530
|
+
nativeTurnRef: turn.nativeTurnRef,
|
|
58312
58531
|
...turn.checkpoint ? { nativeCheckpointRef: turn.checkpoint } : {}
|
|
58313
58532
|
}
|
|
58314
58533
|
};
|
|
58315
58534
|
});
|
|
58316
|
-
let existingIndex = 0;
|
|
58317
|
-
for (const { existing } of aligned) {
|
|
58318
|
-
if (!existing) continue;
|
|
58319
|
-
if (existing.hostTurnId !== record3.turnMappings[existingIndex]?.hostTurnId) {
|
|
58320
|
-
throw new Error("Persisted Turn mappings do not match the Native Snapshot order");
|
|
58321
|
-
}
|
|
58322
|
-
existingIndex += 1;
|
|
58323
|
-
}
|
|
58324
|
-
if (existingIndex !== record3.turnMappings.length) {
|
|
58325
|
-
throw new Error("Persisted Turn mappings do not match the Native Snapshot order");
|
|
58326
|
-
}
|
|
58327
58535
|
const orderedMappings = aligned.map(({ mapping }) => mapping);
|
|
58328
58536
|
const mappingsChanged = orderedMappings.length !== record3.turnMappings.length || orderedMappings.some((mapping, index) => {
|
|
58329
58537
|
const persisted = record3.turnMappings[index];
|
|
@@ -59180,7 +59388,7 @@ var ExternalThreadRuntime = class {
|
|
|
59180
59388
|
import { randomUUID as randomUUID8 } from "node:crypto";
|
|
59181
59389
|
var INTERNAL_REQUEST_PREFIX = "codexhost:official:";
|
|
59182
59390
|
var MAX_RETIRED_IDS = 1024;
|
|
59183
|
-
function
|
|
59391
|
+
function isRecord23(value) {
|
|
59184
59392
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
59185
59393
|
}
|
|
59186
59394
|
var OfficialRequestBroker = class {
|
|
@@ -59223,7 +59431,7 @@ var OfficialRequestBroker = class {
|
|
|
59223
59431
|
});
|
|
59224
59432
|
}
|
|
59225
59433
|
handle(value) {
|
|
59226
|
-
if (!
|
|
59434
|
+
if (!isRecord23(value) || typeof value.id !== "string") return false;
|
|
59227
59435
|
const pending = this.#pending.get(value.id);
|
|
59228
59436
|
if (!pending) return this.#retired.has(value.id);
|
|
59229
59437
|
clearTimeout(pending.timeout);
|
|
@@ -59252,11 +59460,11 @@ var OfficialRequestBroker = class {
|
|
|
59252
59460
|
};
|
|
59253
59461
|
|
|
59254
59462
|
// packages/host-runtime/src/route-observation.ts
|
|
59255
|
-
function
|
|
59463
|
+
function isRecord24(value) {
|
|
59256
59464
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
59257
59465
|
}
|
|
59258
59466
|
function classifyThreadPurpose(request) {
|
|
59259
|
-
return
|
|
59467
|
+
return isRecord24(request.params) && request.params.ephemeral === true ? "ephemeral" : "conversation";
|
|
59260
59468
|
}
|
|
59261
59469
|
var RequestRouteObservationTracker = class {
|
|
59262
59470
|
#nextCreateOrdinal = 0;
|
|
@@ -59281,13 +59489,13 @@ var RequestRouteObservationTracker = class {
|
|
|
59281
59489
|
this.#createByThreadId.set(threadId2, tracked);
|
|
59282
59490
|
}
|
|
59283
59491
|
bindOfficialResponse(response) {
|
|
59284
|
-
if (!
|
|
59492
|
+
if (!isRecord24(response) || !("id" in response)) return;
|
|
59285
59493
|
const tracked = this.#pendingByRequestId.get(response.id);
|
|
59286
59494
|
if (!tracked) return;
|
|
59287
59495
|
this.#pendingByRequestId.delete(response.id);
|
|
59288
59496
|
const result = response.result;
|
|
59289
|
-
const thread =
|
|
59290
|
-
if (
|
|
59497
|
+
const thread = isRecord24(result) ? result.thread : null;
|
|
59498
|
+
if (isRecord24(thread) && typeof thread.id === "string") {
|
|
59291
59499
|
this.#createByThreadId.set(thread.id, tracked);
|
|
59292
59500
|
}
|
|
59293
59501
|
}
|
|
@@ -59384,25 +59592,25 @@ function resolveExternalSessionTreeIds(records) {
|
|
|
59384
59592
|
const resolve2 = (start) => {
|
|
59385
59593
|
const cached2 = resolved.get(start.hostThreadId);
|
|
59386
59594
|
if (cached2) return cached2;
|
|
59387
|
-
const
|
|
59595
|
+
const path18 = [];
|
|
59388
59596
|
const visited = /* @__PURE__ */ new Set();
|
|
59389
59597
|
let current = start;
|
|
59390
59598
|
while (true) {
|
|
59391
59599
|
const known = resolved.get(current.hostThreadId);
|
|
59392
59600
|
if (known) {
|
|
59393
|
-
for (const record3 of
|
|
59601
|
+
for (const record3 of path18) resolved.set(record3.hostThreadId, known);
|
|
59394
59602
|
return known;
|
|
59395
59603
|
}
|
|
59396
59604
|
if (visited.has(current.hostThreadId)) {
|
|
59397
59605
|
throw new Error("External Thread Fork tree contains a cycle");
|
|
59398
59606
|
}
|
|
59399
59607
|
visited.add(current.hostThreadId);
|
|
59400
|
-
|
|
59608
|
+
path18.push(current);
|
|
59401
59609
|
const sourceId = current.forkSource?.hostThreadId;
|
|
59402
59610
|
const source = sourceId ? byId.get(sourceId) : void 0;
|
|
59403
59611
|
if (!source) {
|
|
59404
59612
|
const root = current.hostThreadId;
|
|
59405
|
-
for (const record3 of
|
|
59613
|
+
for (const record3 of path18) resolved.set(record3.hostThreadId, root);
|
|
59406
59614
|
return root;
|
|
59407
59615
|
}
|
|
59408
59616
|
current = source;
|
|
@@ -59453,11 +59661,11 @@ var OfficialThreadListError = class extends Error {
|
|
|
59453
59661
|
}
|
|
59454
59662
|
rpcError;
|
|
59455
59663
|
};
|
|
59456
|
-
function
|
|
59664
|
+
function isRecord25(value) {
|
|
59457
59665
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
59458
59666
|
}
|
|
59459
59667
|
function officialThreadListPageFromResponse(response) {
|
|
59460
|
-
if (
|
|
59668
|
+
if (isRecord25(response.error)) {
|
|
59461
59669
|
if (!Number.isSafeInteger(response.error.code) || typeof response.error.message !== "string") {
|
|
59462
59670
|
throw new Error("Official thread/list error response is invalid");
|
|
59463
59671
|
}
|
|
@@ -59617,9 +59825,19 @@ async function aggregateThreadList(input) {
|
|
|
59617
59825
|
}
|
|
59618
59826
|
|
|
59619
59827
|
// packages/host-runtime/src/app-server-host.ts
|
|
59620
|
-
function
|
|
59828
|
+
function isRecord26(value) {
|
|
59621
59829
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
59622
59830
|
}
|
|
59831
|
+
function isCreditsAdapter(adapter) {
|
|
59832
|
+
return typeof adapter.credits === "function" && typeof adapter.refreshCredits === "function";
|
|
59833
|
+
}
|
|
59834
|
+
function projectAccountCredits(value) {
|
|
59835
|
+
if (!isRecord26(value)) return null;
|
|
59836
|
+
const rest = { ...value };
|
|
59837
|
+
delete rest.fetchedAt;
|
|
59838
|
+
const parsed = accountCreditsSnapshotSchema.safeParse(rest);
|
|
59839
|
+
return parsed.success ? parsed.data : null;
|
|
59840
|
+
}
|
|
59623
59841
|
function errorMessage3(error52) {
|
|
59624
59842
|
return error52 instanceof Error ? error52.message : String(error52);
|
|
59625
59843
|
}
|
|
@@ -59636,6 +59854,7 @@ function officialEnvironment(source) {
|
|
|
59636
59854
|
"CODEXHOST_STOCK_CODEX_PATH",
|
|
59637
59855
|
"CODEXHOST_LAUNCHER_PID",
|
|
59638
59856
|
"CODEXHOST_LAUNCHER_EXECUTABLE",
|
|
59857
|
+
"CODEXHOST_RUNTIME_DESCRIPTOR_PATH",
|
|
59639
59858
|
"CODEXHOST_CONTROL_PORT",
|
|
59640
59859
|
"CODEXHOST_CONTROL_NONCE",
|
|
59641
59860
|
"CODEXHOST_NPM_NODE_PATH",
|
|
@@ -59713,12 +59932,12 @@ function classifyCreateRequestRoute(request, defaultAgent2) {
|
|
|
59713
59932
|
};
|
|
59714
59933
|
}
|
|
59715
59934
|
function requestObject(request) {
|
|
59716
|
-
if (!
|
|
59935
|
+
if (!isRecord26(request.params)) throw new Error(`${request.method} params must be an object`);
|
|
59717
59936
|
return request.params;
|
|
59718
59937
|
}
|
|
59719
59938
|
function requestText(params) {
|
|
59720
59939
|
if (!Array.isArray(params.input)) throw new Error("turn/start input must be an array");
|
|
59721
|
-
const text = params.input.filter((item) =>
|
|
59940
|
+
const text = params.input.filter((item) => isRecord26(item) && item.type === "text").map((item) => item.text).filter((value) => typeof value === "string").join("\n");
|
|
59722
59941
|
if (!text) throw new Error("turn/start must contain text input");
|
|
59723
59942
|
return text;
|
|
59724
59943
|
}
|
|
@@ -59872,11 +60091,11 @@ var AppServerHost = class {
|
|
|
59872
60091
|
}
|
|
59873
60092
|
const request = requestResult.data;
|
|
59874
60093
|
if (request.method === "codexhost/update/check" || request.method === "codexhost/update/start" || request.method === "codexhost/update/status") {
|
|
59875
|
-
|
|
60094
|
+
this.#dispatchDesktopRequest(() => this.#handleUpdateRequest(request));
|
|
59876
60095
|
continue;
|
|
59877
60096
|
}
|
|
59878
60097
|
if (request.method === "codexhost/harness/inspect") {
|
|
59879
|
-
|
|
60098
|
+
this.#dispatchDesktopRequest(() => this.#inspectHarness(request));
|
|
59880
60099
|
continue;
|
|
59881
60100
|
}
|
|
59882
60101
|
if (request.method === "codexhost/thread/fork") {
|
|
@@ -59921,7 +60140,7 @@ var AppServerHost = class {
|
|
|
59921
60140
|
await writeFrame(official.stdin, frame);
|
|
59922
60141
|
continue;
|
|
59923
60142
|
}
|
|
59924
|
-
|
|
60143
|
+
this.#dispatchDesktopRequest(() => this.#listThreads(request, listRequest));
|
|
59925
60144
|
continue;
|
|
59926
60145
|
}
|
|
59927
60146
|
if (request.method === "thread/archive" || request.method === "thread/unarchive") {
|
|
@@ -59992,7 +60211,7 @@ var AppServerHost = class {
|
|
|
59992
60211
|
continue;
|
|
59993
60212
|
}
|
|
59994
60213
|
if (request.method === "thread/fork") {
|
|
59995
|
-
const params =
|
|
60214
|
+
const params = isRecord26(request.params) ? request.params : {};
|
|
59996
60215
|
const resolution = typeof params.threadId === "string" ? await this.#resolveExternalThread(params.threadId) : { kind: "official" };
|
|
59997
60216
|
if (resolution.kind === "error") {
|
|
59998
60217
|
await this.#writer.json(
|
|
@@ -60015,7 +60234,7 @@ var AppServerHost = class {
|
|
|
60015
60234
|
}
|
|
60016
60235
|
}
|
|
60017
60236
|
if (request.method === "thread/rollback") {
|
|
60018
|
-
const params =
|
|
60237
|
+
const params = isRecord26(request.params) ? request.params : {};
|
|
60019
60238
|
const resolution = typeof params.threadId === "string" ? await this.#resolveExternalThread(params.threadId) : { kind: "official" };
|
|
60020
60239
|
if (resolution.kind === "error") {
|
|
60021
60240
|
await this.#writer.json(
|
|
@@ -60155,7 +60374,7 @@ var AppServerHost = class {
|
|
|
60155
60374
|
continue;
|
|
60156
60375
|
}
|
|
60157
60376
|
}
|
|
60158
|
-
if (request.method.startsWith("thread/") && !EXPLICIT_EXTERNAL_THREAD_METHODS.has(request.method) &&
|
|
60377
|
+
if (request.method.startsWith("thread/") && !EXPLICIT_EXTERNAL_THREAD_METHODS.has(request.method) && isRecord26(request.params) && typeof request.params.threadId === "string") {
|
|
60159
60378
|
const location = await this.#locateExternalThread(request.params.threadId);
|
|
60160
60379
|
if (await this.#writeResolutionError(request, location)) continue;
|
|
60161
60380
|
if (location.kind === "external") {
|
|
@@ -60276,7 +60495,6 @@ var AppServerHost = class {
|
|
|
60276
60495
|
}
|
|
60277
60496
|
const result = updateStartResultSchema.parse(await coordinator.start());
|
|
60278
60497
|
await this.#writer.json(rpcEnvelope(request, { result: jsonValueSchema.parse(result) }));
|
|
60279
|
-
coordinator.requestShutdown();
|
|
60280
60498
|
} catch (error52) {
|
|
60281
60499
|
await this.#writer.json(rpcError(request, -32091, errorMessage3(error52).slice(0, 500)));
|
|
60282
60500
|
}
|
|
@@ -60371,9 +60589,13 @@ var AppServerHost = class {
|
|
|
60371
60589
|
);
|
|
60372
60590
|
return;
|
|
60373
60591
|
}
|
|
60592
|
+
const adapter = this.#externalAdapters.get(resolution.thread.harnessId);
|
|
60593
|
+
if (adapter && isCreditsAdapter(adapter)) void adapter.refreshCredits();
|
|
60594
|
+
const credits = adapter && isCreditsAdapter(adapter) ? projectAccountCredits(adapter.credits()) : null;
|
|
60374
60595
|
const result = threadUsageInspectionSchema.parse({
|
|
60375
60596
|
threadId: params.data.threadId,
|
|
60376
|
-
usage: resolution.thread.latestUsage
|
|
60597
|
+
usage: resolution.thread.latestUsage,
|
|
60598
|
+
...credits ? { accountCredits: credits } : {}
|
|
60377
60599
|
});
|
|
60378
60600
|
await this.#writer.json(rpcEnvelope(request, { result: jsonValueSchema.parse(result) }));
|
|
60379
60601
|
}
|
|
@@ -60975,10 +61197,10 @@ var AppServerHost = class {
|
|
|
60975
61197
|
...typeof params.serviceTier === "string" ? { serviceTier: params.serviceTier } : {}
|
|
60976
61198
|
});
|
|
60977
61199
|
try {
|
|
60978
|
-
if (params.initialTurnsPage !== void 0 && params.initialTurnsPage !== null && !
|
|
61200
|
+
if (params.initialTurnsPage !== void 0 && params.initialTurnsPage !== null && !isRecord26(params.initialTurnsPage)) {
|
|
60979
61201
|
throw new ExternalHistoryRequestError("initialTurnsPage must be an object");
|
|
60980
61202
|
}
|
|
60981
|
-
const initialPageParams =
|
|
61203
|
+
const initialPageParams = isRecord26(params.initialTurnsPage) ? params.initialTurnsPage : null;
|
|
60982
61204
|
const initialTurnsPage = initialPageParams ? listExternalTurns(turns, initialPageParams) : null;
|
|
60983
61205
|
const paginated = thread.record.historyMode === "paginated";
|
|
60984
61206
|
const turnsBackwardsCursor = paginated ? listExternalTurns(turns, { limit: 1, itemsView: "notLoaded" }).backwardsCursor : null;
|
|
@@ -61230,7 +61452,7 @@ var AppServerHost = class {
|
|
|
61230
61452
|
}
|
|
61231
61453
|
}
|
|
61232
61454
|
async #handleDesktopApprovalResponse(value) {
|
|
61233
|
-
if (!
|
|
61455
|
+
if (!isRecord26(value) || !isHostApprovalRequestId(value.id)) return false;
|
|
61234
61456
|
const pending = this.#pendingDesktopApprovals.get(value.id);
|
|
61235
61457
|
if (!pending) return true;
|
|
61236
61458
|
this.#pendingDesktopApprovals.delete(value.id);
|
|
@@ -61352,7 +61574,7 @@ var AppServerHost = class {
|
|
|
61352
61574
|
}
|
|
61353
61575
|
}
|
|
61354
61576
|
async #handleDesktopQuestionResponse(value) {
|
|
61355
|
-
if (!
|
|
61577
|
+
if (!isRecord26(value) || !isHostQuestionRequestId(value.id)) return false;
|
|
61356
61578
|
const pending = this.#pendingDesktopQuestions.get(value.id);
|
|
61357
61579
|
if (!pending) return true;
|
|
61358
61580
|
this.#pendingDesktopQuestions.delete(value.id);
|
|
@@ -61453,18 +61675,18 @@ var AppServerHost = class {
|
|
|
61453
61675
|
}
|
|
61454
61676
|
await this.#writer.json(projection);
|
|
61455
61677
|
}
|
|
61678
|
+
#dispatchDesktopRequest(run) {
|
|
61679
|
+
void run().catch((error52) => this.#diagnose(error52));
|
|
61680
|
+
}
|
|
61456
61681
|
#diagnose(error52) {
|
|
61457
61682
|
this.#options.diagnosticOutput.write(`codexhost Host Runtime: ${errorMessage3(error52)}
|
|
61458
61683
|
`);
|
|
61459
61684
|
}
|
|
61460
61685
|
};
|
|
61461
61686
|
|
|
61462
|
-
// packages/host-runtime/src/update-coordinator.ts
|
|
61463
|
-
import { createConnection } from "node:net";
|
|
61464
|
-
|
|
61465
61687
|
// packages/update-manager/dist/distribution.js
|
|
61466
|
-
import { lstat, readFile as
|
|
61467
|
-
import
|
|
61688
|
+
import { lstat, readFile as readFile4 } from "node:fs/promises";
|
|
61689
|
+
import path15 from "node:path";
|
|
61468
61690
|
|
|
61469
61691
|
// packages/update-manager/dist/status.js
|
|
61470
61692
|
var STATUS_SCHEMA_VERSION = 1;
|
|
@@ -61519,6 +61741,7 @@ function parseUpdateStatus(value) {
|
|
|
61519
61741
|
var UPDATE_RUNTIME_ENV = Object.freeze({
|
|
61520
61742
|
launcherPid: "CODEXHOST_LAUNCHER_PID",
|
|
61521
61743
|
launcherExecutable: "CODEXHOST_LAUNCHER_EXECUTABLE",
|
|
61744
|
+
runtimeDescriptorPath: "CODEXHOST_RUNTIME_DESCRIPTOR_PATH",
|
|
61522
61745
|
controllerPort: "CODEXHOST_CONTROL_PORT",
|
|
61523
61746
|
controllerNonce: "CODEXHOST_CONTROL_NONCE",
|
|
61524
61747
|
npmNodePath: "CODEXHOST_NPM_NODE_PATH",
|
|
@@ -61538,7 +61761,7 @@ function parseDistributionMetadata(value) {
|
|
|
61538
61761
|
if (Object.keys(metadata).some((key) => !allowed2.includes(key))) {
|
|
61539
61762
|
throw new Error("distribution metadata contains unknown fields");
|
|
61540
61763
|
}
|
|
61541
|
-
if (metadata.schemaVersion !== 1 || metadata.distribution !== "npm" && metadata.distribution !== "installer" || !["macos-arm64", "macos-x64", "windows-x64", "windows-arm64"].includes(String(metadata.target)) || typeof metadata.version !== "string") {
|
|
61764
|
+
if (metadata.schemaVersion !== 1 || metadata.distribution !== "npm" && metadata.distribution !== "installer" || !["macos-arm64", "macos-x64", "windows-x64", "windows-arm64", "linux-x64"].includes(String(metadata.target)) || typeof metadata.version !== "string") {
|
|
61542
61765
|
throw new Error("distribution metadata is invalid");
|
|
61543
61766
|
}
|
|
61544
61767
|
return {
|
|
@@ -61550,9 +61773,9 @@ function parseDistributionMetadata(value) {
|
|
|
61550
61773
|
}
|
|
61551
61774
|
function absoluteEnvironmentPath(environment, name) {
|
|
61552
61775
|
const value = environment[name];
|
|
61553
|
-
if (!value || !
|
|
61776
|
+
if (!value || !path15.isAbsolute(value))
|
|
61554
61777
|
throw new Error(`${name} must be an absolute path`);
|
|
61555
|
-
return
|
|
61778
|
+
return path15.normalize(value);
|
|
61556
61779
|
}
|
|
61557
61780
|
function positiveEnvironmentInteger(environment, name) {
|
|
61558
61781
|
const value = Number(environment[name]);
|
|
@@ -61569,48 +61792,52 @@ function expectedTarget(platform, architecture) {
|
|
|
61569
61792
|
return "windows-arm64";
|
|
61570
61793
|
if (platform === "win32" && architecture === "x64")
|
|
61571
61794
|
return "windows-x64";
|
|
61795
|
+
if (platform === "linux" && architecture === "x64")
|
|
61796
|
+
return "linux-x64";
|
|
61572
61797
|
throw new Error(`unsupported update host ${platform}/${architecture}`);
|
|
61573
61798
|
}
|
|
61574
61799
|
function defaultUpdateStateDirectory(platform = process.platform, environment = process.env) {
|
|
61575
61800
|
if (platform === "win32") {
|
|
61576
61801
|
const root = environment.LOCALAPPDATA;
|
|
61577
|
-
if (!root || !
|
|
61802
|
+
if (!root || !path15.isAbsolute(root))
|
|
61578
61803
|
throw new Error("LOCALAPPDATA is unavailable");
|
|
61579
|
-
return
|
|
61804
|
+
return path15.join(root, "codexhost", "updates");
|
|
61580
61805
|
}
|
|
61581
61806
|
const home = environment.HOME;
|
|
61582
|
-
if (!home || !
|
|
61807
|
+
if (!home || !path15.isAbsolute(home))
|
|
61583
61808
|
throw new Error("HOME is unavailable");
|
|
61584
|
-
return platform === "darwin" ?
|
|
61809
|
+
return platform === "darwin" ? path15.join(home, "Library", "Application Support", "codexhost", "updates") : path15.join(home, ".codexhost", "updates");
|
|
61585
61810
|
}
|
|
61586
61811
|
async function resolveInstalledUpdateContext(options) {
|
|
61587
61812
|
const environment = options.environment ?? process.env;
|
|
61588
61813
|
const platform = options.platform ?? process.platform;
|
|
61589
61814
|
const architecture = options.architecture ?? process.arch;
|
|
61590
|
-
if (!
|
|
61815
|
+
if (!path15.isAbsolute(options.hostRuntimePath)) {
|
|
61591
61816
|
throw new Error("Host Runtime path must be absolute");
|
|
61592
61817
|
}
|
|
61593
|
-
const hostRuntimePath =
|
|
61818
|
+
const hostRuntimePath = path15.normalize(options.hostRuntimePath);
|
|
61594
61819
|
const runtimeMetadata = await lstat(hostRuntimePath);
|
|
61595
61820
|
if (!runtimeMetadata.isFile() || runtimeMetadata.isSymbolicLink()) {
|
|
61596
61821
|
throw new Error("Host Runtime must be a regular file");
|
|
61597
61822
|
}
|
|
61598
|
-
const appDirectory =
|
|
61599
|
-
const metadata = parseDistributionMetadata(JSON.parse(await
|
|
61823
|
+
const appDirectory = path15.dirname(hostRuntimePath);
|
|
61824
|
+
const metadata = parseDistributionMetadata(JSON.parse(await readFile4(path15.join(appDirectory, "codexhost-distribution.json"), "utf8")));
|
|
61600
61825
|
const target = expectedTarget(platform, architecture);
|
|
61601
61826
|
if (metadata.target !== target) {
|
|
61602
61827
|
throw new Error(`installed target ${metadata.target} does not match ${target}`);
|
|
61603
61828
|
}
|
|
61604
61829
|
const launcherPid = positiveEnvironmentInteger(environment, UPDATE_RUNTIME_ENV.launcherPid);
|
|
61605
61830
|
const launcherExecutable = absoluteEnvironmentPath(environment, UPDATE_RUNTIME_ENV.launcherExecutable);
|
|
61606
|
-
const
|
|
61607
|
-
const
|
|
61608
|
-
const
|
|
61609
|
-
const
|
|
61831
|
+
const runtimeDescriptorPath = absoluteEnvironmentPath(environment, UPDATE_RUNTIME_ENV.runtimeDescriptorPath);
|
|
61832
|
+
const stateDirectory = path15.normalize(options.stateDirectory ?? defaultUpdateStateDirectory(platform, environment));
|
|
61833
|
+
const resourcesRoot = path15.dirname(appDirectory);
|
|
61834
|
+
const installationRoot = platform === "darwin" ? path15.dirname(path15.dirname(resourcesRoot)) : resourcesRoot;
|
|
61835
|
+
const updaterExecutable = path15.join(resourcesRoot, "libexec", platform === "win32" ? "codexhost-updater.exe" : "codexhost-updater");
|
|
61610
61836
|
const common = {
|
|
61611
61837
|
version: metadata.version,
|
|
61612
61838
|
launcherPid,
|
|
61613
61839
|
launcherExecutable,
|
|
61840
|
+
runtimeDescriptorPath,
|
|
61614
61841
|
updaterExecutable,
|
|
61615
61842
|
stateDirectory
|
|
61616
61843
|
};
|
|
@@ -61629,7 +61856,7 @@ async function resolveInstalledUpdateContext(options) {
|
|
|
61629
61856
|
npmLauncherPath: absoluteEnvironmentPath(environment, UPDATE_RUNTIME_ENV.npmLauncherPath),
|
|
61630
61857
|
packageRoot: absoluteEnvironmentPath(environment, UPDATE_RUNTIME_ENV.npmPackageRoot)
|
|
61631
61858
|
};
|
|
61632
|
-
if (
|
|
61859
|
+
if (path15.normalize(npmOptions.packageRoot) !== resourcesRoot) {
|
|
61633
61860
|
throw new Error("npm platform package root does not own the Host Runtime");
|
|
61634
61861
|
}
|
|
61635
61862
|
return { metadata, common, controller, installation: { kind: "npm", options: npmOptions } };
|
|
@@ -61791,8 +62018,8 @@ function selectInstallerReleaseArtifact(release, target) {
|
|
|
61791
62018
|
}
|
|
61792
62019
|
|
|
61793
62020
|
// packages/update-manager/dist/operation-state.js
|
|
61794
|
-
import { lstat as lstat2, mkdir as mkdir2, open as open3, readFile as
|
|
61795
|
-
import
|
|
62021
|
+
import { lstat as lstat2, mkdir as mkdir2, open as open3, readFile as readFile5, readdir as readdir2, rm as rm3, writeFile } from "node:fs/promises";
|
|
62022
|
+
import path16 from "node:path";
|
|
61796
62023
|
var LOCK_FILE = "active-update-v1.lock";
|
|
61797
62024
|
var STATUS_FILE = "status-v1.json";
|
|
61798
62025
|
var TERMINAL_PHASES = /* @__PURE__ */ new Set(["succeeded", "failed"]);
|
|
@@ -61807,12 +62034,12 @@ async function regularFile(filePath) {
|
|
|
61807
62034
|
}
|
|
61808
62035
|
}
|
|
61809
62036
|
async function isUpdateOperationActive(stateDirectory) {
|
|
61810
|
-
if (!
|
|
62037
|
+
if (!path16.isAbsolute(stateDirectory))
|
|
61811
62038
|
throw new Error("update state directory must be absolute");
|
|
61812
|
-
return regularFile(
|
|
62039
|
+
return regularFile(path16.join(stateDirectory, LOCK_FILE));
|
|
61813
62040
|
}
|
|
61814
62041
|
async function discoverLatestUpdateStatus(stateDirectory) {
|
|
61815
|
-
if (!
|
|
62042
|
+
if (!path16.isAbsolute(stateDirectory))
|
|
61816
62043
|
throw new Error("update state directory must be absolute");
|
|
61817
62044
|
let entries;
|
|
61818
62045
|
try {
|
|
@@ -61826,13 +62053,13 @@ async function discoverLatestUpdateStatus(stateDirectory) {
|
|
|
61826
62053
|
for (const entry of entries) {
|
|
61827
62054
|
if (!entry.isDirectory() || entry.isSymbolicLink() || !entry.name.startsWith("update-"))
|
|
61828
62055
|
continue;
|
|
61829
|
-
const statusPath =
|
|
62056
|
+
const statusPath = path16.join(stateDirectory, entry.name, STATUS_FILE);
|
|
61830
62057
|
if (!await regularFile(statusPath))
|
|
61831
62058
|
continue;
|
|
61832
62059
|
try {
|
|
61833
62060
|
candidates2.push({
|
|
61834
62061
|
statusPath,
|
|
61835
|
-
status: parseUpdateStatus(JSON.parse(await
|
|
62062
|
+
status: parseUpdateStatus(JSON.parse(await readFile5(statusPath, "utf8")))
|
|
61836
62063
|
});
|
|
61837
62064
|
} catch {
|
|
61838
62065
|
}
|
|
@@ -61854,10 +62081,10 @@ async function cleanupTerminalUpdateState(stateDirectory, options = {}) {
|
|
|
61854
62081
|
for (const entry of entries) {
|
|
61855
62082
|
if (!entry.isDirectory() || entry.isSymbolicLink() || !entry.name.startsWith("update-"))
|
|
61856
62083
|
continue;
|
|
61857
|
-
const directory =
|
|
61858
|
-
const statusPath =
|
|
62084
|
+
const directory = path16.join(stateDirectory, entry.name);
|
|
62085
|
+
const statusPath = path16.join(directory, STATUS_FILE);
|
|
61859
62086
|
try {
|
|
61860
|
-
const status = parseUpdateStatus(JSON.parse(await
|
|
62087
|
+
const status = parseUpdateStatus(JSON.parse(await readFile5(statusPath, "utf8")));
|
|
61861
62088
|
if (TERMINAL_PHASES.has(status.phase) && now - status.updatedAt > retentionSeconds) {
|
|
61862
62089
|
await rm3(directory, { recursive: true, force: true });
|
|
61863
62090
|
}
|
|
@@ -61866,10 +62093,10 @@ async function cleanupTerminalUpdateState(stateDirectory, options = {}) {
|
|
|
61866
62093
|
}
|
|
61867
62094
|
}
|
|
61868
62095
|
async function acquireUpdateOperationLock(stateDirectory) {
|
|
61869
|
-
if (!
|
|
62096
|
+
if (!path16.isAbsolute(stateDirectory))
|
|
61870
62097
|
throw new Error("update state directory must be absolute");
|
|
61871
62098
|
await mkdir2(stateDirectory, { recursive: true, mode: 448 });
|
|
61872
|
-
const lockPath =
|
|
62099
|
+
const lockPath = path16.join(stateDirectory, LOCK_FILE);
|
|
61873
62100
|
let handle;
|
|
61874
62101
|
try {
|
|
61875
62102
|
handle = await open3(lockPath, "wx", 384);
|
|
@@ -61888,9 +62115,9 @@ async function acquireUpdateOperationLock(stateDirectory) {
|
|
|
61888
62115
|
async setStatusPath(statusPath) {
|
|
61889
62116
|
if (released)
|
|
61890
62117
|
throw new Error("update operation lock is released");
|
|
61891
|
-
if (!
|
|
62118
|
+
if (!path16.isAbsolute(statusPath))
|
|
61892
62119
|
throw new Error("update status path must be absolute");
|
|
61893
|
-
await writeFile(lockPath, `${JSON.stringify({ ownerPid: process.pid, statusPath:
|
|
62120
|
+
await writeFile(lockPath, `${JSON.stringify({ ownerPid: process.pid, statusPath: path16.normalize(statusPath) })}
|
|
61894
62121
|
`, { encoding: "utf8", mode: 384 });
|
|
61895
62122
|
},
|
|
61896
62123
|
async release() {
|
|
@@ -61912,22 +62139,22 @@ function processIsAlive(processId) {
|
|
|
61912
62139
|
}
|
|
61913
62140
|
}
|
|
61914
62141
|
async function recoverUpdateOperationLock(stateDirectory) {
|
|
61915
|
-
const lockPath =
|
|
62142
|
+
const lockPath = path16.join(stateDirectory, LOCK_FILE);
|
|
61916
62143
|
if (!await regularFile(lockPath))
|
|
61917
62144
|
return;
|
|
61918
62145
|
let ownerPid;
|
|
61919
62146
|
let statusPath;
|
|
61920
62147
|
try {
|
|
61921
|
-
const value = JSON.parse(await
|
|
62148
|
+
const value = JSON.parse(await readFile5(lockPath, "utf8"));
|
|
61922
62149
|
ownerPid = value.ownerPid;
|
|
61923
62150
|
statusPath = value.statusPath;
|
|
61924
62151
|
} catch {
|
|
61925
62152
|
return;
|
|
61926
62153
|
}
|
|
61927
|
-
if (typeof statusPath !== "string" || !
|
|
62154
|
+
if (typeof statusPath !== "string" || !path16.isAbsolute(statusPath))
|
|
61928
62155
|
return;
|
|
61929
62156
|
try {
|
|
61930
|
-
const status = parseUpdateStatus(JSON.parse(await
|
|
62157
|
+
const status = parseUpdateStatus(JSON.parse(await readFile5(statusPath, "utf8")));
|
|
61931
62158
|
if (TERMINAL_PHASES.has(status.phase) || typeof ownerPid !== "number" || !processIsAlive(ownerPid)) {
|
|
61932
62159
|
await rm3(lockPath, { force: true });
|
|
61933
62160
|
}
|
|
@@ -61938,8 +62165,8 @@ async function recoverUpdateOperationLock(stateDirectory) {
|
|
|
61938
62165
|
// packages/update-manager/dist/update-manager.js
|
|
61939
62166
|
import { spawn as spawn6 } from "node:child_process";
|
|
61940
62167
|
import { randomUUID as randomUUID10 } from "node:crypto";
|
|
61941
|
-
import { chmod, copyFile as copyFile2, lstat as lstat4, mkdir as mkdir3, readFile as
|
|
61942
|
-
import
|
|
62168
|
+
import { chmod, copyFile as copyFile2, lstat as lstat4, mkdir as mkdir3, readFile as readFile6, rename as rename2, rm as rm4, writeFile as writeFile2 } from "node:fs/promises";
|
|
62169
|
+
import path17 from "node:path";
|
|
61943
62170
|
|
|
61944
62171
|
// packages/update-manager/dist/artifact.js
|
|
61945
62172
|
import { createHash as createHash2 } from "node:crypto";
|
|
@@ -62032,13 +62259,37 @@ async function verifyDownloadedArtifact(source, filePath, result) {
|
|
|
62032
62259
|
|
|
62033
62260
|
// packages/update-manager/dist/update-manager.js
|
|
62034
62261
|
var REQUEST_SCHEMA_VERSION = 1;
|
|
62262
|
+
var WINDOWS_RENAME_RETRY_DELAYS_MS = [10, 30, 70, 150, 300];
|
|
62035
62263
|
function errorMessage4(error52) {
|
|
62036
62264
|
return error52 instanceof Error ? error52.message : String(error52);
|
|
62037
62265
|
}
|
|
62266
|
+
function systemErrorCode2(error52) {
|
|
62267
|
+
return typeof error52 === "object" && error52 !== null && "code" in error52 ? String(error52.code) : null;
|
|
62268
|
+
}
|
|
62269
|
+
function delay4(milliseconds) {
|
|
62270
|
+
return new Promise((resolve2) => setTimeout(resolve2, milliseconds));
|
|
62271
|
+
}
|
|
62272
|
+
async function replaceStatusFile(temporaryPath, statusPath) {
|
|
62273
|
+
let retryIndex = 0;
|
|
62274
|
+
for (; ; ) {
|
|
62275
|
+
try {
|
|
62276
|
+
await rename2(temporaryPath, statusPath);
|
|
62277
|
+
return;
|
|
62278
|
+
} catch (error52) {
|
|
62279
|
+
const retryDelay = WINDOWS_RENAME_RETRY_DELAYS_MS[retryIndex];
|
|
62280
|
+
const code = systemErrorCode2(error52);
|
|
62281
|
+
if (process.platform !== "win32" || retryDelay === void 0 || code !== "EACCES" && code !== "EBUSY" && code !== "EPERM") {
|
|
62282
|
+
throw error52;
|
|
62283
|
+
}
|
|
62284
|
+
retryIndex += 1;
|
|
62285
|
+
await delay4(retryDelay);
|
|
62286
|
+
}
|
|
62287
|
+
}
|
|
62288
|
+
}
|
|
62038
62289
|
function requireAbsolutePath(value, label) {
|
|
62039
|
-
if (!
|
|
62290
|
+
if (!path17.isAbsolute(value))
|
|
62040
62291
|
throw new Error(`${label} must be an absolute path`);
|
|
62041
|
-
return
|
|
62292
|
+
return path17.normalize(value);
|
|
62042
62293
|
}
|
|
62043
62294
|
async function requireRegularFile(value, label) {
|
|
62044
62295
|
const filePath = requireAbsolutePath(value, label);
|
|
@@ -62081,7 +62332,7 @@ function createBackgroundUpdateManager(dependencies = {}) {
|
|
|
62081
62332
|
const now = dependencies.now ?? Date.now;
|
|
62082
62333
|
const preparedRequests = /* @__PURE__ */ new Set();
|
|
62083
62334
|
async function writeStatusSnapshot(statusPath, status) {
|
|
62084
|
-
const temporaryPath =
|
|
62335
|
+
const temporaryPath = path17.join(path17.dirname(statusPath), `.update-status-${randomId()}.tmp`);
|
|
62085
62336
|
try {
|
|
62086
62337
|
await writeFile2(temporaryPath, `${JSON.stringify(status)}
|
|
62087
62338
|
`, {
|
|
@@ -62089,7 +62340,7 @@ function createBackgroundUpdateManager(dependencies = {}) {
|
|
|
62089
62340
|
mode: 384,
|
|
62090
62341
|
flag: "wx"
|
|
62091
62342
|
});
|
|
62092
|
-
await
|
|
62343
|
+
await replaceStatusFile(temporaryPath, statusPath);
|
|
62093
62344
|
} catch (error52) {
|
|
62094
62345
|
await rm4(temporaryPath, { force: true });
|
|
62095
62346
|
throw error52;
|
|
@@ -62137,24 +62388,26 @@ function createBackgroundUpdateManager(dependencies = {}) {
|
|
|
62137
62388
|
const version2 = requireSemanticVersion(options.version);
|
|
62138
62389
|
const launcherPid = requireLauncherPid(options.launcherPid);
|
|
62139
62390
|
const launcherExecutable = await requireRegularFile(options.launcherExecutable, "Launcher executable");
|
|
62391
|
+
const runtimeDescriptorPath = requireAbsolutePath(options.runtimeDescriptorPath, "runtime descriptor path");
|
|
62140
62392
|
const updaterExecutable = await requireRegularFile(options.updaterExecutable, "Updater executable");
|
|
62141
62393
|
const stateDirectory = requireAbsolutePath(options.stateDirectory, "update state directory");
|
|
62142
62394
|
await mkdir3(stateDirectory, { recursive: true, mode: 448 });
|
|
62143
|
-
const workDirectory =
|
|
62395
|
+
const workDirectory = path17.join(stateDirectory, `update-${version2}-${randomId()}`);
|
|
62144
62396
|
await mkdir3(workDirectory, { recursive: false, mode: 448 });
|
|
62145
62397
|
const executableSuffix = platform === "win32" ? ".exe" : "";
|
|
62146
|
-
const helperPath =
|
|
62398
|
+
const helperPath = path17.join(workDirectory, `codexhost-updater${executableSuffix}`);
|
|
62147
62399
|
await copyFile2(updaterExecutable, helperPath);
|
|
62148
62400
|
if (platform !== "win32")
|
|
62149
62401
|
await chmod(helperPath, 448);
|
|
62150
|
-
const requestPath =
|
|
62151
|
-
const statusPath =
|
|
62402
|
+
const requestPath = path17.join(workDirectory, "request-v1.json");
|
|
62403
|
+
const statusPath = path17.join(workDirectory, "status-v1.json");
|
|
62152
62404
|
await writePrivateJson(statusPath, preparedStatus(version2, installation, now()));
|
|
62153
62405
|
await options.onPrepared?.({ version: version2, installation, statusPath });
|
|
62154
62406
|
return {
|
|
62155
62407
|
version: version2,
|
|
62156
62408
|
launcherPid,
|
|
62157
62409
|
launcherExecutable,
|
|
62410
|
+
runtimeDescriptorPath,
|
|
62158
62411
|
workDirectory,
|
|
62159
62412
|
helperPath,
|
|
62160
62413
|
requestPath,
|
|
@@ -62163,8 +62416,8 @@ function createBackgroundUpdateManager(dependencies = {}) {
|
|
|
62163
62416
|
}
|
|
62164
62417
|
async function prepareArtifact(common, installation, sourceValue, fileName) {
|
|
62165
62418
|
const source = validateArtifact(sourceValue);
|
|
62166
|
-
const temporaryPath =
|
|
62167
|
-
const artifactPath =
|
|
62419
|
+
const temporaryPath = path17.join(common.workDirectory, `.${fileName}.download`);
|
|
62420
|
+
const artifactPath = path17.join(common.workDirectory, fileName);
|
|
62168
62421
|
const progress = progressReporter(common.statusPath, common.version, installation, source.size);
|
|
62169
62422
|
try {
|
|
62170
62423
|
const result = await download(source, temporaryPath, progress.update);
|
|
@@ -62190,6 +62443,7 @@ function createBackgroundUpdateManager(dependencies = {}) {
|
|
|
62190
62443
|
version: common.version,
|
|
62191
62444
|
wait_pid: common.launcherPid,
|
|
62192
62445
|
wait_executable: common.launcherExecutable,
|
|
62446
|
+
runtime_descriptor_path: common.runtimeDescriptorPath,
|
|
62193
62447
|
status_path: common.statusPath,
|
|
62194
62448
|
installation
|
|
62195
62449
|
};
|
|
@@ -62237,7 +62491,7 @@ function createBackgroundUpdateManager(dependencies = {}) {
|
|
|
62237
62491
|
throw new Error("macOS DMG updates require macOS");
|
|
62238
62492
|
const common = await prepareCommon(options, "macos-dmg");
|
|
62239
62493
|
const appPath = requireAbsolutePath(options.appPath, "macOS application path");
|
|
62240
|
-
if (
|
|
62494
|
+
if (path17.extname(appPath) !== ".app") {
|
|
62241
62495
|
throw new Error("macOS application path must end in .app");
|
|
62242
62496
|
}
|
|
62243
62497
|
const artifact = await prepareArtifact(common, "macos-dmg", options.artifact, "update.dmg");
|
|
@@ -62260,7 +62514,7 @@ function createBackgroundUpdateManager(dependencies = {}) {
|
|
|
62260
62514
|
async readStatus(statusPathValue) {
|
|
62261
62515
|
const statusPath = requireAbsolutePath(statusPathValue, "update status path");
|
|
62262
62516
|
try {
|
|
62263
|
-
return parseUpdateStatus(JSON.parse(await
|
|
62517
|
+
return parseUpdateStatus(JSON.parse(await readFile6(statusPath, "utf8")));
|
|
62264
62518
|
} catch (error52) {
|
|
62265
62519
|
if (error52.code === "ENOENT")
|
|
62266
62520
|
return null;
|
|
@@ -62272,37 +62526,10 @@ function createBackgroundUpdateManager(dependencies = {}) {
|
|
|
62272
62526
|
|
|
62273
62527
|
// packages/host-runtime/src/update-coordinator.ts
|
|
62274
62528
|
var ERROR_MAX_LENGTH = 500;
|
|
62275
|
-
var CONTROLLER_TIMEOUT_MS = 5e3;
|
|
62276
|
-
var UPDATER_READY_TIMEOUT_MS = 1e4;
|
|
62277
|
-
var UPDATER_READY_POLL_MS = 20;
|
|
62278
62529
|
function boundedError(error52) {
|
|
62279
62530
|
const message3 = error52 instanceof Error ? error52.message : String(error52);
|
|
62280
62531
|
return message3.slice(0, ERROR_MAX_LENGTH) || "Update operation failed";
|
|
62281
62532
|
}
|
|
62282
|
-
function delay4(milliseconds) {
|
|
62283
|
-
return new Promise((resolve2) => setTimeout(resolve2, milliseconds));
|
|
62284
|
-
}
|
|
62285
|
-
async function waitForUpdaterReady(manager, statusPath) {
|
|
62286
|
-
const deadline = Date.now() + UPDATER_READY_TIMEOUT_MS;
|
|
62287
|
-
while (Date.now() < deadline) {
|
|
62288
|
-
const status = await manager.readStatus(statusPath);
|
|
62289
|
-
switch (status?.phase) {
|
|
62290
|
-
case "waiting-for-exit":
|
|
62291
|
-
case "installing":
|
|
62292
|
-
case "restarting":
|
|
62293
|
-
case "succeeded":
|
|
62294
|
-
return;
|
|
62295
|
-
case "failed":
|
|
62296
|
-
throw new Error(status.error ?? "Background Updater failed before Desktop shutdown");
|
|
62297
|
-
case "prepared":
|
|
62298
|
-
break;
|
|
62299
|
-
default:
|
|
62300
|
-
throw new Error("Background Updater reported an unexpected startup phase");
|
|
62301
|
-
}
|
|
62302
|
-
await delay4(UPDATER_READY_POLL_MS);
|
|
62303
|
-
}
|
|
62304
|
-
throw new Error("Background Updater did not become ready before Desktop shutdown");
|
|
62305
|
-
}
|
|
62306
62533
|
function publicStatus(status) {
|
|
62307
62534
|
return {
|
|
62308
62535
|
version: status.version,
|
|
@@ -62314,34 +62541,6 @@ function publicStatus(status) {
|
|
|
62314
62541
|
error: status.error?.slice(0, ERROR_MAX_LENGTH) ?? null
|
|
62315
62542
|
};
|
|
62316
62543
|
}
|
|
62317
|
-
function requestControllerShutdown(controller) {
|
|
62318
|
-
return new Promise((resolve2, reject) => {
|
|
62319
|
-
const socket = createConnection({ host: "127.0.0.1", port: controller.port });
|
|
62320
|
-
let response = "";
|
|
62321
|
-
const timeout = setTimeout(
|
|
62322
|
-
() => socket.destroy(new Error("Controller shutdown timed out")),
|
|
62323
|
-
CONTROLLER_TIMEOUT_MS
|
|
62324
|
-
);
|
|
62325
|
-
const settle = (operation) => {
|
|
62326
|
-
clearTimeout(timeout);
|
|
62327
|
-
operation();
|
|
62328
|
-
};
|
|
62329
|
-
socket.setEncoding("utf8");
|
|
62330
|
-
socket.once("error", (error52) => settle(() => reject(error52)));
|
|
62331
|
-
socket.on("data", (chunk) => {
|
|
62332
|
-
response += chunk;
|
|
62333
|
-
});
|
|
62334
|
-
socket.once(
|
|
62335
|
-
"end",
|
|
62336
|
-
() => settle(() => {
|
|
62337
|
-
if (response === "ready\n") resolve2();
|
|
62338
|
-
else reject(new Error("Desktop Controller rejected the shutdown request"));
|
|
62339
|
-
})
|
|
62340
|
-
);
|
|
62341
|
-
socket.once("connect", () => socket.write(`SHUTDOWN ${controller.nonce}
|
|
62342
|
-
`));
|
|
62343
|
-
});
|
|
62344
|
-
}
|
|
62345
62544
|
function createHostUpdateCoordinator(options) {
|
|
62346
62545
|
const platform = options.platform ?? process.platform;
|
|
62347
62546
|
const manager = options.manager ?? createBackgroundUpdateManager({ platform });
|
|
@@ -62352,16 +62551,7 @@ function createHostUpdateCoordinator(options) {
|
|
|
62352
62551
|
...options.architecture ? { architecture: options.architecture } : {}
|
|
62353
62552
|
});
|
|
62354
62553
|
const fetchLatest = options.fetchLatest ?? ((signal) => fetchLatestGitHubRelease({ signal: signal ?? AbortSignal.timeout(15e3) }));
|
|
62355
|
-
const shutdown = options.shutdown ?? requestControllerShutdown;
|
|
62356
62554
|
let candidate = null;
|
|
62357
|
-
let shutdownPending = null;
|
|
62358
|
-
let shutdownRequested = false;
|
|
62359
|
-
const scheduleShutdown = () => {
|
|
62360
|
-
if (!shutdownRequested || !shutdownPending) return;
|
|
62361
|
-
const controller = shutdownPending;
|
|
62362
|
-
shutdownPending = null;
|
|
62363
|
-
setTimeout(() => void shutdown(controller).catch(() => void 0), 50).unref();
|
|
62364
|
-
};
|
|
62365
62555
|
async function latestStatus(context) {
|
|
62366
62556
|
const discovered = await discoverLatestUpdateStatus(context.common.stateDirectory);
|
|
62367
62557
|
if (!discovered) return null;
|
|
@@ -62371,9 +62561,11 @@ function createHostUpdateCoordinator(options) {
|
|
|
62371
62561
|
return publicStatus(discovered.status);
|
|
62372
62562
|
}
|
|
62373
62563
|
async function installable(context, release) {
|
|
62374
|
-
if (context.
|
|
62564
|
+
if (context.installation.kind === "npm") return true;
|
|
62565
|
+
const target = context.metadata.target;
|
|
62566
|
+
if (target === "linux-x64") return false;
|
|
62375
62567
|
try {
|
|
62376
|
-
selectInstallerReleaseArtifact(release,
|
|
62568
|
+
selectInstallerReleaseArtifact(release, target);
|
|
62377
62569
|
return true;
|
|
62378
62570
|
} catch {
|
|
62379
62571
|
return false;
|
|
@@ -62471,10 +62663,11 @@ function createHostUpdateCoordinator(options) {
|
|
|
62471
62663
|
onPrepared
|
|
62472
62664
|
});
|
|
62473
62665
|
} else {
|
|
62474
|
-
const
|
|
62475
|
-
|
|
62476
|
-
|
|
62477
|
-
|
|
62666
|
+
const target = context.metadata.target;
|
|
62667
|
+
if (target === "linux-x64") {
|
|
62668
|
+
throw new Error("Linux installer updates are unsupported");
|
|
62669
|
+
}
|
|
62670
|
+
const artifact = selectInstallerReleaseArtifact(release, target).source;
|
|
62478
62671
|
prepared2 = context.installation.kind === "windows-installer" ? await manager.prepareWindowsInstaller({
|
|
62479
62672
|
...context.installation.options,
|
|
62480
62673
|
version: release.version,
|
|
@@ -62488,9 +62681,6 @@ function createHostUpdateCoordinator(options) {
|
|
|
62488
62681
|
});
|
|
62489
62682
|
}
|
|
62490
62683
|
if (platform !== "darwin") manager.start(prepared2);
|
|
62491
|
-
await waitForUpdaterReady(manager, prepared2.statusPath);
|
|
62492
|
-
shutdownPending = context.controller;
|
|
62493
|
-
scheduleShutdown();
|
|
62494
62684
|
} catch (error52) {
|
|
62495
62685
|
await lock.release();
|
|
62496
62686
|
rejectPrepared(error52);
|
|
@@ -62514,10 +62704,6 @@ function createHostUpdateCoordinator(options) {
|
|
|
62514
62704
|
} catch {
|
|
62515
62705
|
return { status: null };
|
|
62516
62706
|
}
|
|
62517
|
-
},
|
|
62518
|
-
requestShutdown() {
|
|
62519
|
-
shutdownRequested = true;
|
|
62520
|
-
scheduleShutdown();
|
|
62521
62707
|
}
|
|
62522
62708
|
});
|
|
62523
62709
|
}
|