@liberseek/boft-cli-win32-arm64 0.6.4 → 0.6.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/app/codexhost-distribution.json +1 -1
- package/app/host-runtime.mjs +508 -242
- package/app/plugins/antigravity/plugin.mjs +9 -7
- package/app/plugins/claude-code/plugin.mjs +664 -229
- package/app/plugins/deepseek-harness/plugin.mjs +7797 -10553
- package/app/plugins/grok/plugin.mjs +48 -24
- package/app/plugins/kiro-cli/plugin.mjs +77 -61
- package/app/plugins/omp/plugin.mjs +6 -0
- package/app/plugins/opencode/plugin.mjs +292 -142
- package/app/plugins/pi/plugin.mjs +1489 -1304
- package/app/renderer-extension.js +812 -449
- package/bin/{codexhost.exe → boft.exe} +0 -0
- package/libexec/{codexhost-node-repl.exe → boft-node-repl.exe} +0 -0
- package/libexec/{codexhost-shim.exe → boft-shim.exe} +0 -0
- package/libexec/{codexhost-updater.exe → boft-updater.exe} +0 -0
- package/package.json +1 -1
|
@@ -776,10 +776,10 @@ function mergeDefs(...defs) {
|
|
|
776
776
|
function cloneDef(schema) {
|
|
777
777
|
return mergeDefs(schema._zod.def);
|
|
778
778
|
}
|
|
779
|
-
function getElementAtPath(obj,
|
|
780
|
-
if (!
|
|
779
|
+
function getElementAtPath(obj, path14) {
|
|
780
|
+
if (!path14)
|
|
781
781
|
return obj;
|
|
782
|
-
return
|
|
782
|
+
return path14.reduce((acc, key) => acc?.[key], obj);
|
|
783
783
|
}
|
|
784
784
|
function promiseAllObject(promisesObj) {
|
|
785
785
|
const keys = Object.keys(promisesObj);
|
|
@@ -1188,11 +1188,11 @@ function explicitlyAborted(x2, startIndex = 0) {
|
|
|
1188
1188
|
}
|
|
1189
1189
|
return false;
|
|
1190
1190
|
}
|
|
1191
|
-
function prefixIssues(
|
|
1191
|
+
function prefixIssues(path14, issues) {
|
|
1192
1192
|
return issues.map((iss) => {
|
|
1193
1193
|
var _a4;
|
|
1194
1194
|
(_a4 = iss).path ?? (_a4.path = []);
|
|
1195
|
-
iss.path.unshift(
|
|
1195
|
+
iss.path.unshift(path14);
|
|
1196
1196
|
return iss;
|
|
1197
1197
|
});
|
|
1198
1198
|
}
|
|
@@ -1339,16 +1339,16 @@ function flattenError(error52, mapper = (issue2) => issue2.message) {
|
|
|
1339
1339
|
}
|
|
1340
1340
|
function formatError(error52, mapper = (issue2) => issue2.message) {
|
|
1341
1341
|
const fieldErrors = { _errors: [] };
|
|
1342
|
-
const processError = (error53,
|
|
1342
|
+
const processError = (error53, path14 = []) => {
|
|
1343
1343
|
for (const issue2 of error53.issues) {
|
|
1344
1344
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
1345
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
1345
|
+
issue2.errors.map((issues) => processError({ issues }, [...path14, ...issue2.path]));
|
|
1346
1346
|
} else if (issue2.code === "invalid_key") {
|
|
1347
|
-
processError({ issues: issue2.issues }, [...
|
|
1347
|
+
processError({ issues: issue2.issues }, [...path14, ...issue2.path]);
|
|
1348
1348
|
} else if (issue2.code === "invalid_element") {
|
|
1349
|
-
processError({ issues: issue2.issues }, [...
|
|
1349
|
+
processError({ issues: issue2.issues }, [...path14, ...issue2.path]);
|
|
1350
1350
|
} else {
|
|
1351
|
-
const fullpath = [...
|
|
1351
|
+
const fullpath = [...path14, ...issue2.path];
|
|
1352
1352
|
if (fullpath.length === 0) {
|
|
1353
1353
|
fieldErrors._errors.push(mapper(issue2));
|
|
1354
1354
|
} else {
|
|
@@ -1375,17 +1375,17 @@ function formatError(error52, mapper = (issue2) => issue2.message) {
|
|
|
1375
1375
|
}
|
|
1376
1376
|
function treeifyError(error52, mapper = (issue2) => issue2.message) {
|
|
1377
1377
|
const result = { errors: [] };
|
|
1378
|
-
const processError = (error53,
|
|
1378
|
+
const processError = (error53, path14 = []) => {
|
|
1379
1379
|
var _a4, _b2;
|
|
1380
1380
|
for (const issue2 of error53.issues) {
|
|
1381
1381
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
1382
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
1382
|
+
issue2.errors.map((issues) => processError({ issues }, [...path14, ...issue2.path]));
|
|
1383
1383
|
} else if (issue2.code === "invalid_key") {
|
|
1384
|
-
processError({ issues: issue2.issues }, [...
|
|
1384
|
+
processError({ issues: issue2.issues }, [...path14, ...issue2.path]);
|
|
1385
1385
|
} else if (issue2.code === "invalid_element") {
|
|
1386
|
-
processError({ issues: issue2.issues }, [...
|
|
1386
|
+
processError({ issues: issue2.issues }, [...path14, ...issue2.path]);
|
|
1387
1387
|
} else {
|
|
1388
|
-
const fullpath = [...
|
|
1388
|
+
const fullpath = [...path14, ...issue2.path];
|
|
1389
1389
|
if (fullpath.length === 0) {
|
|
1390
1390
|
result.errors.push(mapper(issue2));
|
|
1391
1391
|
continue;
|
|
@@ -1417,8 +1417,8 @@ function treeifyError(error52, mapper = (issue2) => issue2.message) {
|
|
|
1417
1417
|
}
|
|
1418
1418
|
function toDotPath(_path) {
|
|
1419
1419
|
const segs = [];
|
|
1420
|
-
const
|
|
1421
|
-
for (const seg of
|
|
1420
|
+
const path14 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
1421
|
+
for (const seg of path14) {
|
|
1422
1422
|
if (typeof seg === "number")
|
|
1423
1423
|
segs.push(`[${seg}]`);
|
|
1424
1424
|
else if (typeof seg === "symbol")
|
|
@@ -14110,13 +14110,13 @@ function resolveRef(ref, ctx) {
|
|
|
14110
14110
|
if (!ref.startsWith("#")) {
|
|
14111
14111
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
14112
14112
|
}
|
|
14113
|
-
const
|
|
14114
|
-
if (
|
|
14113
|
+
const path14 = ref.slice(1).split("/").filter(Boolean);
|
|
14114
|
+
if (path14.length === 0) {
|
|
14115
14115
|
return ctx.rootSchema;
|
|
14116
14116
|
}
|
|
14117
14117
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
14118
|
-
if (
|
|
14119
|
-
const key =
|
|
14118
|
+
if (path14[0] === defsKey) {
|
|
14119
|
+
const key = path14[1];
|
|
14120
14120
|
if (!key || !ctx.defs[key]) {
|
|
14121
14121
|
throw new Error(`Reference not found: ${ref}`);
|
|
14122
14122
|
}
|
|
@@ -15525,6 +15525,12 @@ function parseHostUsage(value) {
|
|
|
15525
15525
|
throw new Error(`Harness Usage contains unknown field '${key}'`);
|
|
15526
15526
|
}
|
|
15527
15527
|
}
|
|
15528
|
+
for (const field of ["totalCredits", "contextUsagePercent"]) {
|
|
15529
|
+
const candidate = value[field];
|
|
15530
|
+
if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isFinite(candidate) || candidate < 0)) {
|
|
15531
|
+
throw new Error(`Harness Usage '${field}' must be a finite non-negative number`);
|
|
15532
|
+
}
|
|
15533
|
+
}
|
|
15528
15534
|
for (const field of tokenFields) {
|
|
15529
15535
|
const candidate = value[field];
|
|
15530
15536
|
if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isSafeInteger(candidate) || candidate < 0)) {
|
|
@@ -15710,6 +15716,8 @@ var createSchema = external_exports.object({
|
|
|
15710
15716
|
}).strict();
|
|
15711
15717
|
var resumeSchema = external_exports.object({
|
|
15712
15718
|
kind: external_exports.literal("resume"),
|
|
15719
|
+
model: harnessModelRefSchema.optional(),
|
|
15720
|
+
thinkingOptionId: harnessThinkingOptionIdSchema.optional(),
|
|
15713
15721
|
nativeRef: nativeSessionRefSchema,
|
|
15714
15722
|
cwd: cwdSchema,
|
|
15715
15723
|
knownTurnRefs: external_exports.array(nativeTurnRefSchema).max(1e5).optional()
|
|
@@ -15722,6 +15730,9 @@ var forkSchema = external_exports.object({
|
|
|
15722
15730
|
}).strict();
|
|
15723
15731
|
var rollbackSchema = external_exports.object({
|
|
15724
15732
|
kind: external_exports.literal("rollbackLastTurn"),
|
|
15733
|
+
model: harnessModelRefSchema.optional(),
|
|
15734
|
+
thinkingOptionId: harnessThinkingOptionIdSchema.optional(),
|
|
15735
|
+
permissionModeId: harnessPermissionModeIdSchema.optional(),
|
|
15725
15736
|
sourceRef: nativeSessionRefSchema,
|
|
15726
15737
|
cwd: cwdSchema
|
|
15727
15738
|
}).strict();
|
|
@@ -16431,8 +16442,8 @@ var BrokeredHarnessAdapter = class {
|
|
|
16431
16442
|
};
|
|
16432
16443
|
|
|
16433
16444
|
// dist/claude-code-adapter.js
|
|
16434
|
-
import { randomUUID as
|
|
16435
|
-
import
|
|
16445
|
+
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
16446
|
+
import path12 from "node:path";
|
|
16436
16447
|
|
|
16437
16448
|
// ../../../node_modules/@anthropic-ai/claude-agent-sdk/sdk.mjs
|
|
16438
16449
|
import { createRequire as DW } from "node:module";
|
|
@@ -20339,8 +20350,8 @@ var qU = v(function(BU) {
|
|
|
20339
20350
|
BU._globalThis = void 0;
|
|
20340
20351
|
BU._globalThis = typeof globalThis === "object" ? globalThis : global;
|
|
20341
20352
|
});
|
|
20342
|
-
var GU = v(function(
|
|
20343
|
-
var Axe =
|
|
20353
|
+
var GU = v(function(os5) {
|
|
20354
|
+
var Axe = os5 && os5.__createBinding || (Object.create ? function(e, t, r, n) {
|
|
20344
20355
|
if (n === void 0) n = r;
|
|
20345
20356
|
Object.defineProperty(e, n, { enumerable: true, get: function() {
|
|
20346
20357
|
return t[r];
|
|
@@ -20348,11 +20359,11 @@ var GU = v(function(os4) {
|
|
|
20348
20359
|
} : function(e, t, r, n) {
|
|
20349
20360
|
if (n === void 0) n = r;
|
|
20350
20361
|
e[n] = t[r];
|
|
20351
|
-
}), kxe =
|
|
20362
|
+
}), kxe = os5 && os5.__exportStar || function(e, t) {
|
|
20352
20363
|
for (var r in e) if (r !== "default" && !Object.prototype.hasOwnProperty.call(t, r)) Axe(t, e, r);
|
|
20353
20364
|
};
|
|
20354
|
-
Object.defineProperty(
|
|
20355
|
-
kxe(qU(),
|
|
20365
|
+
Object.defineProperty(os5, "__esModule", { value: true });
|
|
20366
|
+
kxe(qU(), os5);
|
|
20356
20367
|
});
|
|
20357
20368
|
var WU = v(function(is) {
|
|
20358
20369
|
var Oxe = is && is.__createBinding || (Object.create ? function(e, t, r, n) {
|
|
@@ -42589,8 +42600,136 @@ function resolveClaudeCodeExecutable(input = {}, dependencies = {}) {
|
|
|
42589
42600
|
return targetPath(platform).isAbsolute(resolution.executable) ? resolution.executable : path4.resolve(resolution.executable);
|
|
42590
42601
|
}
|
|
42591
42602
|
|
|
42592
|
-
// dist/
|
|
42603
|
+
// dist/pending-session.js
|
|
42604
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
42605
|
+
import { mkdir, open, readFile as readFile2, rename, rm as rm2, stat, unlink } from "node:fs/promises";
|
|
42606
|
+
import os3 from "node:os";
|
|
42593
42607
|
import path5 from "node:path";
|
|
42608
|
+
var reservationSchema = external_exports.strictObject({
|
|
42609
|
+
version: external_exports.literal(1),
|
|
42610
|
+
sessionId: external_exports.uuid(),
|
|
42611
|
+
cwd: external_exports.string().min(1),
|
|
42612
|
+
configuration: harnessConfigurationStateSchema
|
|
42613
|
+
});
|
|
42614
|
+
function isPendingClaudeSession(ref) {
|
|
42615
|
+
return ref.locator !== void 0;
|
|
42616
|
+
}
|
|
42617
|
+
var ClaudePendingSessions = class {
|
|
42618
|
+
#directory;
|
|
42619
|
+
constructor(environment) {
|
|
42620
|
+
this.#directory = path5.join(path5.resolve(environment.CLAUDE_CONFIG_DIR ?? path5.join(os3.homedir(), ".claude")), "codexhost", "pending-sessions");
|
|
42621
|
+
}
|
|
42622
|
+
#path(ref, cwd) {
|
|
42623
|
+
if (ref.harnessId !== "claude-code" || !external_exports.uuid().safeParse(ref.nativeSessionId).success || !external_exports.strictObject({ pendingSession: external_exports.literal(1) }).safeParse(ref.locator).success || !path5.isAbsolute(cwd)) {
|
|
42624
|
+
throw new Error("Claude Code pending Session identity is invalid");
|
|
42625
|
+
}
|
|
42626
|
+
return path5.join(this.#directory, ref.nativeSessionId);
|
|
42627
|
+
}
|
|
42628
|
+
async create(cwd, configuration) {
|
|
42629
|
+
const ref = nativeSessionRefSchema.parse({
|
|
42630
|
+
harnessId: "claude-code",
|
|
42631
|
+
nativeSessionId: randomUUID2(),
|
|
42632
|
+
locator: { pendingSession: 1 },
|
|
42633
|
+
formatVersion: 1
|
|
42634
|
+
});
|
|
42635
|
+
const directory = this.#path(ref, cwd);
|
|
42636
|
+
const reservation = reservationSchema.parse({
|
|
42637
|
+
version: 1,
|
|
42638
|
+
sessionId: ref.nativeSessionId,
|
|
42639
|
+
cwd,
|
|
42640
|
+
configuration
|
|
42641
|
+
});
|
|
42642
|
+
await mkdir(this.#directory, { recursive: true, mode: 448 });
|
|
42643
|
+
await mkdir(directory, { mode: 448 });
|
|
42644
|
+
try {
|
|
42645
|
+
const file2 = await open(path5.join(directory, "session.json"), "wx", 384);
|
|
42646
|
+
try {
|
|
42647
|
+
await file2.writeFile(JSON.stringify(reservation));
|
|
42648
|
+
await file2.sync();
|
|
42649
|
+
} finally {
|
|
42650
|
+
await file2.close();
|
|
42651
|
+
}
|
|
42652
|
+
} catch (error52) {
|
|
42653
|
+
await rm2(directory, { recursive: true, force: true });
|
|
42654
|
+
throw error52;
|
|
42655
|
+
}
|
|
42656
|
+
await this.#sync(directory);
|
|
42657
|
+
await this.#sync(this.#directory);
|
|
42658
|
+
return ref;
|
|
42659
|
+
}
|
|
42660
|
+
async read(ref, cwd) {
|
|
42661
|
+
const directory = this.#path(ref, cwd);
|
|
42662
|
+
const reservation = reservationSchema.parse(JSON.parse(await readFile2(path5.join(directory, "session.json"), "utf8")));
|
|
42663
|
+
if (reservation.sessionId !== ref.nativeSessionId || reservation.cwd !== cwd) {
|
|
42664
|
+
throw new Error("Claude Code pending Session does not belong to this working directory");
|
|
42665
|
+
}
|
|
42666
|
+
let started = false;
|
|
42667
|
+
try {
|
|
42668
|
+
const claim = await stat(path5.join(directory, "started"));
|
|
42669
|
+
if (!claim.isFile())
|
|
42670
|
+
throw new Error("Claude Code pending Session claim is invalid");
|
|
42671
|
+
started = true;
|
|
42672
|
+
} catch (error52) {
|
|
42673
|
+
if (error52.code !== "ENOENT")
|
|
42674
|
+
throw error52;
|
|
42675
|
+
}
|
|
42676
|
+
return { started, configuration: reservation.configuration };
|
|
42677
|
+
}
|
|
42678
|
+
async saveConfiguration(ref, cwd, configuration) {
|
|
42679
|
+
await this.read(ref, cwd);
|
|
42680
|
+
const directory = this.#path(ref, cwd);
|
|
42681
|
+
const temporary = path5.join(directory, `${randomUUID2()}.tmp`);
|
|
42682
|
+
try {
|
|
42683
|
+
const file2 = await open(temporary, "wx", 384);
|
|
42684
|
+
try {
|
|
42685
|
+
await file2.writeFile(JSON.stringify(reservationSchema.parse({
|
|
42686
|
+
version: 1,
|
|
42687
|
+
sessionId: ref.nativeSessionId,
|
|
42688
|
+
cwd,
|
|
42689
|
+
configuration
|
|
42690
|
+
})));
|
|
42691
|
+
await file2.sync();
|
|
42692
|
+
} finally {
|
|
42693
|
+
await file2.close();
|
|
42694
|
+
}
|
|
42695
|
+
await rename(temporary, path5.join(directory, "session.json"));
|
|
42696
|
+
await this.#sync(directory);
|
|
42697
|
+
} finally {
|
|
42698
|
+
await rm2(temporary, { force: true });
|
|
42699
|
+
}
|
|
42700
|
+
}
|
|
42701
|
+
async #sync(directory) {
|
|
42702
|
+
if (process.platform === "win32")
|
|
42703
|
+
return;
|
|
42704
|
+
const handle = await open(directory, "r");
|
|
42705
|
+
try {
|
|
42706
|
+
await handle.sync();
|
|
42707
|
+
} finally {
|
|
42708
|
+
await handle.close();
|
|
42709
|
+
}
|
|
42710
|
+
}
|
|
42711
|
+
async claim(ref, cwd) {
|
|
42712
|
+
await this.read(ref, cwd);
|
|
42713
|
+
const claim = await open(path5.join(this.#path(ref, cwd), "started"), "wx", 384);
|
|
42714
|
+
try {
|
|
42715
|
+
await claim.sync();
|
|
42716
|
+
} finally {
|
|
42717
|
+
await claim.close();
|
|
42718
|
+
}
|
|
42719
|
+
await this.#sync(this.#path(ref, cwd));
|
|
42720
|
+
}
|
|
42721
|
+
/** Only the claim owner may release, after proven close and before submitting any native input. */
|
|
42722
|
+
async release(ref, cwd) {
|
|
42723
|
+
await unlink(path5.join(this.#path(ref, cwd), "started"));
|
|
42724
|
+
await this.#sync(this.#path(ref, cwd));
|
|
42725
|
+
}
|
|
42726
|
+
async discard(ref, cwd) {
|
|
42727
|
+
await rm2(this.#path(ref, cwd), { recursive: true, force: true });
|
|
42728
|
+
}
|
|
42729
|
+
};
|
|
42730
|
+
|
|
42731
|
+
// dist/claude-fork.js
|
|
42732
|
+
import path6 from "node:path";
|
|
42594
42733
|
import { isDeepStrictEqual } from "node:util";
|
|
42595
42734
|
|
|
42596
42735
|
// dist/item-identity.js
|
|
@@ -42680,9 +42819,19 @@ function visibleUserTextParts(message) {
|
|
|
42680
42819
|
return [];
|
|
42681
42820
|
return parts.filter((part) => !isLocalCommandRecord(part) && !isTaskNotificationRecord(part));
|
|
42682
42821
|
}
|
|
42822
|
+
function isInterruptionRecord(value, promptId) {
|
|
42823
|
+
if (value.type !== "user" || promptId === null || value.promptId !== promptId || value.promptSource !== void 0 || !isRecord2(value.message))
|
|
42824
|
+
return false;
|
|
42825
|
+
const content = value.message.content;
|
|
42826
|
+
if (!Array.isArray(content) || content.length !== 1)
|
|
42827
|
+
return false;
|
|
42828
|
+
const part = content[0];
|
|
42829
|
+
return isRecord2(part) && part.type === "text" && (part.text === "[Request interrupted by user]" || part.text === "[Request interrupted by user for tool use]");
|
|
42830
|
+
}
|
|
42683
42831
|
function conversationMessages(values, sessionId) {
|
|
42684
42832
|
const messages = [];
|
|
42685
42833
|
const ids = /* @__PURE__ */ new Set();
|
|
42834
|
+
let promptId = null;
|
|
42686
42835
|
for (const value of values) {
|
|
42687
42836
|
if (!isRecord2(value))
|
|
42688
42837
|
throw new Error("Claude history contains a malformed message");
|
|
@@ -42694,13 +42843,19 @@ function conversationMessages(values, sessionId) {
|
|
|
42694
42843
|
if (ids.has(value.uuid))
|
|
42695
42844
|
throw new Error("Claude history contains duplicate message IDs");
|
|
42696
42845
|
ids.add(value.uuid);
|
|
42697
|
-
|
|
42846
|
+
const interrupted = isInterruptionRecord(value, promptId);
|
|
42847
|
+
const message = {
|
|
42698
42848
|
type: value.type,
|
|
42699
42849
|
uuid: value.uuid,
|
|
42700
42850
|
message: value.message,
|
|
42701
42851
|
timestampMs: isoToMs(value.timestamp),
|
|
42702
|
-
|
|
42703
|
-
|
|
42852
|
+
interrupted,
|
|
42853
|
+
syntheticUser: value.type === "user" && (interrupted || value.isSynthetic === true || value.isMeta === true || isTaskNotificationOrigin(value) || value.toolUseResult !== void 0 && value.toolUseResult !== null)
|
|
42854
|
+
};
|
|
42855
|
+
messages.push(message);
|
|
42856
|
+
if (isHumanUser(message)) {
|
|
42857
|
+
promptId = typeof value.promptId === "string" && value.promptId.length > 0 ? value.promptId : null;
|
|
42858
|
+
}
|
|
42704
42859
|
}
|
|
42705
42860
|
return messages;
|
|
42706
42861
|
}
|
|
@@ -42708,6 +42863,8 @@ function isHumanUser(message) {
|
|
|
42708
42863
|
return visibleUserTextParts(message).length > 0;
|
|
42709
42864
|
}
|
|
42710
42865
|
function turnOutcome(messages) {
|
|
42866
|
+
if (messages.some(({ interrupted }) => interrupted))
|
|
42867
|
+
return { status: "cancelled", reason: "Cancelled by user" };
|
|
42711
42868
|
const assistants = messages.filter(({ type }) => type === "assistant");
|
|
42712
42869
|
const failed = assistants.some(({ message }) => typeof message.error === "string");
|
|
42713
42870
|
if (failed) {
|
|
@@ -42755,7 +42912,7 @@ function mapClaudeSnapshot(values, sessionId) {
|
|
|
42755
42912
|
const turnMessages = messages.slice(index, end);
|
|
42756
42913
|
const outcome = turnOutcome(turnMessages);
|
|
42757
42914
|
const results = toolResultBlocks(turnMessages);
|
|
42758
|
-
const checkpointMessage = turnMessages.findLast(({ type }) => type === "assistant");
|
|
42915
|
+
const checkpointMessage = turnMessages.findLast(({ type, interrupted }) => type === "assistant" || interrupted);
|
|
42759
42916
|
const startedAtMs = turnMessages[0]?.timestampMs;
|
|
42760
42917
|
const completedAtMs = turnMessages.at(-1)?.timestampMs;
|
|
42761
42918
|
let agentMessageOrdinal = 0;
|
|
@@ -43099,6 +43256,7 @@ function comparableTurn(turn) {
|
|
|
43099
43256
|
outcome
|
|
43100
43257
|
})),
|
|
43101
43258
|
outcome: turn.outcome,
|
|
43259
|
+
hasCheckpoint: turn.checkpoint !== void 0,
|
|
43102
43260
|
...turn.model ? { model: turn.model } : {}
|
|
43103
43261
|
};
|
|
43104
43262
|
}
|
|
@@ -43135,8 +43293,8 @@ async function readSnapshot(dependencies, cwd, sessionId) {
|
|
|
43135
43293
|
}
|
|
43136
43294
|
async function forkClaudeSession(input) {
|
|
43137
43295
|
const sourceRef = nativeSessionRefSchema.safeParse(input.sourceRef);
|
|
43138
|
-
const checkpoint = nativeCheckpointRefSchema.safeParse(input.checkpoint);
|
|
43139
|
-
if (!sourceRef.success ||
|
|
43296
|
+
const checkpoint = input.kind === "fork" ? nativeCheckpointRefSchema.safeParse(input.checkpoint) : null;
|
|
43297
|
+
if (!sourceRef.success || sourceRef.data.harnessId !== input.harnessId || checkpoint && (!checkpoint.success || checkpoint.data.harnessId !== input.harnessId || checkpoint.data.nativeSessionId !== sourceRef.data.nativeSessionId)) {
|
|
43140
43298
|
return {
|
|
43141
43299
|
ok: false,
|
|
43142
43300
|
error: error51("invalidRequest", "Claude Code Fork identity does not belong to the source Session", false)
|
|
@@ -43165,7 +43323,7 @@ async function forkClaudeSession(input) {
|
|
|
43165
43323
|
error: error51("protocolError", "Claude Code Session working directory is unavailable", false)
|
|
43166
43324
|
};
|
|
43167
43325
|
}
|
|
43168
|
-
if (
|
|
43326
|
+
if (path6.resolve(sourceInfo.cwd) !== input.cwd) {
|
|
43169
43327
|
return {
|
|
43170
43328
|
ok: false,
|
|
43171
43329
|
error: error51("unsupported", "Claude Code cannot Fork across working directories", false)
|
|
@@ -43174,8 +43332,39 @@ async function forkClaudeSession(input) {
|
|
|
43174
43332
|
const source = await readSnapshot(input.dependencies, input.cwd, sourceRef.data.nativeSessionId);
|
|
43175
43333
|
if (!source.ok)
|
|
43176
43334
|
return source;
|
|
43177
|
-
|
|
43178
|
-
|
|
43335
|
+
if (input.kind === "rollbackLastTurn" && source.value.turns.length === 0) {
|
|
43336
|
+
return {
|
|
43337
|
+
ok: false,
|
|
43338
|
+
error: error51("invalidRequest", "Claude Code Session has no Turn to roll back", false)
|
|
43339
|
+
};
|
|
43340
|
+
}
|
|
43341
|
+
if (input.kind === "rollbackLastTurn" && source.value.turns.length === 1) {
|
|
43342
|
+
let nativeRef;
|
|
43343
|
+
try {
|
|
43344
|
+
nativeRef = await input.pendingSessions.create(input.cwd, input.configuration);
|
|
43345
|
+
} catch {
|
|
43346
|
+
return {
|
|
43347
|
+
ok: false,
|
|
43348
|
+
error: error51("nativeFailure", "Claude Code empty rollback could not be persisted", true)
|
|
43349
|
+
};
|
|
43350
|
+
}
|
|
43351
|
+
const sourceAfter2 = await readSnapshot(input.dependencies, input.cwd, sourceRef.data.nativeSessionId);
|
|
43352
|
+
if (!sourceAfter2.ok || !isDeepStrictEqual(sourceAfter2.value, source.value)) {
|
|
43353
|
+
await input.pendingSessions.discard(nativeRef, input.cwd).catch(() => void 0);
|
|
43354
|
+
return {
|
|
43355
|
+
ok: false,
|
|
43356
|
+
error: error51("protocolError", "Claude Code source history changed during rollback", false)
|
|
43357
|
+
};
|
|
43358
|
+
}
|
|
43359
|
+
return {
|
|
43360
|
+
ok: true,
|
|
43361
|
+
value: { sessionId: nativeRef.nativeSessionId, nativeRef, openMode: "create" }
|
|
43362
|
+
};
|
|
43363
|
+
}
|
|
43364
|
+
const boundaryIndex = input.kind === "rollbackLastTurn" ? source.value.turns.length - 2 : source.value.turns.findIndex((turn) => checkpoint?.success && turn.checkpoint?.checkpointId === checkpoint.data.checkpointId);
|
|
43365
|
+
const retained = source.value.turns[boundaryIndex];
|
|
43366
|
+
const boundaryId = retained?.checkpoint?.checkpointId ?? (input.kind === "rollbackLastTurn" ? retained?.nativeTurnRef.nativeTurnKey : void 0);
|
|
43367
|
+
if (boundaryIndex < 0 || !boundaryId) {
|
|
43179
43368
|
return {
|
|
43180
43369
|
ok: false,
|
|
43181
43370
|
error: error51("checkpointNotFound", "Claude Code Fork Checkpoint is unavailable", false)
|
|
@@ -43184,7 +43373,7 @@ async function forkClaudeSession(input) {
|
|
|
43184
43373
|
let derivedSessionId;
|
|
43185
43374
|
try {
|
|
43186
43375
|
const forked = await input.dependencies.forkSession({
|
|
43187
|
-
checkpointId:
|
|
43376
|
+
checkpointId: boundaryId,
|
|
43188
43377
|
cwd: input.cwd,
|
|
43189
43378
|
sourceSessionId: sourceRef.data.nativeSessionId
|
|
43190
43379
|
});
|
|
@@ -43223,7 +43412,7 @@ async function forkClaudeSession(input) {
|
|
|
43223
43412
|
const derivedContent = derived.value.turns.map(comparableTurn);
|
|
43224
43413
|
const sourceIds = nativeIds(source.value);
|
|
43225
43414
|
const derivedIds = nativeIds(derived.value);
|
|
43226
|
-
if (!isDeepStrictEqual(sourceAfter.value.turns.slice(0,
|
|
43415
|
+
if (input.kind === "rollbackLastTurn" && sourceAfter.value.turns.length !== source.value.turns.length || sourceAfter.value.turns.length < source.value.turns.length || !isDeepStrictEqual(sourceAfter.value.turns.slice(0, source.value.turns.length), source.value.turns) || !isDeepStrictEqual(derivedContent, expectedPrefix) || derivedIds.size === 0 || [...derivedIds].some((id) => sourceIds.has(id))) {
|
|
43227
43416
|
await cleanup();
|
|
43228
43417
|
return {
|
|
43229
43418
|
ok: false,
|
|
@@ -43234,8 +43423,8 @@ async function forkClaudeSession(input) {
|
|
|
43234
43423
|
}
|
|
43235
43424
|
|
|
43236
43425
|
// dist/claude-session-import.js
|
|
43237
|
-
import { realpath, stat } from "node:fs/promises";
|
|
43238
|
-
import
|
|
43426
|
+
import { realpath, stat as stat2 } from "node:fs/promises";
|
|
43427
|
+
import path7 from "node:path";
|
|
43239
43428
|
function titleFromMetadata(metadata) {
|
|
43240
43429
|
for (const value of [metadata.customTitle, metadata.summary, metadata.firstPrompt]) {
|
|
43241
43430
|
if (typeof value !== "string")
|
|
@@ -43257,14 +43446,14 @@ async function sourceFromMetadata(metadata, isRunning, signal, canonicalCwds, pr
|
|
|
43257
43446
|
];
|
|
43258
43447
|
let cwd = null;
|
|
43259
43448
|
for (const candidate2 of new Set(candidates)) {
|
|
43260
|
-
if (!
|
|
43449
|
+
if (!path7.isAbsolute(candidate2))
|
|
43261
43450
|
continue;
|
|
43262
43451
|
let canonical = canonicalCwds.get(candidate2);
|
|
43263
43452
|
if (!canonical) {
|
|
43264
43453
|
canonical = (async () => {
|
|
43265
43454
|
try {
|
|
43266
43455
|
const resolved = await realpath(candidate2);
|
|
43267
|
-
return (await
|
|
43456
|
+
return (await stat2(resolved)).isDirectory() ? resolved : null;
|
|
43268
43457
|
} catch {
|
|
43269
43458
|
return null;
|
|
43270
43459
|
}
|
|
@@ -43334,7 +43523,7 @@ var ClaudeSessionImportIndex = class {
|
|
|
43334
43523
|
if (!metadata || metadata.sessionId !== nativeSessionId)
|
|
43335
43524
|
return null;
|
|
43336
43525
|
const preferredCwds = [];
|
|
43337
|
-
if (typeof metadata.cwd === "string" &&
|
|
43526
|
+
if (typeof metadata.cwd === "string" && path7.isAbsolute(metadata.cwd)) {
|
|
43338
43527
|
try {
|
|
43339
43528
|
const messages = await this.#dependencies.readSessionMessages({
|
|
43340
43529
|
cwd: metadata.cwd,
|
|
@@ -43347,7 +43536,7 @@ var ClaudeSessionImportIndex = class {
|
|
|
43347
43536
|
continue;
|
|
43348
43537
|
}
|
|
43349
43538
|
const cwd = message.cwd;
|
|
43350
|
-
if (
|
|
43539
|
+
if (path7.isAbsolute(cwd) && !preferredCwds.includes(cwd))
|
|
43351
43540
|
preferredCwds.push(cwd);
|
|
43352
43541
|
}
|
|
43353
43542
|
} catch {
|
|
@@ -43358,25 +43547,25 @@ var ClaudeSessionImportIndex = class {
|
|
|
43358
43547
|
};
|
|
43359
43548
|
|
|
43360
43549
|
// dist/claude-transcript.js
|
|
43361
|
-
import
|
|
43362
|
-
import
|
|
43363
|
-
import { readFile as
|
|
43550
|
+
import os4 from "node:os";
|
|
43551
|
+
import path8 from "node:path";
|
|
43552
|
+
import { readFile as readFile3, readdir, stat as stat3 } from "node:fs/promises";
|
|
43364
43553
|
function projectDirectoryName(cwd) {
|
|
43365
43554
|
return cwd.replace(/[^A-Za-z0-9]/gu, "-");
|
|
43366
43555
|
}
|
|
43367
43556
|
function configDirectory(environment) {
|
|
43368
|
-
return environment.CLAUDE_CONFIG_DIR ?
|
|
43557
|
+
return environment.CLAUDE_CONFIG_DIR ? path8.resolve(environment.CLAUDE_CONFIG_DIR) : path8.join(os4.homedir(), ".claude");
|
|
43369
43558
|
}
|
|
43370
43559
|
async function existingFile(file2) {
|
|
43371
43560
|
try {
|
|
43372
|
-
return (await
|
|
43561
|
+
return (await stat3(file2)).isFile();
|
|
43373
43562
|
} catch {
|
|
43374
43563
|
return false;
|
|
43375
43564
|
}
|
|
43376
43565
|
}
|
|
43377
43566
|
async function findTranscriptFile(environment, cwd, relativeName) {
|
|
43378
|
-
const projectsDirectory =
|
|
43379
|
-
const expected =
|
|
43567
|
+
const projectsDirectory = path8.join(configDirectory(environment), "projects");
|
|
43568
|
+
const expected = path8.join(projectsDirectory, projectDirectoryName(cwd), relativeName);
|
|
43380
43569
|
if (await existingFile(expected))
|
|
43381
43570
|
return expected;
|
|
43382
43571
|
let projects;
|
|
@@ -43386,7 +43575,7 @@ async function findTranscriptFile(environment, cwd, relativeName) {
|
|
|
43386
43575
|
return null;
|
|
43387
43576
|
}
|
|
43388
43577
|
for (const project of projects) {
|
|
43389
|
-
const candidate =
|
|
43578
|
+
const candidate = path8.join(projectsDirectory, project, relativeName);
|
|
43390
43579
|
if (await existingFile(candidate))
|
|
43391
43580
|
return candidate;
|
|
43392
43581
|
}
|
|
@@ -43417,14 +43606,14 @@ async function readClaudeTranscript(input) {
|
|
|
43417
43606
|
const transcript = await findTranscriptFile(input.environment, input.cwd, `${input.sessionId}.jsonl`);
|
|
43418
43607
|
if (!transcript)
|
|
43419
43608
|
return null;
|
|
43420
|
-
return parseTranscriptRecords(await
|
|
43609
|
+
return parseTranscriptRecords(await readFile3(transcript, "utf8"), input.sessionId);
|
|
43421
43610
|
}
|
|
43422
43611
|
async function readClaudeSubagentTranscript(input) {
|
|
43423
|
-
const relativeName =
|
|
43612
|
+
const relativeName = path8.join(input.sessionId, "subagents", `agent-${input.nativeSubagentId}.jsonl`);
|
|
43424
43613
|
const transcript = await findTranscriptFile(input.environment, input.cwd, relativeName);
|
|
43425
43614
|
if (!transcript)
|
|
43426
43615
|
return null;
|
|
43427
|
-
return parseTranscriptRecords(await
|
|
43616
|
+
return parseTranscriptRecords(await readFile3(transcript, "utf8"), input.sessionId);
|
|
43428
43617
|
}
|
|
43429
43618
|
|
|
43430
43619
|
// dist/model-catalog.js
|
|
@@ -43686,8 +43875,8 @@ function projectClaudeAccountUsage(usage, account) {
|
|
|
43686
43875
|
}
|
|
43687
43876
|
|
|
43688
43877
|
// dist/gateway-models.js
|
|
43689
|
-
import { readFile as
|
|
43690
|
-
import
|
|
43878
|
+
import { readFile as readFile4 } from "node:fs/promises";
|
|
43879
|
+
import path9 from "node:path";
|
|
43691
43880
|
var GATEWAY_MODELS_TIMEOUT_MS = 3e3;
|
|
43692
43881
|
var GATEWAY_MODELS_MAX_BYTES = 2 * 1024 * 1024;
|
|
43693
43882
|
var OFFICIAL_ANTHROPIC_HOST = "api.anthropic.com";
|
|
@@ -43729,14 +43918,14 @@ function claudeConfigDirectory(environment) {
|
|
|
43729
43918
|
if (configured)
|
|
43730
43919
|
return configured;
|
|
43731
43920
|
const home = trimmedEnv(environment, "HOME") ?? trimmedEnv(environment, "USERPROFILE");
|
|
43732
|
-
return home ?
|
|
43921
|
+
return home ? path9.join(home, ".claude") : void 0;
|
|
43733
43922
|
}
|
|
43734
43923
|
async function readClaudeUserSettingsEnv(environment) {
|
|
43735
43924
|
const configDir = claudeConfigDirectory(environment);
|
|
43736
43925
|
if (!configDir)
|
|
43737
43926
|
return {};
|
|
43738
43927
|
try {
|
|
43739
|
-
const raw = await
|
|
43928
|
+
const raw = await readFile4(path9.join(configDir, "settings.json"), "utf8");
|
|
43740
43929
|
const parsed = JSON.parse(raw);
|
|
43741
43930
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed))
|
|
43742
43931
|
return {};
|
|
@@ -43868,7 +44057,7 @@ async function applyGatewayModelCatalog(snapshot, environment, dependencies = {}
|
|
|
43868
44057
|
}
|
|
43869
44058
|
|
|
43870
44059
|
// dist/file-change.js
|
|
43871
|
-
import
|
|
44060
|
+
import path10 from "node:path";
|
|
43872
44061
|
var hunkSchema = external_exports.object({
|
|
43873
44062
|
oldStart: external_exports.number().int().nonnegative(),
|
|
43874
44063
|
oldLines: external_exports.number().int().nonnegative(),
|
|
@@ -43916,10 +44105,10 @@ function parseClaudeNativeFileChange(toolName, value) {
|
|
|
43916
44105
|
};
|
|
43917
44106
|
}
|
|
43918
44107
|
function displayPath(nativePath, cwd) {
|
|
43919
|
-
const resolvedCwd =
|
|
43920
|
-
const resolvedPath =
|
|
43921
|
-
const relative =
|
|
43922
|
-
const selected = relative.length > 0 && relative !== ".." && !relative.startsWith(`..${
|
|
44108
|
+
const resolvedCwd = path10.resolve(cwd);
|
|
44109
|
+
const resolvedPath = path10.isAbsolute(nativePath) ? path10.resolve(nativePath) : path10.resolve(cwd, nativePath);
|
|
44110
|
+
const relative = path10.relative(resolvedCwd, resolvedPath);
|
|
44111
|
+
const selected = relative.length > 0 && relative !== ".." && !relative.startsWith(`..${path10.sep}`) ? relative : resolvedPath;
|
|
43923
44112
|
const normalized = selected.replaceAll("\\", "/");
|
|
43924
44113
|
return validNativePath(normalized) && normalized !== "." ? normalized : null;
|
|
43925
44114
|
}
|
|
@@ -43931,7 +44120,7 @@ function projectClaudeFileChange(value, cwd) {
|
|
|
43931
44120
|
`@@ -${hunk.oldStart},${hunk.oldLines} +${hunk.newStart},${hunk.newLines} @@`,
|
|
43932
44121
|
...hunk.lines
|
|
43933
44122
|
]);
|
|
43934
|
-
const absoluteDisplayPath =
|
|
44123
|
+
const absoluteDisplayPath = path10.posix.isAbsolute(normalizedPath);
|
|
43935
44124
|
const oldHeader = value.kind === "add" ? "/dev/null" : absoluteDisplayPath ? normalizedPath : `a/${normalizedPath}`;
|
|
43936
44125
|
const newHeader = absoluteDisplayPath ? normalizedPath : `b/${normalizedPath}`;
|
|
43937
44126
|
const unifiedDiff = [`--- ${oldHeader}`, `+++ ${newHeader}`, ...body, ""].join("\n");
|
|
@@ -44625,6 +44814,59 @@ var ClaudeNativeTurnAccumulator = class {
|
|
|
44625
44814
|
}
|
|
44626
44815
|
};
|
|
44627
44816
|
|
|
44817
|
+
// dist/process-fence.js
|
|
44818
|
+
import { execFile } from "node:child_process";
|
|
44819
|
+
import path11 from "node:path";
|
|
44820
|
+
import { setTimeout as setTimeout2 } from "node:timers/promises";
|
|
44821
|
+
import { promisify } from "node:util";
|
|
44822
|
+
var executeFile = promisify(execFile);
|
|
44823
|
+
function signalGroup(pid, signal) {
|
|
44824
|
+
try {
|
|
44825
|
+
process.kill(-pid, signal);
|
|
44826
|
+
return true;
|
|
44827
|
+
} catch (error52) {
|
|
44828
|
+
if (error52.code === "ESRCH")
|
|
44829
|
+
return false;
|
|
44830
|
+
if (signal === 0 && error52.code === "EPERM")
|
|
44831
|
+
return true;
|
|
44832
|
+
throw error52;
|
|
44833
|
+
}
|
|
44834
|
+
}
|
|
44835
|
+
async function closeClaudeProcessGroup(child, timeoutMs) {
|
|
44836
|
+
const pid = child.pid;
|
|
44837
|
+
if (!pid)
|
|
44838
|
+
return;
|
|
44839
|
+
if (process.platform === "win32") {
|
|
44840
|
+
if (child.exitCode !== null || child.signalCode !== null)
|
|
44841
|
+
throw new Error("Claude process tree cannot be confirmed after its Windows root exited");
|
|
44842
|
+
const root = process.env.SystemRoot ?? process.env.SYSTEMROOT;
|
|
44843
|
+
if (!root || !path11.win32.isAbsolute(root))
|
|
44844
|
+
throw new Error("Windows SystemRoot is unavailable");
|
|
44845
|
+
await executeFile(path11.win32.join(root, "System32", "taskkill.exe"), ["/PID", String(pid), "/T", "/F"], {
|
|
44846
|
+
timeout: timeoutMs,
|
|
44847
|
+
windowsHide: true
|
|
44848
|
+
});
|
|
44849
|
+
return;
|
|
44850
|
+
}
|
|
44851
|
+
if (!signalGroup(pid, "SIGTERM"))
|
|
44852
|
+
return;
|
|
44853
|
+
const gracefulDeadline = Date.now() + timeoutMs;
|
|
44854
|
+
while (Date.now() < gracefulDeadline) {
|
|
44855
|
+
if (!signalGroup(pid, 0))
|
|
44856
|
+
return;
|
|
44857
|
+
await setTimeout2(10);
|
|
44858
|
+
}
|
|
44859
|
+
if (!signalGroup(pid, "SIGKILL"))
|
|
44860
|
+
return;
|
|
44861
|
+
const deadline = Date.now() + timeoutMs;
|
|
44862
|
+
while (Date.now() < deadline) {
|
|
44863
|
+
if (!signalGroup(pid, 0))
|
|
44864
|
+
return;
|
|
44865
|
+
await setTimeout2(10);
|
|
44866
|
+
}
|
|
44867
|
+
throw new Error("Claude SDK process group did not exit");
|
|
44868
|
+
}
|
|
44869
|
+
|
|
44628
44870
|
// dist/sdk-transport.js
|
|
44629
44871
|
var CLIENT_APP = "codexhost-claude-code-adapter/0.0.0";
|
|
44630
44872
|
var APPROVAL_TITLE_MAX_LENGTH = 120;
|
|
@@ -44875,6 +45117,7 @@ var ClaudeSdkTransport = class {
|
|
|
44875
45117
|
#provider;
|
|
44876
45118
|
#query = null;
|
|
44877
45119
|
#started = false;
|
|
45120
|
+
#backgroundTasks = /* @__PURE__ */ new Set();
|
|
44878
45121
|
constructor(options) {
|
|
44879
45122
|
this.sessionId = options.sessionId;
|
|
44880
45123
|
this.#cwd = options.cwd;
|
|
@@ -44994,7 +45237,7 @@ var ClaudeSdkTransport = class {
|
|
|
44994
45237
|
return this.runTurn("/recap", userMessageId, onEvent);
|
|
44995
45238
|
}
|
|
44996
45239
|
runTurn(input, userMessageId, onEvent) {
|
|
44997
|
-
if (!this.#started || !this.#query) {
|
|
45240
|
+
if (this.#closePromise || !this.#started || !this.#query) {
|
|
44998
45241
|
return Promise.reject(new Error("Claude SDK transport is not started"));
|
|
44999
45242
|
}
|
|
45000
45243
|
if (this.#active)
|
|
@@ -45149,25 +45392,56 @@ var ClaudeSdkTransport = class {
|
|
|
45149
45392
|
}
|
|
45150
45393
|
}
|
|
45151
45394
|
async #close() {
|
|
45395
|
+
const failures = [];
|
|
45152
45396
|
if (this.#active)
|
|
45153
45397
|
this.#closeInteractions(this.#active, "cancelled");
|
|
45398
|
+
try {
|
|
45399
|
+
const timeout = rejectAfter(this.#closeTimeoutMs, "Claude background tasks did not stop");
|
|
45400
|
+
try {
|
|
45401
|
+
await Promise.race([this.#stopBackgroundTasks(), timeout.promise]);
|
|
45402
|
+
} finally {
|
|
45403
|
+
timeout.cancel();
|
|
45404
|
+
}
|
|
45405
|
+
} catch (error52) {
|
|
45406
|
+
failures.push(error52);
|
|
45407
|
+
}
|
|
45408
|
+
const stopOwnedProcesses = async () => {
|
|
45409
|
+
const stopped = await Promise.allSettled(this.#children.map((child) => closeClaudeProcessGroup(child, this.#closeTimeoutMs)));
|
|
45410
|
+
for (const result of stopped)
|
|
45411
|
+
if (result.status === "rejected")
|
|
45412
|
+
failures.push(result.reason);
|
|
45413
|
+
};
|
|
45414
|
+
if (process.platform === "win32")
|
|
45415
|
+
await stopOwnedProcesses();
|
|
45154
45416
|
this.#input.end();
|
|
45155
|
-
|
|
45156
|
-
|
|
45157
|
-
|
|
45158
|
-
|
|
45159
|
-
]);
|
|
45160
|
-
for (const child of this.#children) {
|
|
45161
|
-
if (!processExited(child))
|
|
45162
|
-
child.kill("SIGTERM");
|
|
45417
|
+
try {
|
|
45418
|
+
this.#query?.close();
|
|
45419
|
+
} catch (error52) {
|
|
45420
|
+
failures.push(error52);
|
|
45163
45421
|
}
|
|
45164
|
-
|
|
45165
|
-
|
|
45166
|
-
|
|
45167
|
-
|
|
45168
|
-
|
|
45169
|
-
|
|
45170
|
-
|
|
45422
|
+
if (process.platform !== "win32")
|
|
45423
|
+
await stopOwnedProcesses();
|
|
45424
|
+
const exitTimeout = rejectAfter(this.#closeTimeoutMs, "Claude SDK process did not exit");
|
|
45425
|
+
try {
|
|
45426
|
+
await Promise.race([
|
|
45427
|
+
Promise.all(this.#children.map((child) => this.#waitForExit(child))),
|
|
45428
|
+
exitTimeout.promise
|
|
45429
|
+
]);
|
|
45430
|
+
} catch (error52) {
|
|
45431
|
+
failures.push(error52);
|
|
45432
|
+
} finally {
|
|
45433
|
+
exitTimeout.cancel();
|
|
45434
|
+
}
|
|
45435
|
+
const drainTimeout = rejectAfter(this.#closeTimeoutMs, "Claude SDK output did not drain");
|
|
45436
|
+
try {
|
|
45437
|
+
await Promise.race([
|
|
45438
|
+
this.#consumeTask?.catch(() => void 0) ?? Promise.resolve(),
|
|
45439
|
+
drainTimeout.promise
|
|
45440
|
+
]);
|
|
45441
|
+
} catch (error52) {
|
|
45442
|
+
failures.push(error52);
|
|
45443
|
+
} finally {
|
|
45444
|
+
drainTimeout.cancel();
|
|
45171
45445
|
}
|
|
45172
45446
|
this.#query = null;
|
|
45173
45447
|
const active = this.#active;
|
|
@@ -45176,10 +45450,40 @@ var ClaudeSdkTransport = class {
|
|
|
45176
45450
|
this.#idleAccumulator = null;
|
|
45177
45451
|
this.#idleLive = false;
|
|
45178
45452
|
active?.reject(new Error("Claude SDK transport closed"));
|
|
45453
|
+
if (failures.length > 0)
|
|
45454
|
+
throw new AggregateError(failures, "Claude SDK shutdown could not be confirmed");
|
|
45455
|
+
}
|
|
45456
|
+
async #stopBackgroundTasks() {
|
|
45457
|
+
const requested = /* @__PURE__ */ new Set();
|
|
45458
|
+
const deadline = Date.now() + this.#closeTimeoutMs;
|
|
45459
|
+
while (this.#backgroundTasks.size > 0) {
|
|
45460
|
+
if (Date.now() >= deadline || !this.#query)
|
|
45461
|
+
throw new Error("Claude background tasks remain active");
|
|
45462
|
+
for (const id of this.#backgroundTasks) {
|
|
45463
|
+
if (requested.has(id))
|
|
45464
|
+
continue;
|
|
45465
|
+
requested.add(id);
|
|
45466
|
+
await this.#query.stopTask(id);
|
|
45467
|
+
}
|
|
45468
|
+
if (this.#backgroundTasks.size > 0)
|
|
45469
|
+
await delay(10);
|
|
45470
|
+
}
|
|
45471
|
+
}
|
|
45472
|
+
#observeBackgroundTasks(message) {
|
|
45473
|
+
if (!isRecord6(message) || message.type !== "system")
|
|
45474
|
+
return;
|
|
45475
|
+
if (message.subtype === "background_tasks_changed" && Array.isArray(message.tasks)) {
|
|
45476
|
+
this.#backgroundTasks = new Set(message.tasks.flatMap((task) => isRecord6(task) && typeof task.task_id === "string" ? [task.task_id] : []));
|
|
45477
|
+
} else if (message.subtype === "task_started" && typeof message.task_id === "string") {
|
|
45478
|
+
this.#backgroundTasks.add(message.task_id);
|
|
45479
|
+
} else if (message.subtype === "task_notification" && typeof message.task_id === "string" && ["completed", "failed", "stopped"].includes(String(message.status))) {
|
|
45480
|
+
this.#backgroundTasks.delete(message.task_id);
|
|
45481
|
+
}
|
|
45179
45482
|
}
|
|
45180
45483
|
async #consume(activeQuery) {
|
|
45181
45484
|
try {
|
|
45182
45485
|
for await (const message of activeQuery) {
|
|
45486
|
+
this.#observeBackgroundTasks(message);
|
|
45183
45487
|
const permissionMode = permissionModeFromMessage(message);
|
|
45184
45488
|
if (permissionMode && permissionMode !== this.#permissionMode) {
|
|
45185
45489
|
this.#permissionMode = permissionMode;
|
|
@@ -45256,7 +45560,8 @@ var ClaudeSdkTransport = class {
|
|
|
45256
45560
|
env: options.env,
|
|
45257
45561
|
signal: options.signal,
|
|
45258
45562
|
stdio: ["pipe", "pipe", "pipe"],
|
|
45259
|
-
windowsHide: true
|
|
45563
|
+
windowsHide: true,
|
|
45564
|
+
detached: process.platform !== "win32"
|
|
45260
45565
|
});
|
|
45261
45566
|
child.stderr.on("data", (chunk) => {
|
|
45262
45567
|
this.#stderrTail = sanitizeDiagnosticTail(`${this.#stderrTail}${chunk.toString()}`);
|
|
@@ -46071,6 +46376,10 @@ var ClaudeHarnessSession = class {
|
|
|
46071
46376
|
#onClosed;
|
|
46072
46377
|
#onPlanLimitObserved;
|
|
46073
46378
|
#openMode;
|
|
46379
|
+
#pendingSessions;
|
|
46380
|
+
#pendingClaimed = false;
|
|
46381
|
+
#submittedInput = false;
|
|
46382
|
+
#startupTask = null;
|
|
46074
46383
|
#randomUUID;
|
|
46075
46384
|
#requestedModel;
|
|
46076
46385
|
#requestedPermissionModeId;
|
|
@@ -46088,7 +46397,9 @@ var ClaudeHarnessSession = class {
|
|
|
46088
46397
|
#readingHistory = false;
|
|
46089
46398
|
#state;
|
|
46090
46399
|
#statePublished = false;
|
|
46400
|
+
#unpersistedMessageIds = [];
|
|
46091
46401
|
#transport = null;
|
|
46402
|
+
#hardCancelTask = null;
|
|
46092
46403
|
#usageGeneration = 0;
|
|
46093
46404
|
#latestUsage = null;
|
|
46094
46405
|
#minimumContextUsedTokens = null;
|
|
@@ -46115,6 +46426,7 @@ var ClaudeHarnessSession = class {
|
|
|
46115
46426
|
#continuationQuiescence = null;
|
|
46116
46427
|
constructor(cwd, dependencies, closeTimeoutMs, onClosed, onPlanLimitObserved, options) {
|
|
46117
46428
|
this.#cwd = cwd;
|
|
46429
|
+
this.#pendingSessions = options.pendingSessions;
|
|
46118
46430
|
const environment = options.environment;
|
|
46119
46431
|
this.#createTransport = environment ? (input) => dependencies.createTransport({ ...input, environment }) : dependencies.createTransport;
|
|
46120
46432
|
this.#randomUUID = dependencies.randomUUID;
|
|
@@ -46130,7 +46442,7 @@ var ClaudeHarnessSession = class {
|
|
|
46130
46442
|
this.#sessionId = options.sessionId;
|
|
46131
46443
|
this.#toolOutputLimit = options.toolOutputLimit;
|
|
46132
46444
|
this.#continuationQuiescenceMs = options.continuationQuiescenceMs;
|
|
46133
|
-
this.#nativeRef = nativeSessionRefSchema.parse({
|
|
46445
|
+
this.#nativeRef = options.nativeRef ?? nativeSessionRefSchema.parse({
|
|
46134
46446
|
harnessId: this.harnessId,
|
|
46135
46447
|
nativeSessionId: this.#sessionId,
|
|
46136
46448
|
formatVersion: 1
|
|
@@ -46139,9 +46451,17 @@ var ClaudeHarnessSession = class {
|
|
|
46139
46451
|
list: async () => ({ ok: true, value: claudeCommandCatalog }),
|
|
46140
46452
|
execute: (command) => this.#executeHarnessCommand(command)
|
|
46141
46453
|
};
|
|
46142
|
-
|
|
46454
|
+
const durable = this.#openMode === "resume" || options.nativeRef !== void 0;
|
|
46455
|
+
this.initialState = durable ? {
|
|
46456
|
+
nativeRef: this.#nativeRef,
|
|
46457
|
+
...options.knownConfiguration ? {
|
|
46458
|
+
...options.requestedModel ? { effectiveModel: options.requestedModel } : {},
|
|
46459
|
+
effectiveThinkingOptionId: this.#requestedThinkingOptionId,
|
|
46460
|
+
effectivePermissionModeId: this.#requestedPermissionModeId
|
|
46461
|
+
} : {}
|
|
46462
|
+
} : {};
|
|
46143
46463
|
this.#state = this.initialState;
|
|
46144
|
-
this.#statePublished =
|
|
46464
|
+
this.#statePublished = durable;
|
|
46145
46465
|
this.outputs = this.#channel.outputs;
|
|
46146
46466
|
}
|
|
46147
46467
|
async readSnapshot() {
|
|
@@ -46164,7 +46484,29 @@ var ClaudeHarnessSession = class {
|
|
|
46164
46484
|
try {
|
|
46165
46485
|
let messages;
|
|
46166
46486
|
try {
|
|
46167
|
-
|
|
46487
|
+
const deadline = Date.now() + this.#closeTimeoutMs;
|
|
46488
|
+
for (; ; ) {
|
|
46489
|
+
messages = await this.#readSessionMessages({
|
|
46490
|
+
cwd: this.#cwd,
|
|
46491
|
+
sessionId: this.#sessionId
|
|
46492
|
+
});
|
|
46493
|
+
const ids = new Set(messages.flatMap((message) => isRecord9(message) && typeof message.uuid === "string" ? [message.uuid] : []));
|
|
46494
|
+
if (this.#unpersistedMessageIds.every((id) => ids.has(id))) {
|
|
46495
|
+
this.#unpersistedMessageIds = [];
|
|
46496
|
+
break;
|
|
46497
|
+
}
|
|
46498
|
+
if (Date.now() >= deadline || this.#phase !== "open") {
|
|
46499
|
+
return {
|
|
46500
|
+
ok: false,
|
|
46501
|
+
error: {
|
|
46502
|
+
code: "sessionBusy",
|
|
46503
|
+
message: "Claude Code history is still being persisted",
|
|
46504
|
+
retryable: true
|
|
46505
|
+
}
|
|
46506
|
+
};
|
|
46507
|
+
}
|
|
46508
|
+
await delay2(25);
|
|
46509
|
+
}
|
|
46168
46510
|
} catch {
|
|
46169
46511
|
return {
|
|
46170
46512
|
ok: false,
|
|
@@ -46175,6 +46517,22 @@ var ClaudeHarnessSession = class {
|
|
|
46175
46517
|
}
|
|
46176
46518
|
};
|
|
46177
46519
|
}
|
|
46520
|
+
if (messages.length === 0 && isPendingClaudeSession(this.#nativeRef)) {
|
|
46521
|
+
try {
|
|
46522
|
+
const pending = await this.#pendingSessions.read(this.#nativeRef, this.#cwd);
|
|
46523
|
+
if (!pending.started)
|
|
46524
|
+
return { ok: true, value: { turns: [], state: this.#state } };
|
|
46525
|
+
} catch {
|
|
46526
|
+
return {
|
|
46527
|
+
ok: false,
|
|
46528
|
+
error: {
|
|
46529
|
+
code: "sessionNotFound",
|
|
46530
|
+
message: "Claude Code pending Session is unavailable",
|
|
46531
|
+
retryable: false
|
|
46532
|
+
}
|
|
46533
|
+
};
|
|
46534
|
+
}
|
|
46535
|
+
}
|
|
46178
46536
|
if (messages.length === 0) {
|
|
46179
46537
|
return {
|
|
46180
46538
|
ok: false,
|
|
@@ -46319,6 +46677,7 @@ var ClaudeHarnessSession = class {
|
|
|
46319
46677
|
resolveCompletion
|
|
46320
46678
|
};
|
|
46321
46679
|
this.#active = active;
|
|
46680
|
+
this.#submittedInput = true;
|
|
46322
46681
|
this.#event({ type: "turn.started", turnId: command.turnId });
|
|
46323
46682
|
this.#event({ type: "item.started", turnId: command.turnId, item });
|
|
46324
46683
|
try {
|
|
@@ -46426,6 +46785,7 @@ var ClaudeHarnessSession = class {
|
|
|
46426
46785
|
resolveCompletion
|
|
46427
46786
|
};
|
|
46428
46787
|
this.#active = active;
|
|
46788
|
+
this.#submittedInput = true;
|
|
46429
46789
|
this.#event({ type: "turn.started", turnId: command.turnId });
|
|
46430
46790
|
if (item)
|
|
46431
46791
|
this.#event({ type: "item.started", turnId: command.turnId, item });
|
|
@@ -46447,6 +46807,12 @@ var ClaudeHarnessSession = class {
|
|
|
46447
46807
|
this.#requestContextUsage(this.#transport, this.#active?.command.turnId, CONTEXT_USAGE_RETRY_DELAYS_MS);
|
|
46448
46808
|
return this.#contextRefreshInFlight ?? Promise.resolve();
|
|
46449
46809
|
}
|
|
46810
|
+
blocksRollback(sessionId) {
|
|
46811
|
+
return this.#sessionId === sessionId && (this.#phase !== "open" || this.#active !== null || this.#acceptingTurn || this.#configurationTask !== null || this.#readingHistory);
|
|
46812
|
+
}
|
|
46813
|
+
async prepareRollback(sessionId) {
|
|
46814
|
+
return this.#sessionId === sessionId ? this.readSnapshot() : { ok: true, value: null };
|
|
46815
|
+
}
|
|
46450
46816
|
close() {
|
|
46451
46817
|
if (!this.#closePromise)
|
|
46452
46818
|
this.#closePromise = this.#close();
|
|
@@ -46500,6 +46866,9 @@ var ClaudeHarnessSession = class {
|
|
|
46500
46866
|
}
|
|
46501
46867
|
}
|
|
46502
46868
|
this.#requestedModel = command.model;
|
|
46869
|
+
const persistenceError = await this.#savePendingConfiguration();
|
|
46870
|
+
if (persistenceError)
|
|
46871
|
+
return { ok: false, error: persistenceError };
|
|
46503
46872
|
this.#publishState(this.#configuredState());
|
|
46504
46873
|
return { ok: true, value: { completed: true } };
|
|
46505
46874
|
} finally {
|
|
@@ -46555,6 +46924,9 @@ var ClaudeHarnessSession = class {
|
|
|
46555
46924
|
}
|
|
46556
46925
|
}
|
|
46557
46926
|
this.#requestedThinkingOptionId = thinkingOptionId;
|
|
46927
|
+
const persistenceError = await this.#savePendingConfiguration();
|
|
46928
|
+
if (persistenceError)
|
|
46929
|
+
return { ok: false, error: persistenceError };
|
|
46558
46930
|
this.#publishState(this.#configuredState());
|
|
46559
46931
|
return { ok: true, value: { completed: true } };
|
|
46560
46932
|
} finally {
|
|
@@ -46611,6 +46983,9 @@ var ClaudeHarnessSession = class {
|
|
|
46611
46983
|
}
|
|
46612
46984
|
}
|
|
46613
46985
|
this.#requestedPermissionModeId = transport ? encodeClaudePermissionModeId(transport.getPermissionMode()) : command.permissionModeId;
|
|
46986
|
+
const persistenceError = await this.#savePendingConfiguration();
|
|
46987
|
+
if (persistenceError)
|
|
46988
|
+
return { ok: false, error: persistenceError };
|
|
46614
46989
|
this.#publishState(this.#configuredState());
|
|
46615
46990
|
return { ok: true, value: { completed: true } };
|
|
46616
46991
|
} finally {
|
|
@@ -46743,6 +47118,7 @@ var ClaudeHarnessSession = class {
|
|
|
46743
47118
|
async #close() {
|
|
46744
47119
|
if (this.#phase === "closed")
|
|
46745
47120
|
return;
|
|
47121
|
+
this.#phase = "closing";
|
|
46746
47122
|
this.#usageGeneration += 1;
|
|
46747
47123
|
this.#contextUsageFreshUntilMs = 0;
|
|
46748
47124
|
this.#contextUsageCooldownUntilMs = 0;
|
|
@@ -46752,78 +47128,133 @@ var ClaudeHarnessSession = class {
|
|
|
46752
47128
|
this.#contextRefreshWake = null;
|
|
46753
47129
|
this.#clearCancelEscalation();
|
|
46754
47130
|
this.#clearContinuationQuiescence();
|
|
46755
|
-
|
|
46756
|
-
|
|
46757
|
-
|
|
46758
|
-
|
|
46759
|
-
|
|
46760
|
-
|
|
46761
|
-
|
|
46762
|
-
|
|
46763
|
-
|
|
46764
|
-
|
|
46765
|
-
|
|
46766
|
-
this.#finishFailed(active, invalidState("Claude Code Session closed during active Turn"));
|
|
46767
|
-
} else {
|
|
46768
|
-
await this.#transport?.abort().catch(() => void 0);
|
|
46769
|
-
await Promise.race([active.completion, delay2(this.#closeTimeoutMs)]);
|
|
46770
|
-
if (this.#active === active) {
|
|
46771
|
-
await this.#transport?.close().catch(() => void 0);
|
|
46772
|
-
transportClosed = true;
|
|
46773
|
-
this.#finishFailed(active, invalidState("Claude Code Session closed during active Turn"));
|
|
46774
|
-
}
|
|
47131
|
+
const failures = [];
|
|
47132
|
+
const settle = async (task) => {
|
|
47133
|
+
if (!task)
|
|
47134
|
+
return;
|
|
47135
|
+
const timeout = rejectAfter2(this.#closeTimeoutMs * 4, "Claude Code Session close timed out");
|
|
47136
|
+
try {
|
|
47137
|
+
await Promise.race([task, timeout.promise]);
|
|
47138
|
+
} catch (error52) {
|
|
47139
|
+
failures.push(error52);
|
|
47140
|
+
} finally {
|
|
47141
|
+
timeout.cancel();
|
|
46775
47142
|
}
|
|
46776
|
-
}
|
|
46777
|
-
|
|
46778
|
-
|
|
47143
|
+
};
|
|
47144
|
+
const closingTransport = this.#transport;
|
|
47145
|
+
await settle(closingTransport?.close());
|
|
47146
|
+
await settle(this.#configurationTask ?? void 0);
|
|
47147
|
+
await settle(this.#startupTask?.then(() => void 0, () => void 0));
|
|
47148
|
+
if (this.#transport !== closingTransport)
|
|
47149
|
+
await settle(this.#transport?.close());
|
|
47150
|
+
if (failures.length === 0)
|
|
47151
|
+
await settle(this.#releaseUnusedClaim());
|
|
47152
|
+
const active = this.#active;
|
|
47153
|
+
if (active)
|
|
47154
|
+
this.#finishFailed(active, invalidState("Claude Code Session closed during active Turn"));
|
|
46779
47155
|
this.#phase = "closed";
|
|
46780
47156
|
this.#channel.end();
|
|
46781
47157
|
this.#onClosed();
|
|
47158
|
+
if (failures.length > 0)
|
|
47159
|
+
throw new AggregateError(failures, "Claude Code Session could not stop safely");
|
|
46782
47160
|
}
|
|
46783
|
-
|
|
47161
|
+
#ensureTransport() {
|
|
47162
|
+
if (this.#startupTask)
|
|
47163
|
+
return this.#startupTask;
|
|
46784
47164
|
if (this.#transport)
|
|
46785
|
-
return this.#transport;
|
|
47165
|
+
return Promise.resolve(this.#transport);
|
|
47166
|
+
const task = this.#startTransport();
|
|
47167
|
+
this.#startupTask = task;
|
|
47168
|
+
void task.finally(() => {
|
|
47169
|
+
if (this.#startupTask === task)
|
|
47170
|
+
this.#startupTask = null;
|
|
47171
|
+
}).catch(() => void 0);
|
|
47172
|
+
return task;
|
|
47173
|
+
}
|
|
47174
|
+
async #startTransport() {
|
|
47175
|
+
if (this.#openMode === "create" && isPendingClaudeSession(this.#nativeRef)) {
|
|
47176
|
+
await this.#pendingSessions.claim(this.#nativeRef, this.#cwd);
|
|
47177
|
+
this.#pendingClaimed = true;
|
|
47178
|
+
}
|
|
47179
|
+
if (this.#phase !== "open") {
|
|
47180
|
+
await this.#releaseUnusedClaim();
|
|
47181
|
+
throw new Error("Claude Code Session closed during startup");
|
|
47182
|
+
}
|
|
46786
47183
|
const selectedModel = this.#requestedModel ?? (this.#openMode === "create" ? CLAUDE_DEFAULT_MODEL_REF : void 0);
|
|
46787
47184
|
const model = selectedModel ? decodeClaudeModelRef(selectedModel) : void 0;
|
|
46788
47185
|
const permissionMode = decodeClaudePermissionModeId(this.#requestedPermissionModeId);
|
|
46789
|
-
|
|
46790
|
-
cwd: this.#cwd,
|
|
46791
|
-
sessionId: this.#sessionId,
|
|
46792
|
-
openMode: this.#openMode,
|
|
46793
|
-
...model ? { model } : {},
|
|
46794
|
-
thinkingOptionId: this.#requestedThinkingOptionId,
|
|
46795
|
-
permissionMode,
|
|
46796
|
-
onPermissionModeChanged: (mode) => this.#handlePermissionModeChanged(mode),
|
|
46797
|
-
onFault: () => this.#fault(faultError()),
|
|
46798
|
-
onPlanLimit: (planLimit) => this.#handlePlanLimit(planLimit)
|
|
46799
|
-
});
|
|
46800
|
-
transport.setAutonomousTurnHandler((turn) => this.#handleAutonomousTurn(turn));
|
|
46801
|
-
transport.setIdleTurnHandler({
|
|
46802
|
-
onEvent: (event) => {
|
|
46803
|
-
const active = this.#active;
|
|
46804
|
-
if (active)
|
|
46805
|
-
this.#handleTurnEvent(active, event);
|
|
46806
|
-
},
|
|
46807
|
-
onTerminal: (result) => {
|
|
46808
|
-
const active = this.#active;
|
|
46809
|
-
if (active)
|
|
46810
|
-
this.#finishResult(active, result);
|
|
46811
|
-
}
|
|
46812
|
-
});
|
|
47186
|
+
let transport;
|
|
46813
47187
|
try {
|
|
47188
|
+
transport = this.#createTransport({
|
|
47189
|
+
cwd: this.#cwd,
|
|
47190
|
+
sessionId: this.#sessionId,
|
|
47191
|
+
openMode: this.#openMode,
|
|
47192
|
+
...model ? { model } : {},
|
|
47193
|
+
thinkingOptionId: this.#requestedThinkingOptionId,
|
|
47194
|
+
permissionMode,
|
|
47195
|
+
onPermissionModeChanged: (mode) => this.#handlePermissionModeChanged(mode),
|
|
47196
|
+
onFault: () => this.#fault(faultError()),
|
|
47197
|
+
onPlanLimit: (planLimit) => this.#handlePlanLimit(planLimit)
|
|
47198
|
+
});
|
|
47199
|
+
this.#transport = transport;
|
|
47200
|
+
transport.setAutonomousTurnHandler((turn) => this.#handleAutonomousTurn(turn));
|
|
47201
|
+
transport.setIdleTurnHandler({
|
|
47202
|
+
onEvent: (event) => {
|
|
47203
|
+
const active = this.#active;
|
|
47204
|
+
if (active)
|
|
47205
|
+
this.#handleTurnEvent(active, event);
|
|
47206
|
+
},
|
|
47207
|
+
onTerminal: (result) => {
|
|
47208
|
+
const active = this.#active;
|
|
47209
|
+
if (active)
|
|
47210
|
+
this.#finishResult(active, result);
|
|
47211
|
+
}
|
|
47212
|
+
});
|
|
46814
47213
|
await transport.start();
|
|
46815
47214
|
this.#state = {
|
|
46816
47215
|
...this.#configuredState(true),
|
|
46817
47216
|
effectivePermissionModeId: encodeClaudePermissionModeId(transport.getPermissionMode())
|
|
46818
47217
|
};
|
|
46819
47218
|
} catch (error52) {
|
|
46820
|
-
|
|
47219
|
+
try {
|
|
47220
|
+
await this.#transport?.close();
|
|
47221
|
+
} catch (closeError) {
|
|
47222
|
+
this.#fault(faultError());
|
|
47223
|
+
throw closeError;
|
|
47224
|
+
}
|
|
47225
|
+
this.#transport = null;
|
|
47226
|
+
await this.#releaseUnusedClaim();
|
|
46821
47227
|
throw error52;
|
|
46822
47228
|
}
|
|
46823
47229
|
this.#openMode = "resume";
|
|
46824
47230
|
this.#transport = transport;
|
|
46825
47231
|
return transport;
|
|
46826
47232
|
}
|
|
47233
|
+
async #releaseUnusedClaim() {
|
|
47234
|
+
if (!this.#pendingClaimed || this.#submittedInput)
|
|
47235
|
+
return;
|
|
47236
|
+
await this.#pendingSessions.release(this.#nativeRef, this.#cwd);
|
|
47237
|
+
this.#pendingClaimed = false;
|
|
47238
|
+
this.#openMode = "create";
|
|
47239
|
+
}
|
|
47240
|
+
async #savePendingConfiguration() {
|
|
47241
|
+
if (!isPendingClaudeSession(this.#nativeRef))
|
|
47242
|
+
return null;
|
|
47243
|
+
const configuration = { ...this.#configuredState() };
|
|
47244
|
+
delete configuration.nativeRef;
|
|
47245
|
+
try {
|
|
47246
|
+
await this.#pendingSessions.saveConfiguration(this.#nativeRef, this.#cwd, configuration);
|
|
47247
|
+
return null;
|
|
47248
|
+
} catch {
|
|
47249
|
+
const error52 = {
|
|
47250
|
+
code: "nativeFailure",
|
|
47251
|
+
message: "Claude Code pending configuration could not be persisted",
|
|
47252
|
+
retryable: false
|
|
47253
|
+
};
|
|
47254
|
+
this.#fault(error52);
|
|
47255
|
+
return error52;
|
|
47256
|
+
}
|
|
47257
|
+
}
|
|
46827
47258
|
#configuredState(nativeReady = this.#state.nativeRef !== void 0) {
|
|
46828
47259
|
const effectiveModel = this.#requestedModel ?? (this.#openMode === "create" ? CLAUDE_DEFAULT_MODEL_REF : this.#state.effectiveModel);
|
|
46829
47260
|
return {
|
|
@@ -47312,7 +47743,7 @@ var ClaudeHarnessSession = class {
|
|
|
47312
47743
|
}
|
|
47313
47744
|
}
|
|
47314
47745
|
#finishResult(active, result) {
|
|
47315
|
-
if (this.#active !== active)
|
|
47746
|
+
if (this.#active !== active || this.#hardCancelTask)
|
|
47316
47747
|
return;
|
|
47317
47748
|
if (result.status === "succeeded" && (active.tools.size > 0 || active.subagents.size > 0)) {
|
|
47318
47749
|
this.#finishFailed(active, transportFailure("protocol"));
|
|
@@ -47649,6 +48080,12 @@ var ClaudeHarnessSession = class {
|
|
|
47649
48080
|
checkpointId: active.checkpointId,
|
|
47650
48081
|
formatVersion: 1
|
|
47651
48082
|
}) : null;
|
|
48083
|
+
this.#unpersistedMessageIds = [
|
|
48084
|
+
.../* @__PURE__ */ new Set([
|
|
48085
|
+
...active.nativeTurnRef ? [active.nativeTurnRef.nativeTurnKey] : [],
|
|
48086
|
+
...active.checkpointId ? [active.checkpointId] : []
|
|
48087
|
+
])
|
|
48088
|
+
];
|
|
47652
48089
|
this.#event({
|
|
47653
48090
|
type: "turn.completed",
|
|
47654
48091
|
turnId: active.command.turnId,
|
|
@@ -47688,14 +48125,19 @@ var ClaudeHarnessSession = class {
|
|
|
47688
48125
|
this.#cancelEscalation = null;
|
|
47689
48126
|
}
|
|
47690
48127
|
#hardCancel(active) {
|
|
47691
|
-
if (this.#active !== active)
|
|
48128
|
+
if (this.#active !== active || this.#hardCancelTask)
|
|
47692
48129
|
return;
|
|
47693
48130
|
this.#clearCancelEscalation();
|
|
47694
48131
|
const transport = this.#transport;
|
|
47695
|
-
this.#
|
|
47696
|
-
|
|
47697
|
-
|
|
47698
|
-
|
|
48132
|
+
this.#hardCancelTask = Promise.resolve().then(() => transport?.close()).then(() => {
|
|
48133
|
+
if (this.#phase !== "open" || this.#active !== active)
|
|
48134
|
+
return;
|
|
48135
|
+
this.#transport = null;
|
|
48136
|
+
this.#openMode = "resume";
|
|
48137
|
+
this.#finish(active, { status: "cancelled", reason: "Cancelled by user" });
|
|
48138
|
+
}, () => this.#fault(faultError())).finally(() => {
|
|
48139
|
+
this.#hardCancelTask = null;
|
|
48140
|
+
});
|
|
47699
48141
|
}
|
|
47700
48142
|
#fault(error52) {
|
|
47701
48143
|
if (this.#phase === "closed" || this.#phase === "closing" || this.#phase === "faulted")
|
|
@@ -47714,8 +48156,7 @@ var ClaudeHarnessSession = class {
|
|
|
47714
48156
|
this.#phase = "faulted";
|
|
47715
48157
|
this.#event({ type: "session.faulted", error: error52 });
|
|
47716
48158
|
this.#channel.end();
|
|
47717
|
-
void this.#transport?.close();
|
|
47718
|
-
this.#onClosed();
|
|
48159
|
+
void this.#transport?.close().catch(() => void 0);
|
|
47719
48160
|
}
|
|
47720
48161
|
#event(event) {
|
|
47721
48162
|
this.#channel.emit({ kind: "event", event });
|
|
@@ -47789,6 +48230,7 @@ var ClaudeCodeAdapter = class {
|
|
|
47789
48230
|
#importAbort = new AbortController();
|
|
47790
48231
|
#importIndex;
|
|
47791
48232
|
#importRequests = /* @__PURE__ */ new Set();
|
|
48233
|
+
#pendingSessions;
|
|
47792
48234
|
#toolOutputLimit;
|
|
47793
48235
|
#continuationQuiescenceMs;
|
|
47794
48236
|
#inspectionCache = /* @__PURE__ */ new Map();
|
|
@@ -47799,6 +48241,7 @@ var ClaudeCodeAdapter = class {
|
|
|
47799
48241
|
#latestPlanLimit = null;
|
|
47800
48242
|
#accountInspection = null;
|
|
47801
48243
|
constructor(options = {}, dependencies) {
|
|
48244
|
+
this.#pendingSessions = new ClaudePendingSessions(options.environment ?? process.env);
|
|
47802
48245
|
this.#closeTimeoutMs = options.closeTimeoutMs ?? DEFAULT_CLOSE_TIMEOUT_MS;
|
|
47803
48246
|
this.#cancelTimeoutMs = options.cancelTimeoutMs ?? DEFAULT_CANCEL_TIMEOUT_MS;
|
|
47804
48247
|
if (!Number.isSafeInteger(this.#cancelTimeoutMs) || this.#cancelTimeoutMs <= 0) {
|
|
@@ -47813,7 +48256,7 @@ var ClaudeCodeAdapter = class {
|
|
|
47813
48256
|
throw new RangeError("Claude Code continuation quiescence must be a positive safe integer");
|
|
47814
48257
|
}
|
|
47815
48258
|
this.#dependencies = dependencies ?? {
|
|
47816
|
-
randomUUID:
|
|
48259
|
+
randomUUID: randomUUID3,
|
|
47817
48260
|
inspectInstallation: () => {
|
|
47818
48261
|
resolveClaudeCodeExecutable({
|
|
47819
48262
|
...options.command ? { command: options.command } : {},
|
|
@@ -47893,7 +48336,7 @@ var ClaudeCodeAdapter = class {
|
|
|
47893
48336
|
error: invalidState("Claude Code Adapter is closing")
|
|
47894
48337
|
};
|
|
47895
48338
|
}
|
|
47896
|
-
const cwd =
|
|
48339
|
+
const cwd = path12.resolve(input.cwd ?? process.cwd());
|
|
47897
48340
|
if (!input.refresh) {
|
|
47898
48341
|
const cached2 = this.#inspectionCache.get(cwd);
|
|
47899
48342
|
if (cached2)
|
|
@@ -48023,79 +48466,18 @@ var ClaudeCodeAdapter = class {
|
|
|
48023
48466
|
}
|
|
48024
48467
|
};
|
|
48025
48468
|
}
|
|
48026
|
-
|
|
48027
|
-
|
|
48028
|
-
|
|
48029
|
-
|
|
48030
|
-
|
|
48031
|
-
|
|
48032
|
-
|
|
48033
|
-
|
|
48034
|
-
|
|
48035
|
-
retryable: false
|
|
48036
|
-
}
|
|
48037
|
-
};
|
|
48038
|
-
}
|
|
48039
|
-
let sourceSnapshot;
|
|
48040
|
-
try {
|
|
48041
|
-
const messages = await this.#dependencies.readSessionMessages({
|
|
48042
|
-
cwd: path10.resolve(input.cwd),
|
|
48043
|
-
sessionId: sourceRef.data.nativeSessionId
|
|
48044
|
-
});
|
|
48045
|
-
sourceSnapshot = mapClaudeSnapshot(messages, sourceRef.data.nativeSessionId);
|
|
48046
|
-
} catch {
|
|
48047
|
-
return {
|
|
48048
|
-
ok: false,
|
|
48049
|
-
error: {
|
|
48050
|
-
code: "nativeFailure",
|
|
48051
|
-
message: "Claude Code history could not be read",
|
|
48052
|
-
retryable: true
|
|
48053
|
-
}
|
|
48054
|
-
};
|
|
48055
|
-
}
|
|
48056
|
-
if (sourceSnapshot.turns.length === 0) {
|
|
48057
|
-
return {
|
|
48058
|
-
ok: false,
|
|
48059
|
-
error: {
|
|
48060
|
-
code: "invalidState",
|
|
48061
|
-
message: "Claude Code Native Session has no Turn to roll back",
|
|
48062
|
-
retryable: false
|
|
48063
|
-
}
|
|
48064
|
-
};
|
|
48065
|
-
}
|
|
48066
|
-
const retained = sourceSnapshot.turns.at(-2);
|
|
48067
|
-
if (!retained) {
|
|
48068
|
-
rollback = {
|
|
48069
|
-
openMode: "create",
|
|
48070
|
-
sessionId: this.#dependencies.randomUUID()
|
|
48071
|
-
};
|
|
48072
|
-
} else if (!retained.checkpoint?.checkpointId) {
|
|
48073
|
-
return {
|
|
48074
|
-
ok: false,
|
|
48075
|
-
error: {
|
|
48076
|
-
code: "checkpointNotFound",
|
|
48077
|
-
message: "Claude Code last-Turn rollback boundary is unavailable",
|
|
48078
|
-
retryable: false
|
|
48079
|
-
}
|
|
48080
|
-
};
|
|
48081
|
-
} else {
|
|
48082
|
-
const forked2 = await forkClaudeSession({
|
|
48083
|
-
checkpoint: retained.checkpoint,
|
|
48084
|
-
cwd: path10.resolve(input.cwd),
|
|
48085
|
-
dependencies: this.#dependencies,
|
|
48086
|
-
harnessId: this.harnessId,
|
|
48087
|
-
sourceRef: sourceRef.data
|
|
48088
|
-
});
|
|
48089
|
-
if (!forked2.ok)
|
|
48090
|
-
return forked2;
|
|
48091
|
-
rollback = {
|
|
48092
|
-
openMode: "resume",
|
|
48093
|
-
sessionId: forked2.value.sessionId
|
|
48094
|
-
};
|
|
48095
|
-
}
|
|
48469
|
+
if (input.kind === "rollbackLastTurn" && [...this.#sessions].some((session2) => session2.blocksRollback(input.sourceRef.nativeSessionId))) {
|
|
48470
|
+
return {
|
|
48471
|
+
ok: false,
|
|
48472
|
+
error: {
|
|
48473
|
+
code: "sessionBusy",
|
|
48474
|
+
message: "Claude Code Session is busy during rollback",
|
|
48475
|
+
retryable: true
|
|
48476
|
+
}
|
|
48477
|
+
};
|
|
48096
48478
|
}
|
|
48097
48479
|
let requestedThinkingOptionId = CLAUDE_DEFAULT_THINKING_OPTION_ID;
|
|
48098
|
-
if (input.kind === "create" && input.thinkingOptionId) {
|
|
48480
|
+
if ((input.kind === "create" || input.kind === "rollbackLastTurn" || input.kind === "resume") && input.thinkingOptionId) {
|
|
48099
48481
|
try {
|
|
48100
48482
|
requestedThinkingOptionId = parseClaudeThinkingOptionId(input.thinkingOptionId);
|
|
48101
48483
|
} catch {
|
|
@@ -48109,7 +48491,7 @@ var ClaudeCodeAdapter = class {
|
|
|
48109
48491
|
};
|
|
48110
48492
|
}
|
|
48111
48493
|
}
|
|
48112
|
-
if (input.kind === "create" && input.model) {
|
|
48494
|
+
if ((input.kind === "create" || input.kind === "rollbackLastTurn" || input.kind === "resume") && input.model) {
|
|
48113
48495
|
try {
|
|
48114
48496
|
decodeClaudeModelRef(input.model);
|
|
48115
48497
|
} catch {
|
|
@@ -48123,7 +48505,7 @@ var ClaudeCodeAdapter = class {
|
|
|
48123
48505
|
};
|
|
48124
48506
|
}
|
|
48125
48507
|
}
|
|
48126
|
-
|
|
48508
|
+
let requestedPermissionModeId = input.kind === "create" ? input.permissionModeId ?? (input.executionPolicy === "unattended-full-access" ? encodeClaudePermissionModeId("auto") : CLAUDE_DEFAULT_PERMISSION_MODE_ID) : input.kind === "rollbackLastTurn" || input.kind === "resume" ? input.permissionModeId ?? CLAUDE_DEFAULT_PERMISSION_MODE_ID : CLAUDE_DEFAULT_PERMISSION_MODE_ID;
|
|
48127
48509
|
try {
|
|
48128
48510
|
decodeClaudePermissionModeId(requestedPermissionModeId);
|
|
48129
48511
|
} catch {
|
|
@@ -48136,7 +48518,14 @@ var ClaudeCodeAdapter = class {
|
|
|
48136
48518
|
}
|
|
48137
48519
|
};
|
|
48138
48520
|
}
|
|
48139
|
-
const cwd =
|
|
48521
|
+
const cwd = path12.resolve(input.cwd);
|
|
48522
|
+
if (input.kind === "rollbackLastTurn") {
|
|
48523
|
+
for (const source of this.#sessions) {
|
|
48524
|
+
const ready = await source.prepareRollback(input.sourceRef.nativeSessionId);
|
|
48525
|
+
if (!ready.ok)
|
|
48526
|
+
return ready;
|
|
48527
|
+
}
|
|
48528
|
+
}
|
|
48140
48529
|
const nativeRef = input.kind === "resume" ? nativeSessionRefSchema.safeParse(input.nativeRef) : null;
|
|
48141
48530
|
if (nativeRef && (!nativeRef.success || nativeRef.data.harnessId !== this.harnessId)) {
|
|
48142
48531
|
return {
|
|
@@ -48148,8 +48537,16 @@ var ClaudeCodeAdapter = class {
|
|
|
48148
48537
|
}
|
|
48149
48538
|
};
|
|
48150
48539
|
}
|
|
48151
|
-
const forked = input.kind === "fork" ? await forkClaudeSession({
|
|
48152
|
-
checkpoint: input.checkpoint
|
|
48540
|
+
const forked = input.kind === "fork" || input.kind === "rollbackLastTurn" ? await forkClaudeSession({
|
|
48541
|
+
...input.kind === "fork" ? { kind: "fork", checkpoint: input.checkpoint } : {
|
|
48542
|
+
kind: "rollbackLastTurn",
|
|
48543
|
+
pendingSessions: this.#pendingSessions,
|
|
48544
|
+
configuration: {
|
|
48545
|
+
...input.model ? { effectiveModel: input.model } : {},
|
|
48546
|
+
effectiveThinkingOptionId: requestedThinkingOptionId,
|
|
48547
|
+
effectivePermissionModeId: requestedPermissionModeId
|
|
48548
|
+
}
|
|
48549
|
+
},
|
|
48153
48550
|
cwd,
|
|
48154
48551
|
dependencies: this.#dependencies,
|
|
48155
48552
|
harnessId: this.harnessId,
|
|
@@ -48157,11 +48554,49 @@ var ClaudeCodeAdapter = class {
|
|
|
48157
48554
|
}) : null;
|
|
48158
48555
|
if (forked && !forked.ok)
|
|
48159
48556
|
return forked;
|
|
48557
|
+
const durableRef = forked?.ok ? forked.value.nativeRef : nativeRef?.success ? nativeRef.data : void 0;
|
|
48558
|
+
let openMode = forked?.ok && forked.value.openMode === "create" || input.kind === "create" ? "create" : "resume";
|
|
48559
|
+
let requestedModel = input.kind !== "fork" ? input.model : void 0;
|
|
48560
|
+
if (durableRef && isPendingClaudeSession(durableRef)) {
|
|
48561
|
+
try {
|
|
48562
|
+
const pending = await this.#pendingSessions.read(durableRef, cwd);
|
|
48563
|
+
if (!pending.started) {
|
|
48564
|
+
const messages = await this.#dependencies.readSessionMessages({
|
|
48565
|
+
cwd,
|
|
48566
|
+
sessionId: durableRef.nativeSessionId
|
|
48567
|
+
});
|
|
48568
|
+
if (messages.length > 0 || input.kind === "resume" && input.knownTurnRefs?.length)
|
|
48569
|
+
throw new Error("Pending Session unexpectedly contains history");
|
|
48570
|
+
openMode = "create";
|
|
48571
|
+
}
|
|
48572
|
+
if (pending.configuration.effectiveModel)
|
|
48573
|
+
decodeClaudeModelRef(pending.configuration.effectiveModel);
|
|
48574
|
+
if (pending.configuration.effectiveThinkingOptionId)
|
|
48575
|
+
parseClaudeThinkingOptionId(pending.configuration.effectiveThinkingOptionId);
|
|
48576
|
+
if (pending.configuration.effectivePermissionModeId)
|
|
48577
|
+
decodeClaudePermissionModeId(pending.configuration.effectivePermissionModeId);
|
|
48578
|
+
requestedModel = pending.configuration.effectiveModel ?? requestedModel;
|
|
48579
|
+
requestedThinkingOptionId = pending.configuration.effectiveThinkingOptionId ?? requestedThinkingOptionId;
|
|
48580
|
+
requestedPermissionModeId = input.kind === "resume" && input.permissionModeId ? input.permissionModeId : pending.configuration.effectivePermissionModeId ?? requestedPermissionModeId;
|
|
48581
|
+
} catch {
|
|
48582
|
+
return {
|
|
48583
|
+
ok: false,
|
|
48584
|
+
error: {
|
|
48585
|
+
code: "sessionNotFound",
|
|
48586
|
+
message: "Claude Code pending Session cannot be recovered",
|
|
48587
|
+
retryable: false
|
|
48588
|
+
}
|
|
48589
|
+
};
|
|
48590
|
+
}
|
|
48591
|
+
}
|
|
48160
48592
|
const session = new ClaudeHarnessSession(cwd, this.#dependencies, this.#closeTimeoutMs, () => this.#sessions.delete(session), (planLimit) => this.#recordPlanLimit(session, planLimit), {
|
|
48161
48593
|
...input.environment ? { environment: input.environment } : {},
|
|
48162
|
-
openMode
|
|
48163
|
-
|
|
48164
|
-
|
|
48594
|
+
openMode,
|
|
48595
|
+
pendingSessions: this.#pendingSessions,
|
|
48596
|
+
knownConfiguration: input.kind === "rollbackLastTurn" || input.kind === "resume" && Boolean(input.model || input.thinkingOptionId) || Boolean(durableRef && isPendingClaudeSession(durableRef)),
|
|
48597
|
+
...durableRef ? { nativeRef: durableRef } : {},
|
|
48598
|
+
sessionId: forked?.ok ? forked.value.sessionId : nativeRef?.success ? nativeRef.data.nativeSessionId : this.#dependencies.randomUUID(),
|
|
48599
|
+
...requestedModel ? { requestedModel } : {},
|
|
48165
48600
|
requestedPermissionModeId,
|
|
48166
48601
|
requestedThinkingOptionId,
|
|
48167
48602
|
toolOutputLimit: this.#toolOutputLimit,
|
|
@@ -48206,7 +48641,7 @@ var ClaudeCodeAdapter = class {
|
|
|
48206
48641
|
};
|
|
48207
48642
|
|
|
48208
48643
|
// dist/user-shell-environment.js
|
|
48209
|
-
import
|
|
48644
|
+
import path13 from "node:path";
|
|
48210
48645
|
import { spawnSync } from "node:child_process";
|
|
48211
48646
|
var ENVIRONMENT_MARKER = Buffer.from("\0CODEXHOST_USER_SHELL_ENV_V1\0");
|
|
48212
48647
|
var ENVIRONMENT_COMMAND = "printf '\\0CODEXHOST_USER_SHELL_ENV_V1\\0'; /usr/bin/env -0";
|
|
@@ -48249,7 +48684,7 @@ function withUserShellEnvironment(environment, dependencies) {
|
|
|
48249
48684
|
if (platform === "win32" || !environment.HOME)
|
|
48250
48685
|
return environment;
|
|
48251
48686
|
const shell = environment.SHELL?.trim() || defaultShell(platform);
|
|
48252
|
-
if (!shell || !SUPPORTED_SHELLS.has(
|
|
48687
|
+
if (!shell || !SUPPORTED_SHELLS.has(path13.basename(shell)))
|
|
48253
48688
|
return environment;
|
|
48254
48689
|
const cacheKey = `${platform}\0${shell}\0${environment.HOME}`;
|
|
48255
48690
|
const cached2 = dependencies ? void 0 : shellEnvironmentCache.get(cacheKey);
|