@codexhost/cli-darwin-x64 0.6.0 → 0.6.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 +1 -1
- package/app/codexhost-distribution.json +1 -1
- package/app/desktop-controller.mjs +2 -1
- package/app/host-runtime.mjs +628 -260
- package/app/plugins/antigravity/plugin.mjs +15 -8
- package/app/plugins/claude-code/plugin.mjs +661 -219
- package/app/plugins/deepseek-harness/plugin.mjs +7277 -10029
- package/app/plugins/enabled.json +2 -1
- package/app/plugins/grok/plugin.mjs +932 -75
- package/app/plugins/kiro-cli/assets/icon.svg +5 -0
- package/app/plugins/kiro-cli/manifest.json +12 -0
- package/app/plugins/kiro-cli/plugin.mjs +23339 -0
- package/app/plugins/omp/plugin.mjs +11 -1
- package/app/plugins/opencode/plugin.mjs +297 -143
- package/app/plugins/pi/plugin.mjs +1489 -1300
- package/app/renderer-extension.js +715 -377
- package/bin/codexhost +0 -0
- package/libexec/codexhost-shim +0 -0
- package/libexec/codexhost-updater +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, path12) {
|
|
780
|
+
if (!path12)
|
|
781
781
|
return obj;
|
|
782
|
-
return
|
|
782
|
+
return path12.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(path12, 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(path12);
|
|
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, path12 = []) => {
|
|
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 }, [...path12, ...issue2.path]));
|
|
1346
1346
|
} else if (issue2.code === "invalid_key") {
|
|
1347
|
-
processError({ issues: issue2.issues }, [...
|
|
1347
|
+
processError({ issues: issue2.issues }, [...path12, ...issue2.path]);
|
|
1348
1348
|
} else if (issue2.code === "invalid_element") {
|
|
1349
|
-
processError({ issues: issue2.issues }, [...
|
|
1349
|
+
processError({ issues: issue2.issues }, [...path12, ...issue2.path]);
|
|
1350
1350
|
} else {
|
|
1351
|
-
const fullpath = [...
|
|
1351
|
+
const fullpath = [...path12, ...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, path12 = []) => {
|
|
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 }, [...path12, ...issue2.path]));
|
|
1383
1383
|
} else if (issue2.code === "invalid_key") {
|
|
1384
|
-
processError({ issues: issue2.issues }, [...
|
|
1384
|
+
processError({ issues: issue2.issues }, [...path12, ...issue2.path]);
|
|
1385
1385
|
} else if (issue2.code === "invalid_element") {
|
|
1386
|
-
processError({ issues: issue2.issues }, [...
|
|
1386
|
+
processError({ issues: issue2.issues }, [...path12, ...issue2.path]);
|
|
1387
1387
|
} else {
|
|
1388
|
-
const fullpath = [...
|
|
1388
|
+
const fullpath = [...path12, ...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 path12 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
1421
|
+
for (const seg of path12) {
|
|
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 path12 = ref.slice(1).split("/").filter(Boolean);
|
|
14114
|
+
if (path12.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 (path12[0] === defsKey) {
|
|
14119
|
+
const key = path12[1];
|
|
14120
14120
|
if (!key || !ctx.defs[key]) {
|
|
14121
14121
|
throw new Error(`Reference not found: ${ref}`);
|
|
14122
14122
|
}
|
|
@@ -14550,6 +14550,8 @@ var threadUsageSnapshotSchema = external_exports.object({
|
|
|
14550
14550
|
reasoningOutputTokens: nonNegativeSafeIntegerSchema.optional(),
|
|
14551
14551
|
totalTokens: nonNegativeSafeIntegerSchema.optional(),
|
|
14552
14552
|
totalCostUsd: finiteNonNegativeNumberSchema.optional(),
|
|
14553
|
+
totalCredits: finiteNonNegativeNumberSchema.optional(),
|
|
14554
|
+
contextUsagePercent: finiteNonNegativeNumberSchema.optional(),
|
|
14553
14555
|
cacheHitRatePercent: cacheHitRatePercentSchema.optional(),
|
|
14554
14556
|
contextWindowTokens: nonNegativeSafeIntegerSchema.optional(),
|
|
14555
14557
|
contextUsedTokens: nonNegativeSafeIntegerSchema.optional(),
|
|
@@ -15481,7 +15483,9 @@ var usageFields = /* @__PURE__ */ new Set([
|
|
|
15481
15483
|
...tokenFields,
|
|
15482
15484
|
...safeIntegerFields,
|
|
15483
15485
|
...percentFields,
|
|
15484
|
-
"totalCostUsd"
|
|
15486
|
+
"totalCostUsd",
|
|
15487
|
+
"totalCredits",
|
|
15488
|
+
"contextUsagePercent"
|
|
15485
15489
|
]);
|
|
15486
15490
|
function isRecord(value) {
|
|
15487
15491
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -15497,6 +15501,12 @@ function parseHostUsage(value) {
|
|
|
15497
15501
|
throw new Error(`Harness Usage contains unknown field '${key}'`);
|
|
15498
15502
|
}
|
|
15499
15503
|
}
|
|
15504
|
+
for (const field of ["totalCredits", "contextUsagePercent"]) {
|
|
15505
|
+
const candidate = value[field];
|
|
15506
|
+
if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isFinite(candidate) || candidate < 0)) {
|
|
15507
|
+
throw new Error(`Harness Usage '${field}' must be a finite non-negative number`);
|
|
15508
|
+
}
|
|
15509
|
+
}
|
|
15500
15510
|
for (const field of tokenFields) {
|
|
15501
15511
|
const candidate = value[field];
|
|
15502
15512
|
if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isSafeInteger(candidate) || candidate < 0)) {
|
|
@@ -15673,6 +15683,8 @@ var createSchema = external_exports.object({
|
|
|
15673
15683
|
}).strict();
|
|
15674
15684
|
var resumeSchema = external_exports.object({
|
|
15675
15685
|
kind: external_exports.literal("resume"),
|
|
15686
|
+
model: harnessModelRefSchema.optional(),
|
|
15687
|
+
thinkingOptionId: harnessThinkingOptionIdSchema.optional(),
|
|
15676
15688
|
nativeRef: nativeSessionRefSchema,
|
|
15677
15689
|
cwd: cwdSchema,
|
|
15678
15690
|
knownTurnRefs: external_exports.array(nativeTurnRefSchema).max(1e5).optional()
|
|
@@ -15685,6 +15697,9 @@ var forkSchema = external_exports.object({
|
|
|
15685
15697
|
}).strict();
|
|
15686
15698
|
var rollbackSchema = external_exports.object({
|
|
15687
15699
|
kind: external_exports.literal("rollbackLastTurn"),
|
|
15700
|
+
model: harnessModelRefSchema.optional(),
|
|
15701
|
+
thinkingOptionId: harnessThinkingOptionIdSchema.optional(),
|
|
15702
|
+
permissionModeId: harnessPermissionModeIdSchema.optional(),
|
|
15688
15703
|
sourceRef: nativeSessionRefSchema,
|
|
15689
15704
|
cwd: cwdSchema
|
|
15690
15705
|
}).strict();
|
|
@@ -16294,8 +16309,8 @@ var BrokeredHarnessAdapter = class {
|
|
|
16294
16309
|
};
|
|
16295
16310
|
|
|
16296
16311
|
// dist/claude-code-adapter.js
|
|
16297
|
-
import { randomUUID as
|
|
16298
|
-
import
|
|
16312
|
+
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
16313
|
+
import path10 from "node:path";
|
|
16299
16314
|
|
|
16300
16315
|
// ../../../node_modules/@anthropic-ai/claude-agent-sdk/sdk.mjs
|
|
16301
16316
|
import { createRequire as DW } from "node:module";
|
|
@@ -20200,8 +20215,8 @@ var qU = v(function(BU) {
|
|
|
20200
20215
|
BU._globalThis = void 0;
|
|
20201
20216
|
BU._globalThis = typeof globalThis === "object" ? globalThis : global;
|
|
20202
20217
|
});
|
|
20203
|
-
var GU = v(function(
|
|
20204
|
-
var Axe =
|
|
20218
|
+
var GU = v(function(os5) {
|
|
20219
|
+
var Axe = os5 && os5.__createBinding || (Object.create ? function(e, t, r, n) {
|
|
20205
20220
|
if (n === void 0) n = r;
|
|
20206
20221
|
Object.defineProperty(e, n, { enumerable: true, get: function() {
|
|
20207
20222
|
return t[r];
|
|
@@ -20209,11 +20224,11 @@ var GU = v(function(os4) {
|
|
|
20209
20224
|
} : function(e, t, r, n) {
|
|
20210
20225
|
if (n === void 0) n = r;
|
|
20211
20226
|
e[n] = t[r];
|
|
20212
|
-
}), kxe =
|
|
20227
|
+
}), kxe = os5 && os5.__exportStar || function(e, t) {
|
|
20213
20228
|
for (var r in e) if (r !== "default" && !Object.prototype.hasOwnProperty.call(t, r)) Axe(t, e, r);
|
|
20214
20229
|
};
|
|
20215
|
-
Object.defineProperty(
|
|
20216
|
-
kxe(qU(),
|
|
20230
|
+
Object.defineProperty(os5, "__esModule", { value: true });
|
|
20231
|
+
kxe(qU(), os5);
|
|
20217
20232
|
});
|
|
20218
20233
|
var WU = v(function(is) {
|
|
20219
20234
|
var Oxe = is && is.__createBinding || (Object.create ? function(e, t, r, n) {
|
|
@@ -42261,8 +42276,136 @@ function resolveClaudeCodeExecutable(input = {}, dependencies = {}) {
|
|
|
42261
42276
|
return targetPath(platform).isAbsolute(resolution.executable) ? resolution.executable : path4.resolve(resolution.executable);
|
|
42262
42277
|
}
|
|
42263
42278
|
|
|
42264
|
-
// dist/
|
|
42279
|
+
// dist/pending-session.js
|
|
42280
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
42281
|
+
import { mkdir, open, readFile as readFile2, rename, rm as rm2, stat, unlink } from "node:fs/promises";
|
|
42282
|
+
import os3 from "node:os";
|
|
42265
42283
|
import path5 from "node:path";
|
|
42284
|
+
var reservationSchema = external_exports.strictObject({
|
|
42285
|
+
version: external_exports.literal(1),
|
|
42286
|
+
sessionId: external_exports.uuid(),
|
|
42287
|
+
cwd: external_exports.string().min(1),
|
|
42288
|
+
configuration: harnessConfigurationStateSchema
|
|
42289
|
+
});
|
|
42290
|
+
function isPendingClaudeSession(ref) {
|
|
42291
|
+
return ref.locator !== void 0;
|
|
42292
|
+
}
|
|
42293
|
+
var ClaudePendingSessions = class {
|
|
42294
|
+
#directory;
|
|
42295
|
+
constructor(environment) {
|
|
42296
|
+
this.#directory = path5.join(path5.resolve(environment.CLAUDE_CONFIG_DIR ?? path5.join(os3.homedir(), ".claude")), "codexhost", "pending-sessions");
|
|
42297
|
+
}
|
|
42298
|
+
#path(ref, cwd) {
|
|
42299
|
+
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)) {
|
|
42300
|
+
throw new Error("Claude Code pending Session identity is invalid");
|
|
42301
|
+
}
|
|
42302
|
+
return path5.join(this.#directory, ref.nativeSessionId);
|
|
42303
|
+
}
|
|
42304
|
+
async create(cwd, configuration) {
|
|
42305
|
+
const ref = nativeSessionRefSchema.parse({
|
|
42306
|
+
harnessId: "claude-code",
|
|
42307
|
+
nativeSessionId: randomUUID2(),
|
|
42308
|
+
locator: { pendingSession: 1 },
|
|
42309
|
+
formatVersion: 1
|
|
42310
|
+
});
|
|
42311
|
+
const directory = this.#path(ref, cwd);
|
|
42312
|
+
const reservation = reservationSchema.parse({
|
|
42313
|
+
version: 1,
|
|
42314
|
+
sessionId: ref.nativeSessionId,
|
|
42315
|
+
cwd,
|
|
42316
|
+
configuration
|
|
42317
|
+
});
|
|
42318
|
+
await mkdir(this.#directory, { recursive: true, mode: 448 });
|
|
42319
|
+
await mkdir(directory, { mode: 448 });
|
|
42320
|
+
try {
|
|
42321
|
+
const file2 = await open(path5.join(directory, "session.json"), "wx", 384);
|
|
42322
|
+
try {
|
|
42323
|
+
await file2.writeFile(JSON.stringify(reservation));
|
|
42324
|
+
await file2.sync();
|
|
42325
|
+
} finally {
|
|
42326
|
+
await file2.close();
|
|
42327
|
+
}
|
|
42328
|
+
} catch (error52) {
|
|
42329
|
+
await rm2(directory, { recursive: true, force: true });
|
|
42330
|
+
throw error52;
|
|
42331
|
+
}
|
|
42332
|
+
await this.#sync(directory);
|
|
42333
|
+
await this.#sync(this.#directory);
|
|
42334
|
+
return ref;
|
|
42335
|
+
}
|
|
42336
|
+
async read(ref, cwd) {
|
|
42337
|
+
const directory = this.#path(ref, cwd);
|
|
42338
|
+
const reservation = reservationSchema.parse(JSON.parse(await readFile2(path5.join(directory, "session.json"), "utf8")));
|
|
42339
|
+
if (reservation.sessionId !== ref.nativeSessionId || reservation.cwd !== cwd) {
|
|
42340
|
+
throw new Error("Claude Code pending Session does not belong to this working directory");
|
|
42341
|
+
}
|
|
42342
|
+
let started = false;
|
|
42343
|
+
try {
|
|
42344
|
+
const claim = await stat(path5.join(directory, "started"));
|
|
42345
|
+
if (!claim.isFile())
|
|
42346
|
+
throw new Error("Claude Code pending Session claim is invalid");
|
|
42347
|
+
started = true;
|
|
42348
|
+
} catch (error52) {
|
|
42349
|
+
if (error52.code !== "ENOENT")
|
|
42350
|
+
throw error52;
|
|
42351
|
+
}
|
|
42352
|
+
return { started, configuration: reservation.configuration };
|
|
42353
|
+
}
|
|
42354
|
+
async saveConfiguration(ref, cwd, configuration) {
|
|
42355
|
+
await this.read(ref, cwd);
|
|
42356
|
+
const directory = this.#path(ref, cwd);
|
|
42357
|
+
const temporary = path5.join(directory, `${randomUUID2()}.tmp`);
|
|
42358
|
+
try {
|
|
42359
|
+
const file2 = await open(temporary, "wx", 384);
|
|
42360
|
+
try {
|
|
42361
|
+
await file2.writeFile(JSON.stringify(reservationSchema.parse({
|
|
42362
|
+
version: 1,
|
|
42363
|
+
sessionId: ref.nativeSessionId,
|
|
42364
|
+
cwd,
|
|
42365
|
+
configuration
|
|
42366
|
+
})));
|
|
42367
|
+
await file2.sync();
|
|
42368
|
+
} finally {
|
|
42369
|
+
await file2.close();
|
|
42370
|
+
}
|
|
42371
|
+
await rename(temporary, path5.join(directory, "session.json"));
|
|
42372
|
+
await this.#sync(directory);
|
|
42373
|
+
} finally {
|
|
42374
|
+
await rm2(temporary, { force: true });
|
|
42375
|
+
}
|
|
42376
|
+
}
|
|
42377
|
+
async #sync(directory) {
|
|
42378
|
+
if (process.platform === "win32")
|
|
42379
|
+
return;
|
|
42380
|
+
const handle = await open(directory, "r");
|
|
42381
|
+
try {
|
|
42382
|
+
await handle.sync();
|
|
42383
|
+
} finally {
|
|
42384
|
+
await handle.close();
|
|
42385
|
+
}
|
|
42386
|
+
}
|
|
42387
|
+
async claim(ref, cwd) {
|
|
42388
|
+
await this.read(ref, cwd);
|
|
42389
|
+
const claim = await open(path5.join(this.#path(ref, cwd), "started"), "wx", 384);
|
|
42390
|
+
try {
|
|
42391
|
+
await claim.sync();
|
|
42392
|
+
} finally {
|
|
42393
|
+
await claim.close();
|
|
42394
|
+
}
|
|
42395
|
+
await this.#sync(this.#path(ref, cwd));
|
|
42396
|
+
}
|
|
42397
|
+
/** Only the claim owner may release, after proven close and before submitting any native input. */
|
|
42398
|
+
async release(ref, cwd) {
|
|
42399
|
+
await unlink(path5.join(this.#path(ref, cwd), "started"));
|
|
42400
|
+
await this.#sync(this.#path(ref, cwd));
|
|
42401
|
+
}
|
|
42402
|
+
async discard(ref, cwd) {
|
|
42403
|
+
await rm2(this.#path(ref, cwd), { recursive: true, force: true });
|
|
42404
|
+
}
|
|
42405
|
+
};
|
|
42406
|
+
|
|
42407
|
+
// dist/claude-fork.js
|
|
42408
|
+
import path6 from "node:path";
|
|
42266
42409
|
import { isDeepStrictEqual } from "node:util";
|
|
42267
42410
|
|
|
42268
42411
|
// dist/item-identity.js
|
|
@@ -42330,9 +42473,19 @@ function visibleUserTextParts(message) {
|
|
|
42330
42473
|
return [];
|
|
42331
42474
|
return parts.filter((part) => !isLocalCommandRecord(part) && !isTaskNotificationRecord(part));
|
|
42332
42475
|
}
|
|
42476
|
+
function isInterruptionRecord(value, promptId) {
|
|
42477
|
+
if (value.type !== "user" || promptId === null || value.promptId !== promptId || value.promptSource !== void 0 || !isRecord2(value.message))
|
|
42478
|
+
return false;
|
|
42479
|
+
const content = value.message.content;
|
|
42480
|
+
if (!Array.isArray(content) || content.length !== 1)
|
|
42481
|
+
return false;
|
|
42482
|
+
const part = content[0];
|
|
42483
|
+
return isRecord2(part) && part.type === "text" && (part.text === "[Request interrupted by user]" || part.text === "[Request interrupted by user for tool use]");
|
|
42484
|
+
}
|
|
42333
42485
|
function conversationMessages(values, sessionId) {
|
|
42334
42486
|
const messages = [];
|
|
42335
42487
|
const ids = /* @__PURE__ */ new Set();
|
|
42488
|
+
let promptId = null;
|
|
42336
42489
|
for (const value of values) {
|
|
42337
42490
|
if (!isRecord2(value))
|
|
42338
42491
|
throw new Error("Claude history contains a malformed message");
|
|
@@ -42344,12 +42497,18 @@ function conversationMessages(values, sessionId) {
|
|
|
42344
42497
|
if (ids.has(value.uuid))
|
|
42345
42498
|
throw new Error("Claude history contains duplicate message IDs");
|
|
42346
42499
|
ids.add(value.uuid);
|
|
42347
|
-
|
|
42500
|
+
const interrupted = isInterruptionRecord(value, promptId);
|
|
42501
|
+
const message = {
|
|
42348
42502
|
type: value.type,
|
|
42349
42503
|
uuid: value.uuid,
|
|
42350
42504
|
message: value.message,
|
|
42351
|
-
|
|
42352
|
-
|
|
42505
|
+
interrupted,
|
|
42506
|
+
syntheticUser: value.type === "user" && (interrupted || value.isSynthetic === true || value.isMeta === true || isTaskNotificationOrigin(value) || value.toolUseResult !== void 0 && value.toolUseResult !== null)
|
|
42507
|
+
};
|
|
42508
|
+
messages.push(message);
|
|
42509
|
+
if (isHumanUser(message)) {
|
|
42510
|
+
promptId = typeof value.promptId === "string" && value.promptId.length > 0 ? value.promptId : null;
|
|
42511
|
+
}
|
|
42353
42512
|
}
|
|
42354
42513
|
return messages;
|
|
42355
42514
|
}
|
|
@@ -42357,6 +42516,8 @@ function isHumanUser(message) {
|
|
|
42357
42516
|
return visibleUserTextParts(message).length > 0;
|
|
42358
42517
|
}
|
|
42359
42518
|
function turnOutcome(messages) {
|
|
42519
|
+
if (messages.some(({ interrupted }) => interrupted))
|
|
42520
|
+
return { status: "cancelled", reason: "Cancelled by user" };
|
|
42360
42521
|
const assistants = messages.filter(({ type }) => type === "assistant");
|
|
42361
42522
|
const failed = assistants.some(({ message }) => typeof message.error === "string");
|
|
42362
42523
|
if (failed) {
|
|
@@ -42403,7 +42564,7 @@ function mapClaudeSnapshot(values, sessionId) {
|
|
|
42403
42564
|
const turnMessages = messages.slice(index, end);
|
|
42404
42565
|
const outcome = turnOutcome(turnMessages);
|
|
42405
42566
|
const results = toolResultBlocks(turnMessages);
|
|
42406
|
-
const checkpointMessage = turnMessages.findLast(({ type }) => type === "assistant");
|
|
42567
|
+
const checkpointMessage = turnMessages.findLast(({ type, interrupted }) => type === "assistant" || interrupted);
|
|
42407
42568
|
let agentMessageOrdinal = 0;
|
|
42408
42569
|
let reasoningOrdinal = 0;
|
|
42409
42570
|
turns.push({
|
|
@@ -42716,6 +42877,7 @@ function comparableTurn(turn) {
|
|
|
42716
42877
|
outcome
|
|
42717
42878
|
})),
|
|
42718
42879
|
outcome: turn.outcome,
|
|
42880
|
+
hasCheckpoint: turn.checkpoint !== void 0,
|
|
42719
42881
|
...turn.model ? { model: turn.model } : {}
|
|
42720
42882
|
};
|
|
42721
42883
|
}
|
|
@@ -42752,8 +42914,8 @@ async function readSnapshot(dependencies, cwd, sessionId) {
|
|
|
42752
42914
|
}
|
|
42753
42915
|
async function forkClaudeSession(input) {
|
|
42754
42916
|
const sourceRef = nativeSessionRefSchema.safeParse(input.sourceRef);
|
|
42755
|
-
const checkpoint = nativeCheckpointRefSchema.safeParse(input.checkpoint);
|
|
42756
|
-
if (!sourceRef.success ||
|
|
42917
|
+
const checkpoint = input.kind === "fork" ? nativeCheckpointRefSchema.safeParse(input.checkpoint) : null;
|
|
42918
|
+
if (!sourceRef.success || sourceRef.data.harnessId !== input.harnessId || checkpoint && (!checkpoint.success || checkpoint.data.harnessId !== input.harnessId || checkpoint.data.nativeSessionId !== sourceRef.data.nativeSessionId)) {
|
|
42757
42919
|
return {
|
|
42758
42920
|
ok: false,
|
|
42759
42921
|
error: error51("invalidRequest", "Claude Code Fork identity does not belong to the source Session", false)
|
|
@@ -42782,7 +42944,7 @@ async function forkClaudeSession(input) {
|
|
|
42782
42944
|
error: error51("protocolError", "Claude Code Session working directory is unavailable", false)
|
|
42783
42945
|
};
|
|
42784
42946
|
}
|
|
42785
|
-
if (
|
|
42947
|
+
if (path6.resolve(sourceInfo.cwd) !== input.cwd) {
|
|
42786
42948
|
return {
|
|
42787
42949
|
ok: false,
|
|
42788
42950
|
error: error51("unsupported", "Claude Code cannot Fork across working directories", false)
|
|
@@ -42791,8 +42953,39 @@ async function forkClaudeSession(input) {
|
|
|
42791
42953
|
const source = await readSnapshot(input.dependencies, input.cwd, sourceRef.data.nativeSessionId);
|
|
42792
42954
|
if (!source.ok)
|
|
42793
42955
|
return source;
|
|
42794
|
-
|
|
42795
|
-
|
|
42956
|
+
if (input.kind === "rollbackLastTurn" && source.value.turns.length === 0) {
|
|
42957
|
+
return {
|
|
42958
|
+
ok: false,
|
|
42959
|
+
error: error51("invalidRequest", "Claude Code Session has no Turn to roll back", false)
|
|
42960
|
+
};
|
|
42961
|
+
}
|
|
42962
|
+
if (input.kind === "rollbackLastTurn" && source.value.turns.length === 1) {
|
|
42963
|
+
let nativeRef;
|
|
42964
|
+
try {
|
|
42965
|
+
nativeRef = await input.pendingSessions.create(input.cwd, input.configuration);
|
|
42966
|
+
} catch {
|
|
42967
|
+
return {
|
|
42968
|
+
ok: false,
|
|
42969
|
+
error: error51("nativeFailure", "Claude Code empty rollback could not be persisted", true)
|
|
42970
|
+
};
|
|
42971
|
+
}
|
|
42972
|
+
const sourceAfter2 = await readSnapshot(input.dependencies, input.cwd, sourceRef.data.nativeSessionId);
|
|
42973
|
+
if (!sourceAfter2.ok || !isDeepStrictEqual(sourceAfter2.value, source.value)) {
|
|
42974
|
+
await input.pendingSessions.discard(nativeRef, input.cwd).catch(() => void 0);
|
|
42975
|
+
return {
|
|
42976
|
+
ok: false,
|
|
42977
|
+
error: error51("protocolError", "Claude Code source history changed during rollback", false)
|
|
42978
|
+
};
|
|
42979
|
+
}
|
|
42980
|
+
return {
|
|
42981
|
+
ok: true,
|
|
42982
|
+
value: { sessionId: nativeRef.nativeSessionId, nativeRef, openMode: "create" }
|
|
42983
|
+
};
|
|
42984
|
+
}
|
|
42985
|
+
const boundaryIndex = input.kind === "rollbackLastTurn" ? source.value.turns.length - 2 : source.value.turns.findIndex((turn) => checkpoint?.success && turn.checkpoint?.checkpointId === checkpoint.data.checkpointId);
|
|
42986
|
+
const retained = source.value.turns[boundaryIndex];
|
|
42987
|
+
const boundaryId = retained?.checkpoint?.checkpointId ?? (input.kind === "rollbackLastTurn" ? retained?.nativeTurnRef.nativeTurnKey : void 0);
|
|
42988
|
+
if (boundaryIndex < 0 || !boundaryId) {
|
|
42796
42989
|
return {
|
|
42797
42990
|
ok: false,
|
|
42798
42991
|
error: error51("checkpointNotFound", "Claude Code Fork Checkpoint is unavailable", false)
|
|
@@ -42801,7 +42994,7 @@ async function forkClaudeSession(input) {
|
|
|
42801
42994
|
let derivedSessionId;
|
|
42802
42995
|
try {
|
|
42803
42996
|
const forked = await input.dependencies.forkSession({
|
|
42804
|
-
checkpointId:
|
|
42997
|
+
checkpointId: boundaryId,
|
|
42805
42998
|
cwd: input.cwd,
|
|
42806
42999
|
sourceSessionId: sourceRef.data.nativeSessionId
|
|
42807
43000
|
});
|
|
@@ -42840,7 +43033,7 @@ async function forkClaudeSession(input) {
|
|
|
42840
43033
|
const derivedContent = derived.value.turns.map(comparableTurn);
|
|
42841
43034
|
const sourceIds = nativeIds(source.value);
|
|
42842
43035
|
const derivedIds = nativeIds(derived.value);
|
|
42843
|
-
if (!isDeepStrictEqual(sourceAfter.value.turns.slice(0,
|
|
43036
|
+
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))) {
|
|
42844
43037
|
await cleanup();
|
|
42845
43038
|
return {
|
|
42846
43039
|
ok: false,
|
|
@@ -42851,26 +43044,26 @@ async function forkClaudeSession(input) {
|
|
|
42851
43044
|
}
|
|
42852
43045
|
|
|
42853
43046
|
// dist/claude-transcript.js
|
|
42854
|
-
import
|
|
42855
|
-
import
|
|
42856
|
-
import { readFile as
|
|
43047
|
+
import os4 from "node:os";
|
|
43048
|
+
import path7 from "node:path";
|
|
43049
|
+
import { readFile as readFile3, readdir, stat as stat2 } from "node:fs/promises";
|
|
42857
43050
|
function projectDirectoryName(cwd) {
|
|
42858
43051
|
return cwd.replace(/[^A-Za-z0-9]/gu, "-");
|
|
42859
43052
|
}
|
|
42860
43053
|
function configDirectory(environment) {
|
|
42861
|
-
return environment.CLAUDE_CONFIG_DIR ?
|
|
43054
|
+
return environment.CLAUDE_CONFIG_DIR ? path7.resolve(environment.CLAUDE_CONFIG_DIR) : path7.join(os4.homedir(), ".claude");
|
|
42862
43055
|
}
|
|
42863
43056
|
async function existingFile(file2) {
|
|
42864
43057
|
try {
|
|
42865
|
-
return (await
|
|
43058
|
+
return (await stat2(file2)).isFile();
|
|
42866
43059
|
} catch {
|
|
42867
43060
|
return false;
|
|
42868
43061
|
}
|
|
42869
43062
|
}
|
|
42870
43063
|
async function findTranscript(input) {
|
|
42871
|
-
const projectsDirectory =
|
|
43064
|
+
const projectsDirectory = path7.join(configDirectory(input.environment), "projects");
|
|
42872
43065
|
const name = `${input.sessionId}.jsonl`;
|
|
42873
|
-
const expected =
|
|
43066
|
+
const expected = path7.join(projectsDirectory, projectDirectoryName(input.cwd), name);
|
|
42874
43067
|
if (await existingFile(expected))
|
|
42875
43068
|
return expected;
|
|
42876
43069
|
let projects;
|
|
@@ -42880,7 +43073,7 @@ async function findTranscript(input) {
|
|
|
42880
43073
|
return null;
|
|
42881
43074
|
}
|
|
42882
43075
|
for (const project of projects) {
|
|
42883
|
-
const candidate =
|
|
43076
|
+
const candidate = path7.join(projectsDirectory, project, name);
|
|
42884
43077
|
if (await existingFile(candidate))
|
|
42885
43078
|
return candidate;
|
|
42886
43079
|
}
|
|
@@ -42893,7 +43086,7 @@ async function readClaudeTranscript(input) {
|
|
|
42893
43086
|
const transcript = await findTranscript(input);
|
|
42894
43087
|
if (!transcript)
|
|
42895
43088
|
return null;
|
|
42896
|
-
const contents = await
|
|
43089
|
+
const contents = await readFile3(transcript, "utf8");
|
|
42897
43090
|
const messages = [];
|
|
42898
43091
|
for (const line of contents.split("\n")) {
|
|
42899
43092
|
if (line.trim().length === 0)
|
|
@@ -43171,7 +43364,7 @@ function projectClaudeAccountUsage(usage, account) {
|
|
|
43171
43364
|
}
|
|
43172
43365
|
|
|
43173
43366
|
// dist/file-change.js
|
|
43174
|
-
import
|
|
43367
|
+
import path8 from "node:path";
|
|
43175
43368
|
var hunkSchema = external_exports.object({
|
|
43176
43369
|
oldStart: external_exports.number().int().nonnegative(),
|
|
43177
43370
|
oldLines: external_exports.number().int().nonnegative(),
|
|
@@ -43219,10 +43412,10 @@ function parseClaudeNativeFileChange(toolName, value) {
|
|
|
43219
43412
|
};
|
|
43220
43413
|
}
|
|
43221
43414
|
function displayPath(nativePath, cwd) {
|
|
43222
|
-
const resolvedCwd =
|
|
43223
|
-
const resolvedPath =
|
|
43224
|
-
const relative =
|
|
43225
|
-
const selected = relative.length > 0 && relative !== ".." && !relative.startsWith(`..${
|
|
43415
|
+
const resolvedCwd = path8.resolve(cwd);
|
|
43416
|
+
const resolvedPath = path8.isAbsolute(nativePath) ? path8.resolve(nativePath) : path8.resolve(cwd, nativePath);
|
|
43417
|
+
const relative = path8.relative(resolvedCwd, resolvedPath);
|
|
43418
|
+
const selected = relative.length > 0 && relative !== ".." && !relative.startsWith(`..${path8.sep}`) ? relative : resolvedPath;
|
|
43226
43419
|
const normalized = selected.replaceAll("\\", "/");
|
|
43227
43420
|
return validNativePath(normalized) && normalized !== "." ? normalized : null;
|
|
43228
43421
|
}
|
|
@@ -43234,7 +43427,7 @@ function projectClaudeFileChange(value, cwd) {
|
|
|
43234
43427
|
`@@ -${hunk.oldStart},${hunk.oldLines} +${hunk.newStart},${hunk.newLines} @@`,
|
|
43235
43428
|
...hunk.lines
|
|
43236
43429
|
]);
|
|
43237
|
-
const absoluteDisplayPath =
|
|
43430
|
+
const absoluteDisplayPath = path8.posix.isAbsolute(normalizedPath);
|
|
43238
43431
|
const oldHeader = value.kind === "add" ? "/dev/null" : absoluteDisplayPath ? normalizedPath : `a/${normalizedPath}`;
|
|
43239
43432
|
const newHeader = absoluteDisplayPath ? normalizedPath : `b/${normalizedPath}`;
|
|
43240
43433
|
const unifiedDiff = [`--- ${oldHeader}`, `+++ ${newHeader}`, ...body, ""].join("\n");
|
|
@@ -43921,6 +44114,59 @@ var ClaudeNativeTurnAccumulator = class {
|
|
|
43921
44114
|
}
|
|
43922
44115
|
};
|
|
43923
44116
|
|
|
44117
|
+
// dist/process-fence.js
|
|
44118
|
+
import { execFile } from "node:child_process";
|
|
44119
|
+
import path9 from "node:path";
|
|
44120
|
+
import { setTimeout as setTimeout2 } from "node:timers/promises";
|
|
44121
|
+
import { promisify } from "node:util";
|
|
44122
|
+
var executeFile = promisify(execFile);
|
|
44123
|
+
function signalGroup(pid, signal) {
|
|
44124
|
+
try {
|
|
44125
|
+
process.kill(-pid, signal);
|
|
44126
|
+
return true;
|
|
44127
|
+
} catch (error52) {
|
|
44128
|
+
if (error52.code === "ESRCH")
|
|
44129
|
+
return false;
|
|
44130
|
+
if (signal === 0 && error52.code === "EPERM")
|
|
44131
|
+
return true;
|
|
44132
|
+
throw error52;
|
|
44133
|
+
}
|
|
44134
|
+
}
|
|
44135
|
+
async function closeClaudeProcessGroup(child, timeoutMs) {
|
|
44136
|
+
const pid = child.pid;
|
|
44137
|
+
if (!pid)
|
|
44138
|
+
return;
|
|
44139
|
+
if (process.platform === "win32") {
|
|
44140
|
+
if (child.exitCode !== null || child.signalCode !== null)
|
|
44141
|
+
throw new Error("Claude process tree cannot be confirmed after its Windows root exited");
|
|
44142
|
+
const root = process.env.SystemRoot ?? process.env.SYSTEMROOT;
|
|
44143
|
+
if (!root || !path9.win32.isAbsolute(root))
|
|
44144
|
+
throw new Error("Windows SystemRoot is unavailable");
|
|
44145
|
+
await executeFile(path9.win32.join(root, "System32", "taskkill.exe"), ["/PID", String(pid), "/T", "/F"], {
|
|
44146
|
+
timeout: timeoutMs,
|
|
44147
|
+
windowsHide: true
|
|
44148
|
+
});
|
|
44149
|
+
return;
|
|
44150
|
+
}
|
|
44151
|
+
if (!signalGroup(pid, "SIGTERM"))
|
|
44152
|
+
return;
|
|
44153
|
+
const gracefulDeadline = Date.now() + timeoutMs;
|
|
44154
|
+
while (Date.now() < gracefulDeadline) {
|
|
44155
|
+
if (!signalGroup(pid, 0))
|
|
44156
|
+
return;
|
|
44157
|
+
await setTimeout2(10);
|
|
44158
|
+
}
|
|
44159
|
+
if (!signalGroup(pid, "SIGKILL"))
|
|
44160
|
+
return;
|
|
44161
|
+
const deadline = Date.now() + timeoutMs;
|
|
44162
|
+
while (Date.now() < deadline) {
|
|
44163
|
+
if (!signalGroup(pid, 0))
|
|
44164
|
+
return;
|
|
44165
|
+
await setTimeout2(10);
|
|
44166
|
+
}
|
|
44167
|
+
throw new Error("Claude SDK process group did not exit");
|
|
44168
|
+
}
|
|
44169
|
+
|
|
43924
44170
|
// dist/sdk-transport.js
|
|
43925
44171
|
var CLIENT_APP = "codexhost-claude-code-adapter/0.0.0";
|
|
43926
44172
|
var APPROVAL_TITLE_MAX_LENGTH = 120;
|
|
@@ -44142,6 +44388,7 @@ var ClaudeSdkTransport = class {
|
|
|
44142
44388
|
#provider;
|
|
44143
44389
|
#query = null;
|
|
44144
44390
|
#started = false;
|
|
44391
|
+
#backgroundTasks = /* @__PURE__ */ new Set();
|
|
44145
44392
|
constructor(options) {
|
|
44146
44393
|
this.sessionId = options.sessionId;
|
|
44147
44394
|
this.#cwd = options.cwd;
|
|
@@ -44261,7 +44508,7 @@ var ClaudeSdkTransport = class {
|
|
|
44261
44508
|
return this.runTurn("/recap", userMessageId, onEvent);
|
|
44262
44509
|
}
|
|
44263
44510
|
runTurn(text, userMessageId, onEvent) {
|
|
44264
|
-
if (!this.#started || !this.#query) {
|
|
44511
|
+
if (this.#closePromise || !this.#started || !this.#query) {
|
|
44265
44512
|
return Promise.reject(new Error("Claude SDK transport is not started"));
|
|
44266
44513
|
}
|
|
44267
44514
|
if (this.#active)
|
|
@@ -44416,25 +44663,56 @@ var ClaudeSdkTransport = class {
|
|
|
44416
44663
|
}
|
|
44417
44664
|
}
|
|
44418
44665
|
async #close() {
|
|
44666
|
+
const failures = [];
|
|
44419
44667
|
if (this.#active)
|
|
44420
44668
|
this.#closeInteractions(this.#active, "cancelled");
|
|
44669
|
+
try {
|
|
44670
|
+
const timeout = rejectAfter(this.#closeTimeoutMs, "Claude background tasks did not stop");
|
|
44671
|
+
try {
|
|
44672
|
+
await Promise.race([this.#stopBackgroundTasks(), timeout.promise]);
|
|
44673
|
+
} finally {
|
|
44674
|
+
timeout.cancel();
|
|
44675
|
+
}
|
|
44676
|
+
} catch (error52) {
|
|
44677
|
+
failures.push(error52);
|
|
44678
|
+
}
|
|
44679
|
+
const stopOwnedProcesses = async () => {
|
|
44680
|
+
const stopped = await Promise.allSettled(this.#children.map((child) => closeClaudeProcessGroup(child, this.#closeTimeoutMs)));
|
|
44681
|
+
for (const result of stopped)
|
|
44682
|
+
if (result.status === "rejected")
|
|
44683
|
+
failures.push(result.reason);
|
|
44684
|
+
};
|
|
44685
|
+
if (process.platform === "win32")
|
|
44686
|
+
await stopOwnedProcesses();
|
|
44421
44687
|
this.#input.end();
|
|
44422
|
-
|
|
44423
|
-
|
|
44424
|
-
|
|
44425
|
-
|
|
44426
|
-
]);
|
|
44427
|
-
for (const child of this.#children) {
|
|
44428
|
-
if (!processExited(child))
|
|
44429
|
-
child.kill("SIGTERM");
|
|
44688
|
+
try {
|
|
44689
|
+
this.#query?.close();
|
|
44690
|
+
} catch (error52) {
|
|
44691
|
+
failures.push(error52);
|
|
44430
44692
|
}
|
|
44431
|
-
|
|
44432
|
-
|
|
44433
|
-
|
|
44434
|
-
|
|
44435
|
-
|
|
44436
|
-
|
|
44437
|
-
|
|
44693
|
+
if (process.platform !== "win32")
|
|
44694
|
+
await stopOwnedProcesses();
|
|
44695
|
+
const exitTimeout = rejectAfter(this.#closeTimeoutMs, "Claude SDK process did not exit");
|
|
44696
|
+
try {
|
|
44697
|
+
await Promise.race([
|
|
44698
|
+
Promise.all(this.#children.map((child) => this.#waitForExit(child))),
|
|
44699
|
+
exitTimeout.promise
|
|
44700
|
+
]);
|
|
44701
|
+
} catch (error52) {
|
|
44702
|
+
failures.push(error52);
|
|
44703
|
+
} finally {
|
|
44704
|
+
exitTimeout.cancel();
|
|
44705
|
+
}
|
|
44706
|
+
const drainTimeout = rejectAfter(this.#closeTimeoutMs, "Claude SDK output did not drain");
|
|
44707
|
+
try {
|
|
44708
|
+
await Promise.race([
|
|
44709
|
+
this.#consumeTask?.catch(() => void 0) ?? Promise.resolve(),
|
|
44710
|
+
drainTimeout.promise
|
|
44711
|
+
]);
|
|
44712
|
+
} catch (error52) {
|
|
44713
|
+
failures.push(error52);
|
|
44714
|
+
} finally {
|
|
44715
|
+
drainTimeout.cancel();
|
|
44438
44716
|
}
|
|
44439
44717
|
this.#query = null;
|
|
44440
44718
|
const active = this.#active;
|
|
@@ -44443,10 +44721,40 @@ var ClaudeSdkTransport = class {
|
|
|
44443
44721
|
this.#idleAccumulator = null;
|
|
44444
44722
|
this.#idleLive = false;
|
|
44445
44723
|
active?.reject(new Error("Claude SDK transport closed"));
|
|
44724
|
+
if (failures.length > 0)
|
|
44725
|
+
throw new AggregateError(failures, "Claude SDK shutdown could not be confirmed");
|
|
44726
|
+
}
|
|
44727
|
+
async #stopBackgroundTasks() {
|
|
44728
|
+
const requested = /* @__PURE__ */ new Set();
|
|
44729
|
+
const deadline = Date.now() + this.#closeTimeoutMs;
|
|
44730
|
+
while (this.#backgroundTasks.size > 0) {
|
|
44731
|
+
if (Date.now() >= deadline || !this.#query)
|
|
44732
|
+
throw new Error("Claude background tasks remain active");
|
|
44733
|
+
for (const id of this.#backgroundTasks) {
|
|
44734
|
+
if (requested.has(id))
|
|
44735
|
+
continue;
|
|
44736
|
+
requested.add(id);
|
|
44737
|
+
await this.#query.stopTask(id);
|
|
44738
|
+
}
|
|
44739
|
+
if (this.#backgroundTasks.size > 0)
|
|
44740
|
+
await delay(10);
|
|
44741
|
+
}
|
|
44742
|
+
}
|
|
44743
|
+
#observeBackgroundTasks(message) {
|
|
44744
|
+
if (!isRecord6(message) || message.type !== "system")
|
|
44745
|
+
return;
|
|
44746
|
+
if (message.subtype === "background_tasks_changed" && Array.isArray(message.tasks)) {
|
|
44747
|
+
this.#backgroundTasks = new Set(message.tasks.flatMap((task) => isRecord6(task) && typeof task.task_id === "string" ? [task.task_id] : []));
|
|
44748
|
+
} else if (message.subtype === "task_started" && typeof message.task_id === "string") {
|
|
44749
|
+
this.#backgroundTasks.add(message.task_id);
|
|
44750
|
+
} else if (message.subtype === "task_notification" && typeof message.task_id === "string" && ["completed", "failed", "stopped"].includes(String(message.status))) {
|
|
44751
|
+
this.#backgroundTasks.delete(message.task_id);
|
|
44752
|
+
}
|
|
44446
44753
|
}
|
|
44447
44754
|
async #consume(activeQuery) {
|
|
44448
44755
|
try {
|
|
44449
44756
|
for await (const message of activeQuery) {
|
|
44757
|
+
this.#observeBackgroundTasks(message);
|
|
44450
44758
|
const permissionMode = permissionModeFromMessage(message);
|
|
44451
44759
|
if (permissionMode && permissionMode !== this.#permissionMode) {
|
|
44452
44760
|
this.#permissionMode = permissionMode;
|
|
@@ -44518,7 +44826,8 @@ var ClaudeSdkTransport = class {
|
|
|
44518
44826
|
env: options.env,
|
|
44519
44827
|
signal: options.signal,
|
|
44520
44828
|
stdio: ["pipe", "pipe", "pipe"],
|
|
44521
|
-
windowsHide: true
|
|
44829
|
+
windowsHide: true,
|
|
44830
|
+
detached: process.platform !== "win32"
|
|
44522
44831
|
});
|
|
44523
44832
|
child.stderr.on("data", (chunk) => {
|
|
44524
44833
|
this.#stderrTail = sanitizeDiagnosticTail(`${this.#stderrTail}${chunk.toString()}`);
|
|
@@ -45054,9 +45363,12 @@ function normalizedModel(model) {
|
|
|
45054
45363
|
}
|
|
45055
45364
|
function firstPartyPrice(model) {
|
|
45056
45365
|
const value = normalizedModel(model);
|
|
45057
|
-
if (/claude-opus-4-(5|6|7|8)(?:-|$)/u.test(value)) {
|
|
45366
|
+
if (/claude-opus-(?:5|4-(?:5|6|7|8))(?:-|$)/u.test(value)) {
|
|
45058
45367
|
return { input: 5, cacheWrite: 6.25, cacheRead: 0.5, output: 25 };
|
|
45059
45368
|
}
|
|
45369
|
+
if (/claude-fable-5(?:-1)?(?:-|$)/u.test(value)) {
|
|
45370
|
+
return value.includes("fable-5-1") ? { input: 10, cacheWrite: 12.5, cacheRead: 0.25, output: 50 } : { input: 10, cacheWrite: 12.5, cacheRead: 1, output: 50 };
|
|
45371
|
+
}
|
|
45060
45372
|
if (/claude-opus-4-(0|1)(?:-|$)/u.test(value) || /claude-opus-4-2025/u.test(value)) {
|
|
45061
45373
|
return { input: 15, cacheWrite: 18.75, cacheRead: 1.5, output: 75 };
|
|
45062
45374
|
}
|
|
@@ -45322,6 +45634,10 @@ var ClaudeHarnessSession = class {
|
|
|
45322
45634
|
#onClosed;
|
|
45323
45635
|
#onPlanLimitObserved;
|
|
45324
45636
|
#openMode;
|
|
45637
|
+
#pendingSessions;
|
|
45638
|
+
#pendingClaimed = false;
|
|
45639
|
+
#submittedInput = false;
|
|
45640
|
+
#startupTask = null;
|
|
45325
45641
|
#randomUUID;
|
|
45326
45642
|
#requestedModel;
|
|
45327
45643
|
#requestedPermissionModeId;
|
|
@@ -45339,7 +45655,9 @@ var ClaudeHarnessSession = class {
|
|
|
45339
45655
|
#readingHistory = false;
|
|
45340
45656
|
#state;
|
|
45341
45657
|
#statePublished = false;
|
|
45658
|
+
#unpersistedMessageIds = [];
|
|
45342
45659
|
#transport = null;
|
|
45660
|
+
#hardCancelTask = null;
|
|
45343
45661
|
#usageGeneration = 0;
|
|
45344
45662
|
#latestUsage = null;
|
|
45345
45663
|
#minimumContextUsedTokens = null;
|
|
@@ -45358,6 +45676,7 @@ var ClaudeHarnessSession = class {
|
|
|
45358
45676
|
#continuationQuiescence = null;
|
|
45359
45677
|
constructor(cwd, dependencies, closeTimeoutMs, onClosed, onPlanLimitObserved, options) {
|
|
45360
45678
|
this.#cwd = cwd;
|
|
45679
|
+
this.#pendingSessions = options.pendingSessions;
|
|
45361
45680
|
const environment = options.environment;
|
|
45362
45681
|
this.#createTransport = environment ? (input) => dependencies.createTransport({ ...input, environment }) : dependencies.createTransport;
|
|
45363
45682
|
this.#randomUUID = dependencies.randomUUID;
|
|
@@ -45373,7 +45692,7 @@ var ClaudeHarnessSession = class {
|
|
|
45373
45692
|
this.#sessionId = options.sessionId;
|
|
45374
45693
|
this.#toolOutputLimit = options.toolOutputLimit;
|
|
45375
45694
|
this.#continuationQuiescenceMs = options.continuationQuiescenceMs;
|
|
45376
|
-
this.#nativeRef = nativeSessionRefSchema.parse({
|
|
45695
|
+
this.#nativeRef = options.nativeRef ?? nativeSessionRefSchema.parse({
|
|
45377
45696
|
harnessId: this.harnessId,
|
|
45378
45697
|
nativeSessionId: this.#sessionId,
|
|
45379
45698
|
formatVersion: 1
|
|
@@ -45382,9 +45701,17 @@ var ClaudeHarnessSession = class {
|
|
|
45382
45701
|
list: async () => ({ ok: true, value: claudeCommandCatalog }),
|
|
45383
45702
|
execute: (command) => this.#executeHarnessCommand(command)
|
|
45384
45703
|
};
|
|
45385
|
-
|
|
45704
|
+
const durable = this.#openMode === "resume" || options.nativeRef !== void 0;
|
|
45705
|
+
this.initialState = durable ? {
|
|
45706
|
+
nativeRef: this.#nativeRef,
|
|
45707
|
+
...options.knownConfiguration ? {
|
|
45708
|
+
...options.requestedModel ? { effectiveModel: options.requestedModel } : {},
|
|
45709
|
+
effectiveThinkingOptionId: this.#requestedThinkingOptionId,
|
|
45710
|
+
effectivePermissionModeId: this.#requestedPermissionModeId
|
|
45711
|
+
} : {}
|
|
45712
|
+
} : {};
|
|
45386
45713
|
this.#state = this.initialState;
|
|
45387
|
-
this.#statePublished =
|
|
45714
|
+
this.#statePublished = durable;
|
|
45388
45715
|
this.outputs = this.#channel.outputs;
|
|
45389
45716
|
}
|
|
45390
45717
|
async readSnapshot() {
|
|
@@ -45407,7 +45734,29 @@ var ClaudeHarnessSession = class {
|
|
|
45407
45734
|
try {
|
|
45408
45735
|
let messages;
|
|
45409
45736
|
try {
|
|
45410
|
-
|
|
45737
|
+
const deadline = Date.now() + this.#closeTimeoutMs;
|
|
45738
|
+
for (; ; ) {
|
|
45739
|
+
messages = await this.#readSessionMessages({
|
|
45740
|
+
cwd: this.#cwd,
|
|
45741
|
+
sessionId: this.#sessionId
|
|
45742
|
+
});
|
|
45743
|
+
const ids = new Set(messages.flatMap((message) => isRecord9(message) && typeof message.uuid === "string" ? [message.uuid] : []));
|
|
45744
|
+
if (this.#unpersistedMessageIds.every((id) => ids.has(id))) {
|
|
45745
|
+
this.#unpersistedMessageIds = [];
|
|
45746
|
+
break;
|
|
45747
|
+
}
|
|
45748
|
+
if (Date.now() >= deadline || this.#phase !== "open") {
|
|
45749
|
+
return {
|
|
45750
|
+
ok: false,
|
|
45751
|
+
error: {
|
|
45752
|
+
code: "sessionBusy",
|
|
45753
|
+
message: "Claude Code history is still being persisted",
|
|
45754
|
+
retryable: true
|
|
45755
|
+
}
|
|
45756
|
+
};
|
|
45757
|
+
}
|
|
45758
|
+
await delay2(25);
|
|
45759
|
+
}
|
|
45411
45760
|
} catch {
|
|
45412
45761
|
return {
|
|
45413
45762
|
ok: false,
|
|
@@ -45418,6 +45767,22 @@ var ClaudeHarnessSession = class {
|
|
|
45418
45767
|
}
|
|
45419
45768
|
};
|
|
45420
45769
|
}
|
|
45770
|
+
if (messages.length === 0 && isPendingClaudeSession(this.#nativeRef)) {
|
|
45771
|
+
try {
|
|
45772
|
+
const pending = await this.#pendingSessions.read(this.#nativeRef, this.#cwd);
|
|
45773
|
+
if (!pending.started)
|
|
45774
|
+
return { ok: true, value: { turns: [], state: this.#state } };
|
|
45775
|
+
} catch {
|
|
45776
|
+
return {
|
|
45777
|
+
ok: false,
|
|
45778
|
+
error: {
|
|
45779
|
+
code: "sessionNotFound",
|
|
45780
|
+
message: "Claude Code pending Session is unavailable",
|
|
45781
|
+
retryable: false
|
|
45782
|
+
}
|
|
45783
|
+
};
|
|
45784
|
+
}
|
|
45785
|
+
}
|
|
45421
45786
|
if (messages.length === 0) {
|
|
45422
45787
|
return {
|
|
45423
45788
|
ok: false,
|
|
@@ -45548,6 +45913,7 @@ var ClaudeHarnessSession = class {
|
|
|
45548
45913
|
resolveCompletion
|
|
45549
45914
|
};
|
|
45550
45915
|
this.#active = active;
|
|
45916
|
+
this.#submittedInput = true;
|
|
45551
45917
|
this.#event({ type: "turn.started", turnId: command.turnId });
|
|
45552
45918
|
this.#event({ type: "item.started", turnId: command.turnId, item });
|
|
45553
45919
|
try {
|
|
@@ -45651,6 +46017,7 @@ var ClaudeHarnessSession = class {
|
|
|
45651
46017
|
resolveCompletion
|
|
45652
46018
|
};
|
|
45653
46019
|
this.#active = active;
|
|
46020
|
+
this.#submittedInput = true;
|
|
45654
46021
|
this.#event({ type: "turn.started", turnId: command.turnId });
|
|
45655
46022
|
if (item)
|
|
45656
46023
|
this.#event({ type: "item.started", turnId: command.turnId, item });
|
|
@@ -45672,6 +46039,12 @@ var ClaudeHarnessSession = class {
|
|
|
45672
46039
|
this.#requestContextUsage(this.#transport, this.#active?.command.turnId, CONTEXT_USAGE_RETRY_DELAYS_MS);
|
|
45673
46040
|
return this.#contextRefreshInFlight ?? Promise.resolve();
|
|
45674
46041
|
}
|
|
46042
|
+
blocksRollback(sessionId) {
|
|
46043
|
+
return this.#sessionId === sessionId && (this.#phase !== "open" || this.#active !== null || this.#acceptingTurn || this.#configurationTask !== null || this.#readingHistory);
|
|
46044
|
+
}
|
|
46045
|
+
async prepareRollback(sessionId) {
|
|
46046
|
+
return this.#sessionId === sessionId ? this.readSnapshot() : { ok: true, value: null };
|
|
46047
|
+
}
|
|
45675
46048
|
close() {
|
|
45676
46049
|
if (!this.#closePromise)
|
|
45677
46050
|
this.#closePromise = this.#close();
|
|
@@ -45725,6 +46098,9 @@ var ClaudeHarnessSession = class {
|
|
|
45725
46098
|
}
|
|
45726
46099
|
}
|
|
45727
46100
|
this.#requestedModel = command.model;
|
|
46101
|
+
const persistenceError = await this.#savePendingConfiguration();
|
|
46102
|
+
if (persistenceError)
|
|
46103
|
+
return { ok: false, error: persistenceError };
|
|
45728
46104
|
this.#publishState(this.#configuredState());
|
|
45729
46105
|
return { ok: true, value: { completed: true } };
|
|
45730
46106
|
} finally {
|
|
@@ -45780,6 +46156,9 @@ var ClaudeHarnessSession = class {
|
|
|
45780
46156
|
}
|
|
45781
46157
|
}
|
|
45782
46158
|
this.#requestedThinkingOptionId = thinkingOptionId;
|
|
46159
|
+
const persistenceError = await this.#savePendingConfiguration();
|
|
46160
|
+
if (persistenceError)
|
|
46161
|
+
return { ok: false, error: persistenceError };
|
|
45783
46162
|
this.#publishState(this.#configuredState());
|
|
45784
46163
|
return { ok: true, value: { completed: true } };
|
|
45785
46164
|
} finally {
|
|
@@ -45836,6 +46215,9 @@ var ClaudeHarnessSession = class {
|
|
|
45836
46215
|
}
|
|
45837
46216
|
}
|
|
45838
46217
|
this.#requestedPermissionModeId = transport ? encodeClaudePermissionModeId(transport.getPermissionMode()) : command.permissionModeId;
|
|
46218
|
+
const persistenceError = await this.#savePendingConfiguration();
|
|
46219
|
+
if (persistenceError)
|
|
46220
|
+
return { ok: false, error: persistenceError };
|
|
45839
46221
|
this.#publishState(this.#configuredState());
|
|
45840
46222
|
return { ok: true, value: { completed: true } };
|
|
45841
46223
|
} finally {
|
|
@@ -45968,6 +46350,7 @@ var ClaudeHarnessSession = class {
|
|
|
45968
46350
|
async #close() {
|
|
45969
46351
|
if (this.#phase === "closed")
|
|
45970
46352
|
return;
|
|
46353
|
+
this.#phase = "closing";
|
|
45971
46354
|
this.#usageGeneration += 1;
|
|
45972
46355
|
this.#contextUsageFreshUntilMs = 0;
|
|
45973
46356
|
this.#contextUsageCooldownUntilMs = 0;
|
|
@@ -45977,78 +46360,133 @@ var ClaudeHarnessSession = class {
|
|
|
45977
46360
|
this.#contextRefreshWake = null;
|
|
45978
46361
|
this.#clearCancelEscalation();
|
|
45979
46362
|
this.#clearContinuationQuiescence();
|
|
45980
|
-
|
|
45981
|
-
|
|
45982
|
-
|
|
45983
|
-
|
|
45984
|
-
|
|
45985
|
-
|
|
45986
|
-
|
|
45987
|
-
|
|
45988
|
-
|
|
45989
|
-
|
|
45990
|
-
|
|
45991
|
-
this.#finishFailed(active, invalidState("Claude Code Session closed during active Turn"));
|
|
45992
|
-
} else {
|
|
45993
|
-
await this.#transport?.abort().catch(() => void 0);
|
|
45994
|
-
await Promise.race([active.completion, delay2(this.#closeTimeoutMs)]);
|
|
45995
|
-
if (this.#active === active) {
|
|
45996
|
-
await this.#transport?.close().catch(() => void 0);
|
|
45997
|
-
transportClosed = true;
|
|
45998
|
-
this.#finishFailed(active, invalidState("Claude Code Session closed during active Turn"));
|
|
45999
|
-
}
|
|
46363
|
+
const failures = [];
|
|
46364
|
+
const settle = async (task) => {
|
|
46365
|
+
if (!task)
|
|
46366
|
+
return;
|
|
46367
|
+
const timeout = rejectAfter2(this.#closeTimeoutMs * 4, "Claude Code Session close timed out");
|
|
46368
|
+
try {
|
|
46369
|
+
await Promise.race([task, timeout.promise]);
|
|
46370
|
+
} catch (error52) {
|
|
46371
|
+
failures.push(error52);
|
|
46372
|
+
} finally {
|
|
46373
|
+
timeout.cancel();
|
|
46000
46374
|
}
|
|
46001
|
-
}
|
|
46002
|
-
|
|
46003
|
-
|
|
46375
|
+
};
|
|
46376
|
+
const closingTransport = this.#transport;
|
|
46377
|
+
await settle(closingTransport?.close());
|
|
46378
|
+
await settle(this.#configurationTask ?? void 0);
|
|
46379
|
+
await settle(this.#startupTask?.then(() => void 0, () => void 0));
|
|
46380
|
+
if (this.#transport !== closingTransport)
|
|
46381
|
+
await settle(this.#transport?.close());
|
|
46382
|
+
if (failures.length === 0)
|
|
46383
|
+
await settle(this.#releaseUnusedClaim());
|
|
46384
|
+
const active = this.#active;
|
|
46385
|
+
if (active)
|
|
46386
|
+
this.#finishFailed(active, invalidState("Claude Code Session closed during active Turn"));
|
|
46004
46387
|
this.#phase = "closed";
|
|
46005
46388
|
this.#channel.end();
|
|
46006
46389
|
this.#onClosed();
|
|
46390
|
+
if (failures.length > 0)
|
|
46391
|
+
throw new AggregateError(failures, "Claude Code Session could not stop safely");
|
|
46007
46392
|
}
|
|
46008
|
-
|
|
46393
|
+
#ensureTransport() {
|
|
46394
|
+
if (this.#startupTask)
|
|
46395
|
+
return this.#startupTask;
|
|
46009
46396
|
if (this.#transport)
|
|
46010
|
-
return this.#transport;
|
|
46397
|
+
return Promise.resolve(this.#transport);
|
|
46398
|
+
const task = this.#startTransport();
|
|
46399
|
+
this.#startupTask = task;
|
|
46400
|
+
void task.finally(() => {
|
|
46401
|
+
if (this.#startupTask === task)
|
|
46402
|
+
this.#startupTask = null;
|
|
46403
|
+
}).catch(() => void 0);
|
|
46404
|
+
return task;
|
|
46405
|
+
}
|
|
46406
|
+
async #startTransport() {
|
|
46407
|
+
if (this.#openMode === "create" && isPendingClaudeSession(this.#nativeRef)) {
|
|
46408
|
+
await this.#pendingSessions.claim(this.#nativeRef, this.#cwd);
|
|
46409
|
+
this.#pendingClaimed = true;
|
|
46410
|
+
}
|
|
46411
|
+
if (this.#phase !== "open") {
|
|
46412
|
+
await this.#releaseUnusedClaim();
|
|
46413
|
+
throw new Error("Claude Code Session closed during startup");
|
|
46414
|
+
}
|
|
46011
46415
|
const selectedModel = this.#requestedModel ?? (this.#openMode === "create" ? CLAUDE_DEFAULT_MODEL_REF : void 0);
|
|
46012
46416
|
const model = selectedModel ? decodeClaudeModelRef(selectedModel) : void 0;
|
|
46013
46417
|
const permissionMode = decodeClaudePermissionModeId(this.#requestedPermissionModeId);
|
|
46014
|
-
|
|
46015
|
-
cwd: this.#cwd,
|
|
46016
|
-
sessionId: this.#sessionId,
|
|
46017
|
-
openMode: this.#openMode,
|
|
46018
|
-
...model ? { model } : {},
|
|
46019
|
-
thinkingOptionId: this.#requestedThinkingOptionId,
|
|
46020
|
-
permissionMode,
|
|
46021
|
-
onPermissionModeChanged: (mode) => this.#handlePermissionModeChanged(mode),
|
|
46022
|
-
onFault: () => this.#fault(faultError()),
|
|
46023
|
-
onPlanLimit: (planLimit) => this.#handlePlanLimit(planLimit)
|
|
46024
|
-
});
|
|
46025
|
-
transport.setAutonomousTurnHandler((turn) => this.#handleAutonomousTurn(turn));
|
|
46026
|
-
transport.setIdleTurnHandler({
|
|
46027
|
-
onEvent: (event) => {
|
|
46028
|
-
const active = this.#active;
|
|
46029
|
-
if (active)
|
|
46030
|
-
this.#handleTurnEvent(active, event);
|
|
46031
|
-
},
|
|
46032
|
-
onTerminal: (result) => {
|
|
46033
|
-
const active = this.#active;
|
|
46034
|
-
if (active)
|
|
46035
|
-
this.#finishResult(active, result);
|
|
46036
|
-
}
|
|
46037
|
-
});
|
|
46418
|
+
let transport;
|
|
46038
46419
|
try {
|
|
46420
|
+
transport = this.#createTransport({
|
|
46421
|
+
cwd: this.#cwd,
|
|
46422
|
+
sessionId: this.#sessionId,
|
|
46423
|
+
openMode: this.#openMode,
|
|
46424
|
+
...model ? { model } : {},
|
|
46425
|
+
thinkingOptionId: this.#requestedThinkingOptionId,
|
|
46426
|
+
permissionMode,
|
|
46427
|
+
onPermissionModeChanged: (mode) => this.#handlePermissionModeChanged(mode),
|
|
46428
|
+
onFault: () => this.#fault(faultError()),
|
|
46429
|
+
onPlanLimit: (planLimit) => this.#handlePlanLimit(planLimit)
|
|
46430
|
+
});
|
|
46431
|
+
this.#transport = transport;
|
|
46432
|
+
transport.setAutonomousTurnHandler((turn) => this.#handleAutonomousTurn(turn));
|
|
46433
|
+
transport.setIdleTurnHandler({
|
|
46434
|
+
onEvent: (event) => {
|
|
46435
|
+
const active = this.#active;
|
|
46436
|
+
if (active)
|
|
46437
|
+
this.#handleTurnEvent(active, event);
|
|
46438
|
+
},
|
|
46439
|
+
onTerminal: (result) => {
|
|
46440
|
+
const active = this.#active;
|
|
46441
|
+
if (active)
|
|
46442
|
+
this.#finishResult(active, result);
|
|
46443
|
+
}
|
|
46444
|
+
});
|
|
46039
46445
|
await transport.start();
|
|
46040
46446
|
this.#state = {
|
|
46041
46447
|
...this.#configuredState(true),
|
|
46042
46448
|
effectivePermissionModeId: encodeClaudePermissionModeId(transport.getPermissionMode())
|
|
46043
46449
|
};
|
|
46044
46450
|
} catch (error52) {
|
|
46045
|
-
|
|
46451
|
+
try {
|
|
46452
|
+
await this.#transport?.close();
|
|
46453
|
+
} catch (closeError) {
|
|
46454
|
+
this.#fault(faultError());
|
|
46455
|
+
throw closeError;
|
|
46456
|
+
}
|
|
46457
|
+
this.#transport = null;
|
|
46458
|
+
await this.#releaseUnusedClaim();
|
|
46046
46459
|
throw error52;
|
|
46047
46460
|
}
|
|
46048
46461
|
this.#openMode = "resume";
|
|
46049
46462
|
this.#transport = transport;
|
|
46050
46463
|
return transport;
|
|
46051
46464
|
}
|
|
46465
|
+
async #releaseUnusedClaim() {
|
|
46466
|
+
if (!this.#pendingClaimed || this.#submittedInput)
|
|
46467
|
+
return;
|
|
46468
|
+
await this.#pendingSessions.release(this.#nativeRef, this.#cwd);
|
|
46469
|
+
this.#pendingClaimed = false;
|
|
46470
|
+
this.#openMode = "create";
|
|
46471
|
+
}
|
|
46472
|
+
async #savePendingConfiguration() {
|
|
46473
|
+
if (!isPendingClaudeSession(this.#nativeRef))
|
|
46474
|
+
return null;
|
|
46475
|
+
const configuration = { ...this.#configuredState() };
|
|
46476
|
+
delete configuration.nativeRef;
|
|
46477
|
+
try {
|
|
46478
|
+
await this.#pendingSessions.saveConfiguration(this.#nativeRef, this.#cwd, configuration);
|
|
46479
|
+
return null;
|
|
46480
|
+
} catch {
|
|
46481
|
+
const error52 = {
|
|
46482
|
+
code: "nativeFailure",
|
|
46483
|
+
message: "Claude Code pending configuration could not be persisted",
|
|
46484
|
+
retryable: false
|
|
46485
|
+
};
|
|
46486
|
+
this.#fault(error52);
|
|
46487
|
+
return error52;
|
|
46488
|
+
}
|
|
46489
|
+
}
|
|
46052
46490
|
#configuredState(nativeReady = this.#state.nativeRef !== void 0) {
|
|
46053
46491
|
const effectiveModel = this.#requestedModel ?? (this.#openMode === "create" ? CLAUDE_DEFAULT_MODEL_REF : this.#state.effectiveModel);
|
|
46054
46492
|
return {
|
|
@@ -46494,7 +46932,7 @@ var ClaudeHarnessSession = class {
|
|
|
46494
46932
|
}
|
|
46495
46933
|
}
|
|
46496
46934
|
#finishResult(active, result) {
|
|
46497
|
-
if (this.#active !== active)
|
|
46935
|
+
if (this.#active !== active || this.#hardCancelTask)
|
|
46498
46936
|
return;
|
|
46499
46937
|
if (result.status === "succeeded" && (active.tools.size > 0 || active.subagents.size > 0)) {
|
|
46500
46938
|
this.#finishFailed(active, transportFailure("protocol"));
|
|
@@ -46787,6 +47225,12 @@ var ClaudeHarnessSession = class {
|
|
|
46787
47225
|
checkpointId: active.checkpointId,
|
|
46788
47226
|
formatVersion: 1
|
|
46789
47227
|
}) : null;
|
|
47228
|
+
this.#unpersistedMessageIds = [
|
|
47229
|
+
.../* @__PURE__ */ new Set([
|
|
47230
|
+
...active.nativeTurnRef ? [active.nativeTurnRef.nativeTurnKey] : [],
|
|
47231
|
+
...active.checkpointId ? [active.checkpointId] : []
|
|
47232
|
+
])
|
|
47233
|
+
];
|
|
46790
47234
|
this.#event({
|
|
46791
47235
|
type: "turn.completed",
|
|
46792
47236
|
turnId: active.command.turnId,
|
|
@@ -46825,14 +47269,19 @@ var ClaudeHarnessSession = class {
|
|
|
46825
47269
|
this.#cancelEscalation = null;
|
|
46826
47270
|
}
|
|
46827
47271
|
#hardCancel(active) {
|
|
46828
|
-
if (this.#active !== active)
|
|
47272
|
+
if (this.#active !== active || this.#hardCancelTask)
|
|
46829
47273
|
return;
|
|
46830
47274
|
this.#clearCancelEscalation();
|
|
46831
47275
|
const transport = this.#transport;
|
|
46832
|
-
this.#
|
|
46833
|
-
|
|
46834
|
-
|
|
46835
|
-
|
|
47276
|
+
this.#hardCancelTask = Promise.resolve().then(() => transport?.close()).then(() => {
|
|
47277
|
+
if (this.#phase !== "open" || this.#active !== active)
|
|
47278
|
+
return;
|
|
47279
|
+
this.#transport = null;
|
|
47280
|
+
this.#openMode = "resume";
|
|
47281
|
+
this.#finish(active, { status: "cancelled", reason: "Cancelled by user" });
|
|
47282
|
+
}, () => this.#fault(faultError())).finally(() => {
|
|
47283
|
+
this.#hardCancelTask = null;
|
|
47284
|
+
});
|
|
46836
47285
|
}
|
|
46837
47286
|
#fault(error52) {
|
|
46838
47287
|
if (this.#phase === "closed" || this.#phase === "closing" || this.#phase === "faulted")
|
|
@@ -46851,8 +47300,7 @@ var ClaudeHarnessSession = class {
|
|
|
46851
47300
|
this.#phase = "faulted";
|
|
46852
47301
|
this.#event({ type: "session.faulted", error: error52 });
|
|
46853
47302
|
this.#channel.end();
|
|
46854
|
-
void this.#transport?.close();
|
|
46855
|
-
this.#onClosed();
|
|
47303
|
+
void this.#transport?.close().catch(() => void 0);
|
|
46856
47304
|
}
|
|
46857
47305
|
#event(event) {
|
|
46858
47306
|
this.#channel.emit({ kind: "event", event });
|
|
@@ -46904,6 +47352,7 @@ var ClaudeCodeAdapter = class {
|
|
|
46904
47352
|
#cancelTimeoutMs;
|
|
46905
47353
|
#closeTimeoutMs;
|
|
46906
47354
|
#dependencies;
|
|
47355
|
+
#pendingSessions;
|
|
46907
47356
|
#toolOutputLimit;
|
|
46908
47357
|
#continuationQuiescenceMs;
|
|
46909
47358
|
#inspectionCache = /* @__PURE__ */ new Map();
|
|
@@ -46914,6 +47363,7 @@ var ClaudeCodeAdapter = class {
|
|
|
46914
47363
|
#latestPlanLimit = null;
|
|
46915
47364
|
#accountInspection = null;
|
|
46916
47365
|
constructor(options = {}, dependencies) {
|
|
47366
|
+
this.#pendingSessions = new ClaudePendingSessions(options.environment ?? process.env);
|
|
46917
47367
|
this.#closeTimeoutMs = options.closeTimeoutMs ?? DEFAULT_CLOSE_TIMEOUT_MS;
|
|
46918
47368
|
this.#cancelTimeoutMs = options.cancelTimeoutMs ?? DEFAULT_CANCEL_TIMEOUT_MS;
|
|
46919
47369
|
if (!Number.isSafeInteger(this.#cancelTimeoutMs) || this.#cancelTimeoutMs <= 0) {
|
|
@@ -46928,7 +47378,7 @@ var ClaudeCodeAdapter = class {
|
|
|
46928
47378
|
throw new RangeError("Claude Code continuation quiescence must be a positive safe integer");
|
|
46929
47379
|
}
|
|
46930
47380
|
this.#dependencies = dependencies ?? {
|
|
46931
|
-
randomUUID:
|
|
47381
|
+
randomUUID: randomUUID3,
|
|
46932
47382
|
inspectInstallation: () => {
|
|
46933
47383
|
resolveClaudeCodeExecutable({
|
|
46934
47384
|
...options.command ? { command: options.command } : {},
|
|
@@ -46974,7 +47424,7 @@ var ClaudeCodeAdapter = class {
|
|
|
46974
47424
|
error: invalidState("Claude Code Adapter is closing")
|
|
46975
47425
|
};
|
|
46976
47426
|
}
|
|
46977
|
-
const cwd =
|
|
47427
|
+
const cwd = path10.resolve(input.cwd ?? process.cwd());
|
|
46978
47428
|
if (!input.refresh) {
|
|
46979
47429
|
const cached2 = this.#inspectionCache.get(cwd);
|
|
46980
47430
|
if (cached2)
|
|
@@ -47103,79 +47553,18 @@ var ClaudeCodeAdapter = class {
|
|
|
47103
47553
|
}
|
|
47104
47554
|
};
|
|
47105
47555
|
}
|
|
47106
|
-
|
|
47107
|
-
|
|
47108
|
-
|
|
47109
|
-
|
|
47110
|
-
|
|
47111
|
-
|
|
47112
|
-
|
|
47113
|
-
|
|
47114
|
-
|
|
47115
|
-
retryable: false
|
|
47116
|
-
}
|
|
47117
|
-
};
|
|
47118
|
-
}
|
|
47119
|
-
let sourceSnapshot;
|
|
47120
|
-
try {
|
|
47121
|
-
const messages = await this.#dependencies.readSessionMessages({
|
|
47122
|
-
cwd: path8.resolve(input.cwd),
|
|
47123
|
-
sessionId: sourceRef.data.nativeSessionId
|
|
47124
|
-
});
|
|
47125
|
-
sourceSnapshot = mapClaudeSnapshot(messages, sourceRef.data.nativeSessionId);
|
|
47126
|
-
} catch {
|
|
47127
|
-
return {
|
|
47128
|
-
ok: false,
|
|
47129
|
-
error: {
|
|
47130
|
-
code: "nativeFailure",
|
|
47131
|
-
message: "Claude Code history could not be read",
|
|
47132
|
-
retryable: true
|
|
47133
|
-
}
|
|
47134
|
-
};
|
|
47135
|
-
}
|
|
47136
|
-
if (sourceSnapshot.turns.length === 0) {
|
|
47137
|
-
return {
|
|
47138
|
-
ok: false,
|
|
47139
|
-
error: {
|
|
47140
|
-
code: "invalidState",
|
|
47141
|
-
message: "Claude Code Native Session has no Turn to roll back",
|
|
47142
|
-
retryable: false
|
|
47143
|
-
}
|
|
47144
|
-
};
|
|
47145
|
-
}
|
|
47146
|
-
const retained = sourceSnapshot.turns.at(-2);
|
|
47147
|
-
if (!retained) {
|
|
47148
|
-
rollback = {
|
|
47149
|
-
openMode: "create",
|
|
47150
|
-
sessionId: this.#dependencies.randomUUID()
|
|
47151
|
-
};
|
|
47152
|
-
} else if (!retained.checkpoint?.checkpointId) {
|
|
47153
|
-
return {
|
|
47154
|
-
ok: false,
|
|
47155
|
-
error: {
|
|
47156
|
-
code: "checkpointNotFound",
|
|
47157
|
-
message: "Claude Code last-Turn rollback boundary is unavailable",
|
|
47158
|
-
retryable: false
|
|
47159
|
-
}
|
|
47160
|
-
};
|
|
47161
|
-
} else {
|
|
47162
|
-
const forked2 = await forkClaudeSession({
|
|
47163
|
-
checkpoint: retained.checkpoint,
|
|
47164
|
-
cwd: path8.resolve(input.cwd),
|
|
47165
|
-
dependencies: this.#dependencies,
|
|
47166
|
-
harnessId: this.harnessId,
|
|
47167
|
-
sourceRef: sourceRef.data
|
|
47168
|
-
});
|
|
47169
|
-
if (!forked2.ok)
|
|
47170
|
-
return forked2;
|
|
47171
|
-
rollback = {
|
|
47172
|
-
openMode: "resume",
|
|
47173
|
-
sessionId: forked2.value.sessionId
|
|
47174
|
-
};
|
|
47175
|
-
}
|
|
47556
|
+
if (input.kind === "rollbackLastTurn" && [...this.#sessions].some((session2) => session2.blocksRollback(input.sourceRef.nativeSessionId))) {
|
|
47557
|
+
return {
|
|
47558
|
+
ok: false,
|
|
47559
|
+
error: {
|
|
47560
|
+
code: "sessionBusy",
|
|
47561
|
+
message: "Claude Code Session is busy during rollback",
|
|
47562
|
+
retryable: true
|
|
47563
|
+
}
|
|
47564
|
+
};
|
|
47176
47565
|
}
|
|
47177
47566
|
let requestedThinkingOptionId = CLAUDE_DEFAULT_THINKING_OPTION_ID;
|
|
47178
|
-
if (input.kind === "create" && input.thinkingOptionId) {
|
|
47567
|
+
if ((input.kind === "create" || input.kind === "rollbackLastTurn" || input.kind === "resume") && input.thinkingOptionId) {
|
|
47179
47568
|
try {
|
|
47180
47569
|
requestedThinkingOptionId = parseClaudeThinkingOptionId(input.thinkingOptionId);
|
|
47181
47570
|
} catch {
|
|
@@ -47189,7 +47578,7 @@ var ClaudeCodeAdapter = class {
|
|
|
47189
47578
|
};
|
|
47190
47579
|
}
|
|
47191
47580
|
}
|
|
47192
|
-
if (input.kind === "create" && input.model) {
|
|
47581
|
+
if ((input.kind === "create" || input.kind === "rollbackLastTurn" || input.kind === "resume") && input.model) {
|
|
47193
47582
|
try {
|
|
47194
47583
|
decodeClaudeModelRef(input.model);
|
|
47195
47584
|
} catch {
|
|
@@ -47203,7 +47592,7 @@ var ClaudeCodeAdapter = class {
|
|
|
47203
47592
|
};
|
|
47204
47593
|
}
|
|
47205
47594
|
}
|
|
47206
|
-
|
|
47595
|
+
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;
|
|
47207
47596
|
try {
|
|
47208
47597
|
decodeClaudePermissionModeId(requestedPermissionModeId);
|
|
47209
47598
|
} catch {
|
|
@@ -47216,7 +47605,14 @@ var ClaudeCodeAdapter = class {
|
|
|
47216
47605
|
}
|
|
47217
47606
|
};
|
|
47218
47607
|
}
|
|
47219
|
-
const cwd =
|
|
47608
|
+
const cwd = path10.resolve(input.cwd);
|
|
47609
|
+
if (input.kind === "rollbackLastTurn") {
|
|
47610
|
+
for (const source of this.#sessions) {
|
|
47611
|
+
const ready = await source.prepareRollback(input.sourceRef.nativeSessionId);
|
|
47612
|
+
if (!ready.ok)
|
|
47613
|
+
return ready;
|
|
47614
|
+
}
|
|
47615
|
+
}
|
|
47220
47616
|
const nativeRef = input.kind === "resume" ? nativeSessionRefSchema.safeParse(input.nativeRef) : null;
|
|
47221
47617
|
if (nativeRef && (!nativeRef.success || nativeRef.data.harnessId !== this.harnessId)) {
|
|
47222
47618
|
return {
|
|
@@ -47228,8 +47624,16 @@ var ClaudeCodeAdapter = class {
|
|
|
47228
47624
|
}
|
|
47229
47625
|
};
|
|
47230
47626
|
}
|
|
47231
|
-
const forked = input.kind === "fork" ? await forkClaudeSession({
|
|
47232
|
-
checkpoint: input.checkpoint
|
|
47627
|
+
const forked = input.kind === "fork" || input.kind === "rollbackLastTurn" ? await forkClaudeSession({
|
|
47628
|
+
...input.kind === "fork" ? { kind: "fork", checkpoint: input.checkpoint } : {
|
|
47629
|
+
kind: "rollbackLastTurn",
|
|
47630
|
+
pendingSessions: this.#pendingSessions,
|
|
47631
|
+
configuration: {
|
|
47632
|
+
...input.model ? { effectiveModel: input.model } : {},
|
|
47633
|
+
effectiveThinkingOptionId: requestedThinkingOptionId,
|
|
47634
|
+
effectivePermissionModeId: requestedPermissionModeId
|
|
47635
|
+
}
|
|
47636
|
+
},
|
|
47233
47637
|
cwd,
|
|
47234
47638
|
dependencies: this.#dependencies,
|
|
47235
47639
|
harnessId: this.harnessId,
|
|
@@ -47237,11 +47641,49 @@ var ClaudeCodeAdapter = class {
|
|
|
47237
47641
|
}) : null;
|
|
47238
47642
|
if (forked && !forked.ok)
|
|
47239
47643
|
return forked;
|
|
47644
|
+
const durableRef = forked?.ok ? forked.value.nativeRef : nativeRef?.success ? nativeRef.data : void 0;
|
|
47645
|
+
let openMode = forked?.ok && forked.value.openMode === "create" || input.kind === "create" ? "create" : "resume";
|
|
47646
|
+
let requestedModel = input.kind !== "fork" ? input.model : void 0;
|
|
47647
|
+
if (durableRef && isPendingClaudeSession(durableRef)) {
|
|
47648
|
+
try {
|
|
47649
|
+
const pending = await this.#pendingSessions.read(durableRef, cwd);
|
|
47650
|
+
if (!pending.started) {
|
|
47651
|
+
const messages = await this.#dependencies.readSessionMessages({
|
|
47652
|
+
cwd,
|
|
47653
|
+
sessionId: durableRef.nativeSessionId
|
|
47654
|
+
});
|
|
47655
|
+
if (messages.length > 0 || input.kind === "resume" && input.knownTurnRefs?.length)
|
|
47656
|
+
throw new Error("Pending Session unexpectedly contains history");
|
|
47657
|
+
openMode = "create";
|
|
47658
|
+
}
|
|
47659
|
+
if (pending.configuration.effectiveModel)
|
|
47660
|
+
decodeClaudeModelRef(pending.configuration.effectiveModel);
|
|
47661
|
+
if (pending.configuration.effectiveThinkingOptionId)
|
|
47662
|
+
parseClaudeThinkingOptionId(pending.configuration.effectiveThinkingOptionId);
|
|
47663
|
+
if (pending.configuration.effectivePermissionModeId)
|
|
47664
|
+
decodeClaudePermissionModeId(pending.configuration.effectivePermissionModeId);
|
|
47665
|
+
requestedModel = pending.configuration.effectiveModel ?? requestedModel;
|
|
47666
|
+
requestedThinkingOptionId = pending.configuration.effectiveThinkingOptionId ?? requestedThinkingOptionId;
|
|
47667
|
+
requestedPermissionModeId = input.kind === "resume" && input.permissionModeId ? input.permissionModeId : pending.configuration.effectivePermissionModeId ?? requestedPermissionModeId;
|
|
47668
|
+
} catch {
|
|
47669
|
+
return {
|
|
47670
|
+
ok: false,
|
|
47671
|
+
error: {
|
|
47672
|
+
code: "sessionNotFound",
|
|
47673
|
+
message: "Claude Code pending Session cannot be recovered",
|
|
47674
|
+
retryable: false
|
|
47675
|
+
}
|
|
47676
|
+
};
|
|
47677
|
+
}
|
|
47678
|
+
}
|
|
47240
47679
|
const session = new ClaudeHarnessSession(cwd, this.#dependencies, this.#closeTimeoutMs, () => this.#sessions.delete(session), (planLimit) => this.#recordPlanLimit(session, planLimit), {
|
|
47241
47680
|
...input.environment ? { environment: input.environment } : {},
|
|
47242
|
-
openMode
|
|
47243
|
-
|
|
47244
|
-
|
|
47681
|
+
openMode,
|
|
47682
|
+
pendingSessions: this.#pendingSessions,
|
|
47683
|
+
knownConfiguration: input.kind === "rollbackLastTurn" || input.kind === "resume" && Boolean(input.model || input.thinkingOptionId) || Boolean(durableRef && isPendingClaudeSession(durableRef)),
|
|
47684
|
+
...durableRef ? { nativeRef: durableRef } : {},
|
|
47685
|
+
sessionId: forked?.ok ? forked.value.sessionId : nativeRef?.success ? nativeRef.data.nativeSessionId : this.#dependencies.randomUUID(),
|
|
47686
|
+
...requestedModel ? { requestedModel } : {},
|
|
47245
47687
|
requestedPermissionModeId,
|
|
47246
47688
|
requestedThinkingOptionId,
|
|
47247
47689
|
toolOutputLimit: this.#toolOutputLimit,
|
|
@@ -47284,7 +47726,7 @@ var ClaudeCodeAdapter = class {
|
|
|
47284
47726
|
};
|
|
47285
47727
|
|
|
47286
47728
|
// dist/user-shell-environment.js
|
|
47287
|
-
import
|
|
47729
|
+
import path11 from "node:path";
|
|
47288
47730
|
import { spawnSync } from "node:child_process";
|
|
47289
47731
|
var ENVIRONMENT_MARKER = Buffer.from("\0CODEXHOST_USER_SHELL_ENV_V1\0");
|
|
47290
47732
|
var ENVIRONMENT_COMMAND = "printf '\\0CODEXHOST_USER_SHELL_ENV_V1\\0'; /usr/bin/env -0";
|
|
@@ -47327,7 +47769,7 @@ function withUserShellEnvironment(environment, dependencies) {
|
|
|
47327
47769
|
if (platform === "win32" || !environment.HOME)
|
|
47328
47770
|
return environment;
|
|
47329
47771
|
const shell = environment.SHELL?.trim() || defaultShell(platform);
|
|
47330
|
-
if (!shell || !SUPPORTED_SHELLS.has(
|
|
47772
|
+
if (!shell || !SUPPORTED_SHELLS.has(path11.basename(shell)))
|
|
47331
47773
|
return environment;
|
|
47332
47774
|
const cacheKey = `${platform}\0${shell}\0${environment.HOME}`;
|
|
47333
47775
|
const cached2 = dependencies ? void 0 : shellEnvironmentCache.get(cacheKey);
|