@codexhost/cli-darwin-x64 0.13.3 → 0.15.0

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.
@@ -777,10 +777,10 @@ function mergeDefs(...defs) {
777
777
  function cloneDef(schema) {
778
778
  return mergeDefs(schema._zod.def);
779
779
  }
780
- function getElementAtPath(obj, path19) {
781
- if (!path19)
780
+ function getElementAtPath(obj, path18) {
781
+ if (!path18)
782
782
  return obj;
783
- return path19.reduce((acc, key) => acc?.[key], obj);
783
+ return path18.reduce((acc, key) => acc?.[key], obj);
784
784
  }
785
785
  function promiseAllObject(promisesObj) {
786
786
  const keys = Object.keys(promisesObj);
@@ -1189,11 +1189,11 @@ function explicitlyAborted(x, startIndex = 0) {
1189
1189
  }
1190
1190
  return false;
1191
1191
  }
1192
- function prefixIssues(path19, issues) {
1192
+ function prefixIssues(path18, issues) {
1193
1193
  return issues.map((iss) => {
1194
1194
  var _a4;
1195
1195
  (_a4 = iss).path ?? (_a4.path = []);
1196
- iss.path.unshift(path19);
1196
+ iss.path.unshift(path18);
1197
1197
  return iss;
1198
1198
  });
1199
1199
  }
@@ -1340,16 +1340,16 @@ function flattenError(error52, mapper = (issue2) => issue2.message) {
1340
1340
  }
1341
1341
  function formatError(error52, mapper = (issue2) => issue2.message) {
1342
1342
  const fieldErrors = { _errors: [] };
1343
- const processError = (error53, path19 = []) => {
1343
+ const processError = (error53, path18 = []) => {
1344
1344
  for (const issue2 of error53.issues) {
1345
1345
  if (issue2.code === "invalid_union" && issue2.errors.length) {
1346
- issue2.errors.map((issues) => processError({ issues }, [...path19, ...issue2.path]));
1346
+ issue2.errors.map((issues) => processError({ issues }, [...path18, ...issue2.path]));
1347
1347
  } else if (issue2.code === "invalid_key") {
1348
- processError({ issues: issue2.issues }, [...path19, ...issue2.path]);
1348
+ processError({ issues: issue2.issues }, [...path18, ...issue2.path]);
1349
1349
  } else if (issue2.code === "invalid_element") {
1350
- processError({ issues: issue2.issues }, [...path19, ...issue2.path]);
1350
+ processError({ issues: issue2.issues }, [...path18, ...issue2.path]);
1351
1351
  } else {
1352
- const fullpath = [...path19, ...issue2.path];
1352
+ const fullpath = [...path18, ...issue2.path];
1353
1353
  if (fullpath.length === 0) {
1354
1354
  fieldErrors._errors.push(mapper(issue2));
1355
1355
  } else {
@@ -1376,17 +1376,17 @@ function formatError(error52, mapper = (issue2) => issue2.message) {
1376
1376
  }
1377
1377
  function treeifyError(error52, mapper = (issue2) => issue2.message) {
1378
1378
  const result = { errors: [] };
1379
- const processError = (error53, path19 = []) => {
1379
+ const processError = (error53, path18 = []) => {
1380
1380
  var _a4, _b2;
1381
1381
  for (const issue2 of error53.issues) {
1382
1382
  if (issue2.code === "invalid_union" && issue2.errors.length) {
1383
- issue2.errors.map((issues) => processError({ issues }, [...path19, ...issue2.path]));
1383
+ issue2.errors.map((issues) => processError({ issues }, [...path18, ...issue2.path]));
1384
1384
  } else if (issue2.code === "invalid_key") {
1385
- processError({ issues: issue2.issues }, [...path19, ...issue2.path]);
1385
+ processError({ issues: issue2.issues }, [...path18, ...issue2.path]);
1386
1386
  } else if (issue2.code === "invalid_element") {
1387
- processError({ issues: issue2.issues }, [...path19, ...issue2.path]);
1387
+ processError({ issues: issue2.issues }, [...path18, ...issue2.path]);
1388
1388
  } else {
1389
- const fullpath = [...path19, ...issue2.path];
1389
+ const fullpath = [...path18, ...issue2.path];
1390
1390
  if (fullpath.length === 0) {
1391
1391
  result.errors.push(mapper(issue2));
1392
1392
  continue;
@@ -1418,8 +1418,8 @@ function treeifyError(error52, mapper = (issue2) => issue2.message) {
1418
1418
  }
1419
1419
  function toDotPath(_path) {
1420
1420
  const segs = [];
1421
- const path19 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
1422
- for (const seg of path19) {
1421
+ const path18 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
1422
+ for (const seg of path18) {
1423
1423
  if (typeof seg === "number")
1424
1424
  segs.push(`[${seg}]`);
1425
1425
  else if (typeof seg === "symbol")
@@ -3040,10 +3040,10 @@ var $ZodObject = /* @__PURE__ */ $constructor("$ZodObject", (inst, def) => {
3040
3040
  const shape = def.shape;
3041
3041
  const propValues = {};
3042
3042
  for (const key in shape) {
3043
- const field = shape[key]._zod;
3044
- if (field.values) {
3043
+ const field2 = shape[key]._zod;
3044
+ if (field2.values) {
3045
3045
  propValues[key] ?? (propValues[key] = /* @__PURE__ */ new Set());
3046
- for (const v of field.values)
3046
+ for (const v of field2.values)
3047
3047
  propValues[key].add(v);
3048
3048
  }
3049
3049
  }
@@ -14111,13 +14111,13 @@ function resolveRef(ref, ctx) {
14111
14111
  if (!ref.startsWith("#")) {
14112
14112
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
14113
14113
  }
14114
- const path19 = ref.slice(1).split("/").filter(Boolean);
14115
- if (path19.length === 0) {
14114
+ const path18 = ref.slice(1).split("/").filter(Boolean);
14115
+ if (path18.length === 0) {
14116
14116
  return ctx.rootSchema;
14117
14117
  }
14118
14118
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
14119
- if (path19[0] === defsKey) {
14120
- const key = path19[1];
14119
+ if (path18[0] === defsKey) {
14120
+ const key = path18[1];
14121
14121
  if (!key || !ctx.defs[key]) {
14122
14122
  throw new Error(`Reference not found: ${ref}`);
14123
14123
  }
@@ -14662,10 +14662,19 @@ var model = external_exports.string().min(1).max(512);
14662
14662
  var project = external_exports.string().min(1).max(4096);
14663
14663
  var usageStatisticsParamsSchema = external_exports.strictObject({
14664
14664
  range: external_exports.enum(USAGE_STATISTICS_RANGES),
14665
+ /** Display timezone for ranges, dates and hourly buckets; omitted means the Host's local zone. */
14666
+ timeZone: external_exports.string().min(1).max(128).refine((value) => {
14667
+ try {
14668
+ new Intl.DateTimeFormat("en", { timeZone: value });
14669
+ return true;
14670
+ } catch {
14671
+ return false;
14672
+ }
14673
+ }, "Unsupported usage statistics timezone").optional(),
14665
14674
  harness: harness.optional(),
14666
14675
  model: model.nullable().optional(),
14667
14676
  project: project.nullable().optional(),
14668
- /** One local date inside the range. */
14677
+ /** One date in the query timezone inside the range. */
14669
14678
  date: localDate.optional()
14670
14679
  });
14671
14680
  var usageStatisticsTotalsSchema = external_exports.strictObject({
@@ -14701,7 +14710,7 @@ var usageStatisticsSessionSchema = external_exports.strictObject({
14701
14710
  });
14702
14711
  var usageStatisticsResultSchema = external_exports.strictObject({
14703
14712
  range: external_exports.enum(USAGE_STATISTICS_RANGES),
14704
- /** First local date of the range; null for all time. */
14713
+ /** First date in the query timezone (Host local when omitted); null for all time. */
14705
14714
  from: localDate.nullable(),
14706
14715
  to: localDate,
14707
14716
  /** The filters these figures apply, echoed so a late answer to older filters is recognised. */
@@ -14741,7 +14750,7 @@ var usageStatisticsResultSchema = external_exports.strictObject({
14741
14750
  totals: usageStatisticsTotalsSchema,
14742
14751
  /** Each date and Harness of the range: every filter except the day. */
14743
14752
  daily: external_exports.array(external_exports.strictObject({ date: localDate, harness, ...totals })).max(2e5),
14744
- /** Local weekday (0 = Sunday) and hour, all filters applied. */
14753
+ /** Weekday (0 = Sunday) and hour in the query timezone, all filters applied. */
14745
14754
  hourly: external_exports.array(external_exports.strictObject({
14746
14755
  weekday: external_exports.number().int().min(0).max(6),
14747
14756
  hour: external_exports.number().int().min(0).max(23),
@@ -14781,6 +14790,51 @@ var hostInteractionIdSchema = opaqueIdSchema.brand();
14781
14790
  var threadPrewarmDiscardParamsSchema = external_exports.object({ threadId: hostThreadIdSchema });
14782
14791
  var threadPrewarmDiscardResultSchema = external_exports.object({ discarded: external_exports.boolean() });
14783
14792
 
14793
+ // ../../shared-contracts/dist/thread-questions.js
14794
+ var field = external_exports.discriminatedUnion("type", [
14795
+ external_exports.object({
14796
+ id: external_exports.string().min(1),
14797
+ type: external_exports.literal("choice"),
14798
+ prompt: external_exports.string(),
14799
+ options: external_exports.array(external_exports.object({
14800
+ value: external_exports.string().min(1),
14801
+ label: external_exports.string(),
14802
+ description: external_exports.string().optional()
14803
+ })).min(1),
14804
+ multiple: external_exports.boolean(),
14805
+ allowOther: external_exports.boolean(),
14806
+ optional: external_exports.boolean()
14807
+ }),
14808
+ external_exports.object({
14809
+ id: external_exports.string().min(1),
14810
+ type: external_exports.literal("text"),
14811
+ prompt: external_exports.string(),
14812
+ multiline: external_exports.boolean(),
14813
+ secret: external_exports.literal(false),
14814
+ optional: external_exports.boolean(),
14815
+ placeholder: external_exports.string().optional(),
14816
+ prefill: external_exports.string().optional()
14817
+ })
14818
+ ]);
14819
+ var threadQuestionSchema = external_exports.object({
14820
+ interactionId: external_exports.string().min(1),
14821
+ turnId: external_exports.string().min(1),
14822
+ title: external_exports.string().optional(),
14823
+ questions: external_exports.array(field).min(1)
14824
+ }).refine(({ questions }) => questions.some((q) => q.type === "choice" && q.multiple), {
14825
+ message: "Shared cards require at least one multi-select question"
14826
+ });
14827
+ var threadQuestionsListParamsSchema = external_exports.strictObject({ threadId: external_exports.string().min(1) });
14828
+ var threadQuestionsResultSchema = external_exports.object({ questions: external_exports.array(threadQuestionSchema) });
14829
+ var threadQuestionRespondParamsSchema = external_exports.strictObject({
14830
+ threadId: external_exports.string().min(1),
14831
+ turnId: external_exports.string().min(1),
14832
+ interactionId: external_exports.string().min(1),
14833
+ answers: external_exports.record(external_exports.string(), external_exports.array(external_exports.string())),
14834
+ cancelled: external_exports.boolean().default(false)
14835
+ });
14836
+ var threadQuestionRespondResultSchema = external_exports.object({ accepted: external_exports.literal(true) });
14837
+
14784
14838
  // ../../shared-contracts/dist/console.js
14785
14839
  var consoleAnnouncementSchema = external_exports.strictObject({
14786
14840
  title: external_exports.string().trim().min(1).max(200),
@@ -14801,6 +14855,8 @@ var CONSOLE_HOST_METHODS = Object.freeze([
14801
14855
  "codexhost/harness/display-settings/set",
14802
14856
  "codexhost/harness/inspect",
14803
14857
  "codexhost/harness/installation",
14858
+ "codexhost/harness/installation/start",
14859
+ "codexhost/harness/installation/status",
14804
14860
  "codexhost/harness/launch-settings/get",
14805
14861
  "codexhost/harness/launch-settings/set",
14806
14862
  "codexhost/harness/web-ui/open",
@@ -14876,7 +14932,18 @@ var threadManualCompactionStartedSchema = external_exports.strictObject({
14876
14932
  var nonNegativeSafeIntegerSchema = external_exports.number().int().safe().nonnegative();
14877
14933
  var finiteNonNegativeNumberSchema = external_exports.number().finite().nonnegative();
14878
14934
  var cacheHitRatePercentSchema = external_exports.number().finite().min(0).max(100);
14935
+ var indicatorTextSchema = (maximum) => harnessLocalizedTextSchema.refine((entries) => Object.values(entries).every((text2) => text2.length <= maximum));
14936
+ var composerIndicatorsSchema = external_exports.array(external_exports.object({
14937
+ kind: external_exports.literal("countdown"),
14938
+ id: external_exports.string().min(1).max(64),
14939
+ expiresAtUnix: nonNegativeSafeIntegerSchema,
14940
+ label: indicatorTextSchema(256).optional(),
14941
+ tooltip: indicatorTextSchema(1024).optional()
14942
+ }).strict()).max(2).refine((entries) => new Set(entries.map(({ id: id2 }) => id2)).size === entries.length, {
14943
+ message: "Composer indicator IDs must be unique"
14944
+ });
14879
14945
  var threadUsageSnapshotSchema = external_exports.object({
14946
+ composerIndicators: composerIndicatorsSchema.optional(),
14880
14947
  inputTokens: nonNegativeSafeIntegerSchema.optional(),
14881
14948
  cachedInputTokens: nonNegativeSafeIntegerSchema.optional(),
14882
14949
  cacheWriteInputTokens: nonNegativeSafeIntegerSchema.optional(),
@@ -15284,7 +15351,9 @@ var harnessSessionCapabilitiesSchema = external_exports.object({
15284
15351
  }).strict().optional(),
15285
15352
  autonomousTurns: external_exports.object({
15286
15353
  observe: external_exports.boolean()
15287
- }).strict().optional()
15354
+ }).strict().optional(),
15355
+ /** True only when `turn.steer` delivers input into the active Turn through a native primitive. */
15356
+ steer: external_exports.boolean().optional()
15288
15357
  }).strict();
15289
15358
  var harnessConfigurationStateSchema = external_exports.object({
15290
15359
  effectiveModel: harnessModelRefSchema.optional(),
@@ -15331,7 +15400,9 @@ var harnessInspectionSchema = external_exports.union([
15331
15400
  var harnessInspectParamsSchema = external_exports.object({
15332
15401
  harnessId: harnessIdSchema,
15333
15402
  cwd: nonBlankTextSchema2.max(16384).optional(),
15334
- refresh: external_exports.boolean().optional()
15403
+ refresh: external_exports.boolean().optional(),
15404
+ /** `availability` asks only whether the Harness can run; see `InspectHarnessInput.purpose`. */
15405
+ purpose: external_exports.literal("availability").optional()
15335
15406
  }).strict();
15336
15407
  var harnessWebUiOpenParamsSchema = external_exports.object({
15337
15408
  harnessId: harnessIdSchema
@@ -15414,6 +15485,15 @@ var threadOwnershipListResultSchema = external_exports.object({
15414
15485
  seen.add(thread.threadId);
15415
15486
  }
15416
15487
  });
15488
+ var threadSteeringInspectParamsSchema = external_exports.object({
15489
+ threadId: hostThreadIdSchema,
15490
+ /** The text about to be steered; a Harness command always stops and restarts. */
15491
+ text: external_exports.string().optional()
15492
+ }).strict();
15493
+ var threadSteerDeliverySchema = external_exports.enum(["activeTurn", "newTurn"]);
15494
+ var threadSteeringInspectResultSchema = external_exports.object({
15495
+ delivery: external_exports.enum(["official", "activeTurn", "newTurn"])
15496
+ }).strict();
15417
15497
 
15418
15498
  // ../../shared-contracts/dist/harness-plugins.js
15419
15499
  var HARNESS_PLUGIN_MANIFEST_MAX_BYTES = 32 * 1024;
@@ -15515,6 +15595,10 @@ var harnessInstallationStateSchema = external_exports.object({
15515
15595
  latestVersion: external_exports.string().min(1).max(128),
15516
15596
  updateAvailable: external_exports.boolean(),
15517
15597
  canUpdate: external_exports.boolean(),
15598
+ /** Defaults to CLI; some Harnesses ship only inside a desktop application. */
15599
+ versionKind: external_exports.enum(["cli", "application"]).optional(),
15600
+ /** Official download opened by the user; does not imply an automatic installation. */
15601
+ manualUpdateUrl: external_exports.url().max(2048).refine((value) => /^https:\/\/[^/?#@]+(?:[/?#]|$)/iu.test(value), "Manual updates require a credential-free HTTPS URL").optional(),
15518
15602
  // Adapter-owned diagnostic text; UI uses messageCode rather than displaying it verbatim.
15519
15603
  message: external_exports.string().max(2048).optional(),
15520
15604
  messageCode: external_exports.string().min(1).max(128).optional(),
@@ -15522,6 +15606,20 @@ var harnessInstallationStateSchema = external_exports.object({
15522
15606
  notice: harnessLocalizedTextSchema.optional(),
15523
15607
  latestVersionKind: external_exports.enum(["unknown", "tracking-branch"]).optional()
15524
15608
  }).strict();
15609
+ var harnessInstallationTaskParamsSchema = external_exports.object({ taskId: external_exports.string().uuid() }).strict();
15610
+ var harnessInstallationTaskSchema = external_exports.discriminatedUnion("status", [
15611
+ external_exports.object({ taskId: external_exports.string().uuid(), status: external_exports.literal("running") }).strict(),
15612
+ external_exports.object({
15613
+ taskId: external_exports.string().uuid(),
15614
+ status: external_exports.literal("succeeded"),
15615
+ result: harnessInstallationStateSchema
15616
+ }).strict(),
15617
+ external_exports.object({
15618
+ taskId: external_exports.string().uuid(),
15619
+ status: external_exports.literal("failed"),
15620
+ error: external_exports.object({ code: external_exports.number().int(), message: external_exports.string().min(1).max(2048) }).strict()
15621
+ }).strict()
15622
+ ]);
15525
15623
 
15526
15624
  // ../../shared-contracts/dist/codex-accounts.js
15527
15625
  var accountIdSchema = external_exports.string().min(1).max(256).regex(/^[A-Za-z0-9._~-]+$/u);
@@ -16034,6 +16132,7 @@ var usageFields = /* @__PURE__ */ new Set([
16034
16132
  ...safeIntegerFields,
16035
16133
  ...percentFields,
16036
16134
  "sessionCacheUsage",
16135
+ "composerIndicators",
16037
16136
  "totalCostUsd",
16038
16137
  "totalCredits",
16039
16138
  "contextUsagePercent",
@@ -16056,26 +16155,27 @@ function parseHostUsage(value) {
16056
16155
  throw new Error(`Harness Usage contains unknown field '${key}'`);
16057
16156
  }
16058
16157
  }
16059
- for (const field of [
16158
+ const indicators = value.composerIndicators === void 0 ? {} : { composerIndicators: composerIndicatorsSchema.parse(value.composerIndicators) };
16159
+ for (const field2 of [
16060
16160
  "totalCredits",
16061
16161
  "contextUsagePercent",
16062
16162
  "apiOutputTokensPerSecond"
16063
16163
  ]) {
16064
- const candidate = value[field];
16164
+ const candidate = value[field2];
16065
16165
  if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isFinite(candidate) || candidate < 0)) {
16066
- throw new Error(`Harness Usage '${field}' must be a finite non-negative number`);
16166
+ throw new Error(`Harness Usage '${field2}' must be a finite non-negative number`);
16067
16167
  }
16068
16168
  }
16069
- for (const field of tokenFields) {
16070
- const candidate = value[field];
16169
+ for (const field2 of tokenFields) {
16170
+ const candidate = value[field2];
16071
16171
  if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isSafeInteger(candidate) || candidate < 0)) {
16072
- throw new Error(`Harness Usage '${field}' must be a non-negative safe integer`);
16172
+ throw new Error(`Harness Usage '${field2}' must be a non-negative safe integer`);
16073
16173
  }
16074
16174
  }
16075
- for (const field of safeIntegerFields) {
16076
- const candidate = value[field];
16175
+ for (const field2 of safeIntegerFields) {
16176
+ const candidate = value[field2];
16077
16177
  if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isSafeInteger(candidate) || candidate < 0)) {
16078
- throw new Error(`Harness Usage '${field}' must be a non-negative safe integer`);
16178
+ throw new Error(`Harness Usage '${field2}' must be a non-negative safe integer`);
16079
16179
  }
16080
16180
  }
16081
16181
  if (value.outputTokensPerSecond !== void 0 && (typeof value.outputTokensPerSecond !== "number" || !Number.isFinite(value.outputTokensPerSecond) || value.outputTokensPerSecond < 0)) {
@@ -16084,10 +16184,10 @@ function parseHostUsage(value) {
16084
16184
  if (value.totalCostUsd !== void 0 && (typeof value.totalCostUsd !== "number" || !Number.isFinite(value.totalCostUsd) || value.totalCostUsd < 0)) {
16085
16185
  throw new Error("Harness Usage 'totalCostUsd' must be a finite non-negative number");
16086
16186
  }
16087
- for (const field of percentFields) {
16088
- const candidate = value[field];
16187
+ for (const field2 of percentFields) {
16188
+ const candidate = value[field2];
16089
16189
  if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isFinite(candidate) || candidate < 0 || candidate > 100)) {
16090
- throw new Error(`Harness Usage '${field}' must be between 0 and 100`);
16190
+ throw new Error(`Harness Usage '${field2}' must be between 0 and 100`);
16091
16191
  }
16092
16192
  }
16093
16193
  if (value.sessionCacheUsage !== void 0) {
@@ -16126,9 +16226,9 @@ function parseHostUsage(value) {
16126
16226
  if (value.costSource !== "publicPrice") {
16127
16227
  throw new Error("Harness Usage 'unpricedModels' must be provided with a 'publicPrice' cost");
16128
16228
  }
16129
- return { ...value, unpricedModels: [...models] };
16229
+ return { ...value, ...indicators, unpricedModels: [...models] };
16130
16230
  }
16131
- return { ...value };
16231
+ return { ...value, ...indicators };
16132
16232
  }
16133
16233
  var requestTokenFields = [
16134
16234
  "inputTokens",
@@ -16158,19 +16258,19 @@ function parseHostUsageRequest(value) {
16158
16258
  if (typeof value.requestId !== "string" || value.requestId.length === 0) {
16159
16259
  throw new Error("Harness Usage request 'requestId' must be a non-empty string");
16160
16260
  }
16161
- for (const field of ["model", "provider"]) {
16162
- const candidate = value[field];
16261
+ for (const field2 of ["model", "provider"]) {
16262
+ const candidate = value[field2];
16163
16263
  if (candidate !== void 0 && (typeof candidate !== "string" || candidate.length === 0)) {
16164
- throw new Error(`Harness Usage request '${field}' must be a non-empty string`);
16264
+ throw new Error(`Harness Usage request '${field2}' must be a non-empty string`);
16165
16265
  }
16166
16266
  }
16167
16267
  if (value.historical !== void 0 && typeof value.historical !== "boolean") {
16168
16268
  throw new Error("Harness Usage request 'historical' must be a boolean");
16169
16269
  }
16170
- for (const field of requestTokenFields) {
16171
- const candidate = value[field];
16270
+ for (const field2 of requestTokenFields) {
16271
+ const candidate = value[field2];
16172
16272
  if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isSafeInteger(candidate) || candidate < 0)) {
16173
- throw new Error(`Harness Usage request '${field}' must be a non-negative safe integer`);
16273
+ throw new Error(`Harness Usage request '${field2}' must be a non-negative safe integer`);
16174
16274
  }
16175
16275
  }
16176
16276
  if (value.inputTokens === void 0 || value.outputTokens === void 0) {
@@ -16318,6 +16418,7 @@ var HARNESS_BROKER_PROTOCOL_VERSION = 1;
16318
16418
  var HARNESS_BROKER_MAX_FRAME_BYTES = 8 * 1024 * 1024;
16319
16419
  var HARNESS_BROKER_MAX_PENDING_REQUESTS = 32;
16320
16420
  var HARNESS_BROKER_REQUEST_TIMEOUT_MS = 15e3;
16421
+ var HARNESS_BROKER_SESSION_IMPORT_PAGE_SIZE = 100;
16321
16422
  var HARNESS_BROKER_IDLE_TIMEOUT_MS = 60 * 60 * 1e3;
16322
16423
  var HARNESS_BROKER_RETIRING_ERROR_CODE = "brokerRetiring";
16323
16424
  var harnessBrokerMethodSchema = external_exports.enum([
@@ -16325,8 +16426,11 @@ var harnessBrokerMethodSchema = external_exports.enum([
16325
16426
  "adapter.inspectAccount",
16326
16427
  "adapter.credits",
16327
16428
  "adapter.open",
16429
+ "adapter.sessionImport.list",
16430
+ "adapter.sessionImport.resolve",
16328
16431
  "adapter.subagent.readSnapshot",
16329
16432
  "session.readSnapshot",
16433
+ "session.readCapabilities",
16330
16434
  "session.refreshUsage",
16331
16435
  "session.execute",
16332
16436
  "session.commands.list",
@@ -16426,30 +16530,6 @@ function consumeBrokerFrames(socket, onFrame, onError) {
16426
16530
  });
16427
16531
  }
16428
16532
 
16429
- // ../../harness-broker/dist/paths.js
16430
- import os from "node:os";
16431
- import path from "node:path";
16432
- var HARNESS_BROKER_DESCRIPTOR_ENV = "CODEXHOST_CLAUDE_BROKER_DESCRIPTOR";
16433
- var HARNESS_BROKER_DESCRIPTOR_FILE = "claude-code-broker-v1.json";
16434
- function defaultHarnessBrokerDirectory(environment = process.env) {
16435
- const home = environment.HOME || os.homedir();
16436
- return path.join(home, ".codexhost", "harness-broker");
16437
- }
16438
- function defaultHarnessBrokerDescriptorPath(environment = process.env, harnessId = "claude-code") {
16439
- harnessPluginIdSchema.parse(harnessId);
16440
- if (harnessId !== "claude-code")
16441
- return path.join(defaultHarnessBrokerDirectory(environment), `${harnessId}-broker-v1.json`);
16442
- return environment[HARNESS_BROKER_DESCRIPTOR_ENV] ?? path.join(defaultHarnessBrokerDirectory(environment), HARNESS_BROKER_DESCRIPTOR_FILE);
16443
- }
16444
- function harnessBrokerLaunchAgentLabel(harnessId = "claude-code") {
16445
- harnessPluginIdSchema.parse(harnessId);
16446
- return harnessId === "claude-code" ? "ai.bytepioneer.codexhost.native-harness-broker" : `ai.bytepioneer.codexhost.${harnessId}-broker`;
16447
- }
16448
- function harnessBrokerLaunchAgentPlistPath(environment = process.env, harnessId = "claude-code") {
16449
- const home = environment.HOME || os.homedir();
16450
- return path.join(home, "Library", "LaunchAgents", `${harnessBrokerLaunchAgentLabel(harnessId)}.plist`);
16451
- }
16452
-
16453
16533
  // ../../harness-broker/dist/validation.js
16454
16534
  var cwdSchema = external_exports.string().min(1).max(16384);
16455
16535
  var brokerEnvironmentSchema = external_exports.object({
@@ -16500,13 +16580,42 @@ var brokerOpenInputSchema = external_exports.discriminatedUnion("kind", [
16500
16580
  forkSchema,
16501
16581
  rollbackSchema
16502
16582
  ]);
16503
- var brokerInspectInputSchema = external_exports.object({ cwd: cwdSchema.optional(), refresh: external_exports.boolean().optional() }).strict();
16583
+ var brokerInspectInputSchema = external_exports.object({
16584
+ cwd: cwdSchema.optional(),
16585
+ refresh: external_exports.boolean().optional(),
16586
+ purpose: external_exports.literal("availability").optional()
16587
+ }).strict();
16588
+ var brokerSessionImportListParamsSchema = external_exports.object({
16589
+ offset: external_exports.number().int().nonnegative().safe(),
16590
+ limit: external_exports.number().int().min(1).max(HARNESS_BROKER_SESSION_IMPORT_PAGE_SIZE)
16591
+ }).strict();
16592
+ var brokerSessionImportResolveParamsSchema = external_exports.object({ nativeSessionId: harnessSessionImportIdSchema }).strict();
16593
+ var brokerSessionImportPageSchema = external_exports.object({
16594
+ candidates: external_exports.array(harnessSessionImportCandidateSchema).max(HARNESS_BROKER_SESSION_IMPORT_PAGE_SIZE),
16595
+ total: external_exports.number().int().nonnegative().safe()
16596
+ }).strict();
16597
+ var brokerSessionImportSourceSchema = external_exports.object({
16598
+ candidate: harnessSessionImportCandidateSchema,
16599
+ nativeRef: nativeSessionRefSchema
16600
+ }).strict().superRefine((source, context) => {
16601
+ if (source.nativeRef.nativeSessionId !== source.candidate.nativeSessionId) {
16602
+ context.addIssue({
16603
+ code: "custom",
16604
+ message: "Session import source identity does not match"
16605
+ });
16606
+ }
16607
+ });
16504
16608
  var textInputSchema = external_exports.object({ type: external_exports.literal("text"), text: external_exports.string().max(4e6) }).strict();
16505
16609
  var turnStartSchema = external_exports.object({
16506
16610
  type: external_exports.literal("turn.start"),
16507
16611
  turnId: hostTurnIdSchema,
16508
16612
  input: external_exports.array(textInputSchema)
16509
16613
  }).strict();
16614
+ var turnSteerSchema = external_exports.object({
16615
+ type: external_exports.literal("turn.steer"),
16616
+ turnId: hostTurnIdSchema,
16617
+ input: external_exports.array(textInputSchema)
16618
+ }).strict();
16510
16619
  var turnCancelSchema = external_exports.object({ type: external_exports.literal("turn.cancel"), turnId: hostTurnIdSchema }).strict();
16511
16620
  var interactionResponseSchema = external_exports.union([
16512
16621
  external_exports.object({
@@ -16532,6 +16641,7 @@ var permissionSelectSchema = external_exports.object({
16532
16641
  }).strict();
16533
16642
  var brokerHostCommandSchema = external_exports.discriminatedUnion("type", [
16534
16643
  turnStartSchema,
16644
+ turnSteerSchema,
16535
16645
  turnCancelSchema,
16536
16646
  interactionRespondSchema,
16537
16647
  modelSelectSchema,
@@ -16665,6 +16775,107 @@ var harnessOutputSchema = external_exports.custom((value) => {
16665
16775
  return false;
16666
16776
  });
16667
16777
 
16778
+ // ../../harness-broker/dist/session-import-client.js
16779
+ function createBrokerSessionImportCapability(input) {
16780
+ let listing = null;
16781
+ const closed = () => ({
16782
+ ok: false,
16783
+ error: { code: "invalidState", message: "Harness broker adapter is closed", retryable: false }
16784
+ });
16785
+ const invalid = () => ({
16786
+ ok: false,
16787
+ error: {
16788
+ code: "protocolError",
16789
+ message: "Harness broker returned invalid Session import metadata",
16790
+ retryable: false
16791
+ }
16792
+ });
16793
+ const list = async () => {
16794
+ try {
16795
+ const candidates = [];
16796
+ const identities = /* @__PURE__ */ new Set();
16797
+ let total;
16798
+ for (; ; ) {
16799
+ if (input.isClosed())
16800
+ return closed();
16801
+ const result = await input.request("adapter.sessionImport.list", {
16802
+ offset: candidates.length,
16803
+ limit: HARNESS_BROKER_SESSION_IMPORT_PAGE_SIZE
16804
+ });
16805
+ if (input.isClosed())
16806
+ return closed();
16807
+ if (!result.ok)
16808
+ return result;
16809
+ const page = brokerSessionImportPageSchema.safeParse(result.value);
16810
+ if (!page.success || total !== void 0 && total !== page.data.total || page.data.total < candidates.length + page.data.candidates.length || page.data.candidates.length === 0 && candidates.length < page.data.total)
16811
+ return invalid();
16812
+ total = page.data.total;
16813
+ for (const candidate of page.data.candidates) {
16814
+ if (identities.has(candidate.nativeSessionId))
16815
+ return invalid();
16816
+ identities.add(candidate.nativeSessionId);
16817
+ candidates.push(candidate);
16818
+ }
16819
+ if (candidates.length === total)
16820
+ return { ok: true, value: candidates };
16821
+ }
16822
+ } catch (error52) {
16823
+ return { ok: false, error: input.error(error52) };
16824
+ }
16825
+ };
16826
+ return {
16827
+ listCandidates() {
16828
+ if (input.isClosed())
16829
+ return Promise.resolve(closed());
16830
+ listing ??= list().finally(() => {
16831
+ listing = null;
16832
+ });
16833
+ return listing;
16834
+ },
16835
+ async resolveCandidate(nativeSessionId) {
16836
+ if (input.isClosed())
16837
+ return closed();
16838
+ try {
16839
+ const result = await input.request("adapter.sessionImport.resolve", { nativeSessionId });
16840
+ if (input.isClosed())
16841
+ return closed();
16842
+ if (!result.ok)
16843
+ return result;
16844
+ const source = brokerSessionImportSourceSchema.safeParse(result.value);
16845
+ if (!source.success || source.data.nativeRef.harnessId !== input.harnessId || source.data.candidate.nativeSessionId !== nativeSessionId)
16846
+ return invalid();
16847
+ return { ok: true, value: source.data };
16848
+ } catch (error52) {
16849
+ return { ok: false, error: input.error(error52) };
16850
+ }
16851
+ }
16852
+ };
16853
+ }
16854
+
16855
+ // ../../harness-broker/dist/paths.js
16856
+ import os from "node:os";
16857
+ import path from "node:path";
16858
+ var HARNESS_BROKER_DESCRIPTOR_ENV = "CODEXHOST_CLAUDE_BROKER_DESCRIPTOR";
16859
+ var HARNESS_BROKER_DESCRIPTOR_FILE = "claude-code-broker-v1.json";
16860
+ function defaultHarnessBrokerDirectory(environment = process.env) {
16861
+ const home = environment.HOME || os.homedir();
16862
+ return path.join(home, ".codexhost", "harness-broker");
16863
+ }
16864
+ function defaultHarnessBrokerDescriptorPath(environment = process.env, harnessId = "claude-code") {
16865
+ harnessPluginIdSchema.parse(harnessId);
16866
+ if (harnessId !== "claude-code")
16867
+ return path.join(defaultHarnessBrokerDirectory(environment), `${harnessId}-broker-v1.json`);
16868
+ return environment[HARNESS_BROKER_DESCRIPTOR_ENV] ?? path.join(defaultHarnessBrokerDirectory(environment), HARNESS_BROKER_DESCRIPTOR_FILE);
16869
+ }
16870
+ function harnessBrokerLaunchAgentLabel(harnessId = "claude-code") {
16871
+ harnessPluginIdSchema.parse(harnessId);
16872
+ return harnessId === "claude-code" ? "ai.bytepioneer.codexhost.native-harness-broker" : `ai.bytepioneer.codexhost.${harnessId}-broker`;
16873
+ }
16874
+ function harnessBrokerLaunchAgentPlistPath(environment = process.env, harnessId = "claude-code") {
16875
+ const home = environment.HOME || os.homedir();
16876
+ return path.join(home, "Library", "LaunchAgents", `${harnessBrokerLaunchAgentLabel(harnessId)}.plist`);
16877
+ }
16878
+
16668
16879
  // ../../harness-broker/dist/client.js
16669
16880
  function unavailable(message, retryable = true) {
16670
16881
  return { code: "unavailable", message, retryable, stage: "harnessBroker" };
@@ -16724,6 +16935,7 @@ function parseSessionMetadata(value) {
16724
16935
  sessionId: candidate.sessionId,
16725
16936
  sessionGeneration: candidate.sessionGeneration,
16726
16937
  capabilities: harnessSessionCapabilitiesSchema.parse(candidate.capabilities),
16938
+ readCapabilities: candidate.readCapabilities === true,
16727
16939
  initialState: state,
16728
16940
  initialUsage: candidate.initialUsage === null ? null : parseHostUsage(candidate.initialUsage),
16729
16941
  commands: candidate.commands === true
@@ -17075,6 +17287,11 @@ var BrokeredHarnessSession = class {
17075
17287
  event: { type: "session.faulted", error: unavailable(error52.message) }
17076
17288
  });
17077
17289
  }
17290
+ async readCapabilities() {
17291
+ if (!this.#metadata.readCapabilities)
17292
+ return { ...this.capabilities, steer: false };
17293
+ return harnessSessionCapabilitiesSchema.parse(await this.#request("session.readCapabilities", {}));
17294
+ }
17078
17295
  async refreshUsage() {
17079
17296
  await this.#request("session.refreshUsage", {});
17080
17297
  }
@@ -17106,6 +17323,8 @@ var BrokeredHarnessSession = class {
17106
17323
  try {
17107
17324
  return parseHarnessResult(await this.#request("session.execute", { command }));
17108
17325
  } catch (error52) {
17326
+ if (command.type === "turn.steer")
17327
+ throw error52;
17109
17328
  return {
17110
17329
  ok: false,
17111
17330
  error: unavailable(error52 instanceof Error ? error52.message : String(error52))
@@ -17193,6 +17412,7 @@ var BrokeredHarnessAdapter = class {
17193
17412
  commandCatalog;
17194
17413
  liveCommandCatalog;
17195
17414
  harnessId;
17415
+ sessionImport;
17196
17416
  credits;
17197
17417
  refreshCredits;
17198
17418
  #descriptorPath;
@@ -17215,6 +17435,14 @@ var BrokeredHarnessAdapter = class {
17215
17435
  };
17216
17436
  constructor(input = {}) {
17217
17437
  this.harnessId = harnessPluginIdSchema.parse(input.harnessId ?? "claude-code");
17438
+ if (input.sessionImport) {
17439
+ this.sessionImport = createBrokerSessionImportCapability({
17440
+ harnessId: this.harnessId,
17441
+ request: async (method, params) => parseHarnessResult(await this.#request(method, params, method === "adapter.sessionImport.resolve")),
17442
+ isClosed: () => this.#closed,
17443
+ error: (error52) => this.#error(error52)
17444
+ });
17445
+ }
17218
17446
  if (input.accountCredits !== false) {
17219
17447
  this.credits = () => this.#credits;
17220
17448
  this.refreshCredits = () => this.#refreshAccountCredits();
@@ -17492,10 +17720,13 @@ function usageSessionTitle(value) {
17492
17720
  return void 0;
17493
17721
  if (normalized.length <= MAX_SESSION_TITLE_LENGTH)
17494
17722
  return normalized;
17495
- const characters = [...normalized];
17496
- if (characters.length <= MAX_SESSION_TITLE_LENGTH)
17497
- return normalized;
17498
- return `${characters.slice(0, MAX_SESSION_TITLE_LENGTH - 1).join("").trimEnd()}…`;
17723
+ let title = "";
17724
+ for (const character of normalized) {
17725
+ if (title.length + character.length >= MAX_SESSION_TITLE_LENGTH)
17726
+ break;
17727
+ title += character;
17728
+ }
17729
+ return `${title.trimEnd()}…`;
17499
17730
  }
17500
17731
  function sessionIdOk(value) {
17501
17732
  return typeof value === "string" && value.length > 0 && value.length <= MAX_SESSION_ID_LENGTH;
@@ -17648,9 +17879,34 @@ function createClaudeUsageStatistics(environment) {
17648
17879
  });
17649
17880
  }
17650
17881
 
17882
+ // dist/claude-prompt-cache.js
17883
+ function lastClaudeAssistantResponseUnix(messages) {
17884
+ let latest;
17885
+ for (const entry of messages) {
17886
+ if (typeof entry !== "object" || entry === null || !("type" in entry) || entry.type !== "assistant" || "isSidechain" in entry && entry.isSidechain === true || "parent_tool_use_id" in entry && entry.parent_tool_use_id != null || !("timestamp" in entry) || typeof entry.timestamp !== "string")
17887
+ continue;
17888
+ const time3 = Math.floor(Date.parse(entry.timestamp) / 1e3);
17889
+ if (Number.isSafeInteger(time3) && time3 >= 0)
17890
+ latest = Math.max(latest ?? 0, time3);
17891
+ }
17892
+ return latest;
17893
+ }
17894
+ function claudePromptCacheIndicators(accountCreditsSupported, lastResponseAtUnix) {
17895
+ if (!accountCreditsSupported || lastResponseAtUnix === void 0)
17896
+ return [];
17897
+ return [
17898
+ {
17899
+ kind: "countdown",
17900
+ id: "prompt-cache",
17901
+ expiresAtUnix: lastResponseAtUnix + 3600,
17902
+ label: { en: "Prompt cache", "zh-CN": "提示词缓存" }
17903
+ }
17904
+ ];
17905
+ }
17906
+
17651
17907
  // dist/claude-code-adapter.js
17652
17908
  import { randomUUID as randomUUID5 } from "node:crypto";
17653
- import path16 from "node:path";
17909
+ import path15 from "node:path";
17654
17910
 
17655
17911
  // ../../../node_modules/@anthropic-ai/claude-agent-sdk/sdk.mjs
17656
17912
  import { createRequire as jre } from "node:module";
@@ -54290,7 +54546,6 @@ var ClaudePendingSessions = class {
54290
54546
  };
54291
54547
 
54292
54548
  // dist/claude-fork.js
54293
- import path12 from "node:path";
54294
54549
  import { isDeepStrictEqual } from "node:util";
54295
54550
 
54296
54551
  // dist/file-change.js
@@ -54432,6 +54687,17 @@ function targetedSubagentId(argumentsValue) {
54432
54687
  return void 0;
54433
54688
  return boundedString(argumentsValue.to ?? argumentsValue.recipient ?? argumentsValue.agentId, SUBAGENT_DESCRIPTION_LIMIT);
54434
54689
  }
54690
+ function claudeSendMessageFailed(nativeResult, outputText) {
54691
+ if (isRecord7(nativeResult) && typeof nativeResult.success === "boolean") {
54692
+ return nativeResult.success === false;
54693
+ }
54694
+ try {
54695
+ const parsed = JSON.parse(outputText ?? "");
54696
+ return isRecord7(parsed) && parsed.success === false;
54697
+ } catch {
54698
+ return false;
54699
+ }
54700
+ }
54435
54701
  function includesAuthenticationFailure(errors) {
54436
54702
  return errors.some((error52) => AUTHENTICATION_ERRORS.has(error52));
54437
54703
  }
@@ -54448,11 +54714,20 @@ function parseResultModelUsage(value) {
54448
54714
  if (!isRecord7(value))
54449
54715
  return void 0;
54450
54716
  const usage = [];
54451
- for (const entry of Object.values(value)) {
54717
+ for (const [model2, entry] of Object.entries(value)) {
54452
54718
  if (!isRecord7(entry) || !safeNonNegativeInteger(entry.inputTokens) || !safeNonNegativeInteger(entry.outputTokens)) {
54453
54719
  return void 0;
54454
54720
  }
54455
- usage.push({ inputTokens: entry.inputTokens, outputTokens: entry.outputTokens });
54721
+ const cacheRead = safeNonNegativeInteger(entry.cacheReadInputTokens) ? entry.cacheReadInputTokens : 0;
54722
+ const cacheWrite = safeNonNegativeInteger(entry.cacheCreationInputTokens) ? entry.cacheCreationInputTokens : 0;
54723
+ const promptTokens = entry.inputTokens + cacheRead + cacheWrite;
54724
+ usage.push({
54725
+ model: model2,
54726
+ inputTokens: entry.inputTokens,
54727
+ outputTokens: entry.outputTokens,
54728
+ ...Number.isSafeInteger(promptTokens) ? { promptTokens } : {},
54729
+ ...safeNonNegativeInteger(entry.contextWindow) && entry.contextWindow > 0 ? { contextWindowTokens: entry.contextWindow } : {}
54730
+ });
54456
54731
  }
54457
54732
  return usage;
54458
54733
  }
@@ -54803,6 +55078,7 @@ var ClaudeNativeTurnAccumulator = class {
54803
55078
  events.push({
54804
55079
  type: "message.completed",
54805
55080
  messageId,
55081
+ localCommand: true,
54806
55082
  ...checkpointId ? { checkpointId } : {}
54807
55083
  });
54808
55084
  }
@@ -55152,7 +55428,7 @@ var ClaudeNativeTurnAccumulator = class {
55152
55428
  events.push({
55153
55429
  type: "subagent.completed",
55154
55430
  callId,
55155
- isError,
55431
+ isError: isError || tool.name === "SendMessage" && claudeSendMessageFailed(nativeResult, outputText),
55156
55432
  ...subagentContinuesInBackground(nativeResult, outputText) ? { continuesInBackground: true } : {},
55157
55433
  ...agentId ? { nativeSubagentId: agentId } : {},
55158
55434
  ...resultSummary ? { resultSummary } : {}
@@ -55283,6 +55559,10 @@ function conversationMessages(values, sessionId) {
55283
55559
  const messages = [];
55284
55560
  const ids = /* @__PURE__ */ new Set();
55285
55561
  let promptId = null;
55562
+ const occupancy = new ClaudeBackgroundOccupancy();
55563
+ let accumulator = new ClaudeNativeTurnAccumulator();
55564
+ const sends = /* @__PURE__ */ new Map();
55565
+ let pendingNotification = false;
55286
55566
  for (const value of values) {
55287
55567
  if (!isRecord8(value))
55288
55568
  throw new Error("Claude history contains a malformed message");
@@ -55301,8 +55581,48 @@ function conversationMessages(values, sessionId) {
55301
55581
  message: value.message,
55302
55582
  nested: typeof value.parent_tool_use_id === "string" && value.parent_tool_use_id.length > 0,
55303
55583
  interrupted,
55584
+ startsTurn: false,
55304
55585
  syntheticUser: value.type === "user" && (interrupted || value.isSynthetic === true || value.isMeta === true || isTaskNotificationOrigin(value) || value.toolUseResult !== void 0 && value.toolUseResult !== null)
55305
55586
  };
55587
+ const notification = message.type === "user" && !message.nested && (isTaskNotificationOrigin(value) || textParts(message.message.content).some(isTaskNotificationRecord));
55588
+ message.startsTurn = isHumanUser(message) || notification && !occupancy.unsettled && !pendingNotification;
55589
+ if (message.startsTurn) {
55590
+ occupancy.clear();
55591
+ sends.clear();
55592
+ accumulator = new ClaudeNativeTurnAccumulator();
55593
+ }
55594
+ for (const event of accumulator.consume(value).events) {
55595
+ if (event.type === "subagent.started") {
55596
+ if (event.operation === "send") {
55597
+ sends.set(event.callId, event.nativeSubagentId);
55598
+ } else if (event.background)
55599
+ occupancy.occupySpawn(event.callId, event.nativeSubagentId);
55600
+ } else if (event.type === "subagent.completed") {
55601
+ if (sends.has(event.callId)) {
55602
+ const agentId = event.nativeSubagentId ?? sends.get(event.callId);
55603
+ if (!event.isError && agentId)
55604
+ occupancy.occupyAgent(agentId);
55605
+ sends.delete(event.callId);
55606
+ } else if (!event.isError && event.continuesInBackground) {
55607
+ occupancy.occupySpawn(event.callId, event.nativeSubagentId);
55608
+ } else
55609
+ occupancy.release(event.callId, event.nativeSubagentId);
55610
+ } else if (event.type === "workflow.launched" && event.background && !event.isError) {
55611
+ occupancy.occupySpawn(event.callId, event.taskId);
55612
+ } else if (event.type === "subagent.settled") {
55613
+ occupancy.notify(event.callId, event.nativeSubagentId);
55614
+ }
55615
+ }
55616
+ if (notification)
55617
+ pendingNotification = true;
55618
+ if (message.type === "assistant" && !message.nested) {
55619
+ pendingNotification = false;
55620
+ if (["end_turn", "stop_sequence", "max_tokens"].includes(String(message.message.stop_reason))) {
55621
+ occupancy.releaseContinuations();
55622
+ }
55623
+ }
55624
+ if (interrupted)
55625
+ occupancy.clear();
55306
55626
  messages.push(message);
55307
55627
  if (isHumanUser(message)) {
55308
55628
  promptId = typeof value.promptId === "string" && value.promptId.length > 0 ? value.promptId : null;
@@ -55359,17 +55679,17 @@ function mapClaudeSnapshot(values, sessionId) {
55359
55679
  const turns = [];
55360
55680
  for (let index = 0; index < messages.length; ) {
55361
55681
  const user = messages[index];
55362
- if (!user || !isHumanUser(user)) {
55682
+ if (!user || !user.startsTurn) {
55363
55683
  index += 1;
55364
55684
  continue;
55365
55685
  }
55366
55686
  let end = index + 1;
55367
- while (end < messages.length && !isHumanUser(messages[end]))
55687
+ while (end < messages.length && !messages[end]?.startsTurn)
55368
55688
  end += 1;
55369
55689
  const turnMessages = messages.slice(index, end);
55370
55690
  const outcome = turnOutcome(turnMessages);
55371
55691
  const results = toolResultBlocks(turnMessages);
55372
- const checkpointMessage = turnMessages.findLast(({ type, interrupted }) => type === "assistant" || interrupted);
55692
+ const checkpointMessage = turnMessages.findLast(({ type, interrupted, nested }) => !nested && (type === "assistant" || interrupted));
55373
55693
  let agentMessageOrdinal = 0;
55374
55694
  let reasoningOrdinal = 0;
55375
55695
  let toolOrdinal = 0;
@@ -55463,7 +55783,7 @@ function mapClaudeSnapshot(values, sessionId) {
55463
55783
  if (!result)
55464
55784
  continue;
55465
55785
  const output = toolResultOutput(result);
55466
- const failed = result.is_error === true;
55786
+ const failed = result.is_error === true || block.name === "SendMessage" && claudeSendMessageFailed(void 0, output);
55467
55787
  const toolOutcome = failed ? {
55468
55788
  status: "failed",
55469
55789
  error: {
@@ -55758,12 +56078,6 @@ async function forkClaudeSession(input) {
55758
56078
  error: error51("protocolError", "Claude Code Session working directory is unavailable", false)
55759
56079
  };
55760
56080
  }
55761
- if (path12.resolve(sourceInfo.cwd) !== input.cwd) {
55762
- return {
55763
- ok: false,
55764
- error: error51("unsupported", "Claude Code cannot Fork across working directories", false)
55765
- };
55766
- }
55767
56081
  const source = await readSnapshot(input.dependencies, input.cwd, sourceRef.data.nativeSessionId);
55768
56082
  if (!source.ok)
55769
56083
  return source;
@@ -55863,13 +56177,13 @@ import { readFile as readFile6, rename as rename4, rm as rm5, stat as stat5, wri
55863
56177
 
55864
56178
  // dist/claude-transcript.js
55865
56179
  import os6 from "node:os";
55866
- import path13 from "node:path";
56180
+ import path12 from "node:path";
55867
56181
  import { readFile as readFile5, readdir as readdir3, stat as stat4 } from "node:fs/promises";
55868
56182
  function projectDirectoryName(cwd) {
55869
56183
  return cwd.replace(/[^A-Za-z0-9]/gu, "-");
55870
56184
  }
55871
56185
  function configDirectory(environment) {
55872
- return environment.CLAUDE_CONFIG_DIR ? path13.resolve(environment.CLAUDE_CONFIG_DIR) : path13.join(os6.homedir(), ".claude");
56186
+ return environment.CLAUDE_CONFIG_DIR ? path12.resolve(environment.CLAUDE_CONFIG_DIR) : path12.join(os6.homedir(), ".claude");
55873
56187
  }
55874
56188
  async function existingFile(file2) {
55875
56189
  try {
@@ -55879,9 +56193,9 @@ async function existingFile(file2) {
55879
56193
  }
55880
56194
  }
55881
56195
  async function findClaudeTranscript(input) {
55882
- const projectsDirectory = path13.join(configDirectory(input.environment), "projects");
56196
+ const projectsDirectory = path12.join(configDirectory(input.environment), "projects");
55883
56197
  const name = `${input.sessionId}.jsonl`;
55884
- const expected = path13.join(projectsDirectory, projectDirectoryName(input.cwd), name);
56198
+ const expected = path12.join(projectsDirectory, projectDirectoryName(input.cwd), name);
55885
56199
  if (await existingFile(expected))
55886
56200
  return expected;
55887
56201
  let projects;
@@ -55891,7 +56205,7 @@ async function findClaudeTranscript(input) {
55891
56205
  return null;
55892
56206
  }
55893
56207
  for (const project2 of projects) {
55894
- const candidate = path13.join(projectsDirectory, project2, name);
56208
+ const candidate = path12.join(projectsDirectory, project2, name);
55895
56209
  if (await existingFile(candidate))
55896
56210
  return candidate;
55897
56211
  }
@@ -56001,7 +56315,7 @@ async function remapForkedSessionReferences(input) {
56001
56315
  import { Buffer as Buffer2 } from "node:buffer";
56002
56316
  import { readFile as readFile7 } from "node:fs/promises";
56003
56317
  import os7 from "node:os";
56004
- import path14 from "node:path";
56318
+ import path13 from "node:path";
56005
56319
 
56006
56320
  // dist/thinking-options.js
56007
56321
  var option = (id2, label) => ({
@@ -56094,7 +56408,7 @@ function decodeClaudeModelRef(ref) {
56094
56408
  return value === "default" ? void 0 : value;
56095
56409
  }
56096
56410
  function resolveClaudeConfigDirectory(environment = process.env) {
56097
- return path14.resolve(environment.CLAUDE_CONFIG_DIR ?? path14.join(os7.homedir(), ".claude"));
56411
+ return path13.resolve(environment.CLAUDE_CONFIG_DIR ?? path13.join(os7.homedir(), ".claude"));
56098
56412
  }
56099
56413
  function parseModelPickerOptions(value) {
56100
56414
  if (!Array.isArray(value))
@@ -56136,7 +56450,7 @@ function parseClaudeModelPickerSettings(value) {
56136
56450
  };
56137
56451
  }
56138
56452
  async function readClaudeUserModelPicker(environment = process.env) {
56139
- const settingsPath = path14.join(resolveClaudeConfigDirectory(environment), "settings.json");
56453
+ const settingsPath = path13.join(resolveClaudeConfigDirectory(environment), "settings.json");
56140
56454
  let raw;
56141
56455
  try {
56142
56456
  raw = await readFile7(settingsPath, "utf8");
@@ -56482,7 +56796,7 @@ function projectClaudeAccountUsage(usage, account) {
56482
56796
 
56483
56797
  // dist/process-fence.js
56484
56798
  import { execFile as execFile3 } from "node:child_process";
56485
- import path15 from "node:path";
56799
+ import path14 from "node:path";
56486
56800
  import { setTimeout as setTimeout2 } from "node:timers/promises";
56487
56801
  import { promisify } from "node:util";
56488
56802
  var executeFile = promisify(execFile3);
@@ -56506,9 +56820,9 @@ async function closeClaudeProcessGroup(child, timeoutMs) {
56506
56820
  if (child.exitCode !== null || child.signalCode !== null)
56507
56821
  throw new Error("Claude process tree cannot be confirmed after its Windows root exited");
56508
56822
  const root = process.env.SystemRoot ?? process.env.SYSTEMROOT;
56509
- if (!root || !path15.win32.isAbsolute(root))
56823
+ if (!root || !path14.win32.isAbsolute(root))
56510
56824
  throw new Error("Windows SystemRoot is unavailable");
56511
- await executeFile(path15.win32.join(root, "System32", "taskkill.exe"), ["/PID", String(pid), "/T", "/F"], {
56825
+ await executeFile(path14.win32.join(root, "System32", "taskkill.exe"), ["/PID", String(pid), "/T", "/F"], {
56512
56826
  timeout: timeoutMs,
56513
56827
  windowsHide: true
56514
56828
  });
@@ -56533,12 +56847,21 @@ async function closeClaudeProcessGroup(child, timeoutMs) {
56533
56847
  throw new Error("Claude SDK process group did not exit");
56534
56848
  }
56535
56849
 
56850
+ // dist/transport.js
56851
+ var ClaudeSteerMissedTurnError = class extends Error {
56852
+ constructor() {
56853
+ super("Claude Code steer missed the active Turn");
56854
+ this.name = "ClaudeSteerMissedTurnError";
56855
+ }
56856
+ };
56857
+
56536
56858
  // dist/sdk-transport.js
56537
56859
  var CLIENT_APP = "codexhost-claude-code-adapter/0.0.0";
56538
56860
  var SESSION_ENTRYPOINT = "codexhost-sdk";
56539
56861
  var APPROVAL_TITLE_MAX_LENGTH = 120;
56540
56862
  var APPROVAL_DESCRIPTION_MAX_LENGTH = 500;
56541
56863
  var DEFAULT_ABORT_TIMEOUT_MS = 2e3;
56864
+ var DEFAULT_STEER_QUEUED_TIMEOUT_MS = 5e3;
56542
56865
  var WORKFLOW_AGENT_LABEL_LIMIT = 1e3;
56543
56866
  var INTERRUPT_TIMEOUT_MESSAGE = "Claude SDK interrupt timed out";
56544
56867
  var PushableInput = class {
@@ -56794,6 +57117,13 @@ var ClaudeSdkTransport = class {
56794
57117
  #queryFactory;
56795
57118
  #thinkingOptionId;
56796
57119
  #active = null;
57120
+ #steerQueuedTimeoutMs;
57121
+ #nativeSteer = false;
57122
+ /** Root tool calls of the requested Turn that have started and not yet returned a result. */
57123
+ #rootToolCalls = /* @__PURE__ */ new Set();
57124
+ #pendingSteers = /* @__PURE__ */ new Map();
57125
+ /** Written steers Claude has not yet drained into a native turn, by message ID. */
57126
+ #steerTakeovers = /* @__PURE__ */ new Map();
56797
57127
  #autonomous = null;
56798
57128
  #autonomousTurnHandler = null;
56799
57129
  #idleHandler = null;
@@ -56817,6 +57147,7 @@ var ClaudeSdkTransport = class {
56817
57147
  this.sessionId = options.sessionId;
56818
57148
  this.#cwd = options.cwd;
56819
57149
  this.#abortTimeoutMs = options.abortTimeoutMs ?? DEFAULT_ABORT_TIMEOUT_MS;
57150
+ this.#steerQueuedTimeoutMs = options.steerQueuedTimeoutMs ?? DEFAULT_STEER_QUEUED_TIMEOUT_MS;
56820
57151
  this.#closeTimeoutMs = options.closeTimeoutMs;
56821
57152
  this.#command = options.command;
56822
57153
  this.#environment = options.environment ?? process.env;
@@ -56871,7 +57202,8 @@ var ClaudeSdkTransport = class {
56871
57202
  thinking: thinking.enabled ? { type: "adaptive", display: "summarized" } : { type: "disabled" },
56872
57203
  ...thinking.effort ? { effort: thinking.effort } : {},
56873
57204
  pathToClaudeCodeExecutable: executable,
56874
- settingSources: ["user"],
57205
+ // Omitted settingSources loads user, project and local settings like the
57206
+ // Claude Code CLI, so project CLAUDE.md and .claude/skills apply.
56875
57207
  permissionMode: this.#permissionMode,
56876
57208
  ...this.#allowDangerouslySkipPermissions ? { allowDangerouslySkipPermissions: true } : {},
56877
57209
  canUseTool: (toolName, input, options) => this.#canUseTool(toolName, input, options),
@@ -56908,6 +57240,47 @@ var ClaudeSdkTransport = class {
56908
57240
  return null;
56909
57241
  return { commands: this.#slashCommands, skillNames: this.#skillNames };
56910
57242
  }
57243
+ supportsNativeSteer() {
57244
+ return this.#nativeSteer;
57245
+ }
57246
+ /**
57247
+ * `priority: "next"` joins after the current tool call, and a tool result is always followed by
57248
+ * another model request. So a steer written while a root tool call runs folds into this Turn;
57249
+ * one written while Claude streams its final text may instead run as the next Turn.
57250
+ *
57251
+ * A held Turn's continuation steers as well: while its idle stream is live, the pushed input
57252
+ * runs as that Turn's next Segment, and the background work the Turn waits on keeps running.
57253
+ */
57254
+ canSteerActiveTurn() {
57255
+ if (!this.#nativeSteer)
57256
+ return false;
57257
+ if (this.#active !== null)
57258
+ return this.#rootToolCalls.size > 0;
57259
+ return this.#idleLive && this.#idleHandler !== null;
57260
+ }
57261
+ #observeRootToolCalls(message) {
57262
+ if (!isRecord11(message) || message.parent_tool_use_id != null)
57263
+ return;
57264
+ if (message.type !== "assistant" && message.type !== "user")
57265
+ return;
57266
+ const body = message.message;
57267
+ if (!isRecord11(body) || !Array.isArray(body.content))
57268
+ return;
57269
+ for (const block of body.content) {
57270
+ if (!isRecord11(block))
57271
+ continue;
57272
+ if (message.type === "assistant" && block.type === "tool_use" && typeof block.id === "string") {
57273
+ this.#rootToolCalls.add(block.id);
57274
+ } else if (message.type === "user" && block.type === "tool_result" && typeof block.tool_use_id === "string") {
57275
+ this.#rootToolCalls.delete(block.tool_use_id);
57276
+ }
57277
+ }
57278
+ }
57279
+ #observeNativeCapabilities(message) {
57280
+ if (!isRecord11(message) || message.type !== "system" || message.subtype !== "init")
57281
+ return;
57282
+ this.#nativeSteer = Array.isArray(message.capabilities) && message.capabilities.includes("msg_lifecycle_v1");
57283
+ }
56911
57284
  #observeSlashCommands(message) {
56912
57285
  if (!isRecord11(message) || message.type !== "system")
56913
57286
  return;
@@ -57030,6 +57403,7 @@ var ClaudeSdkTransport = class {
57030
57403
  const unclaimed = this.#autonomous?.events ?? [];
57031
57404
  this.#autonomous = null;
57032
57405
  const promise2 = new Promise((resolve5, reject) => {
57406
+ this.#rootToolCalls.clear();
57033
57407
  this.#active = {
57034
57408
  accumulator: new ClaudeNativeTurnAccumulator(this.#provider ? { provider: this.#provider } : {}),
57035
57409
  onEvent,
@@ -57049,6 +57423,63 @@ var ClaudeSdkTransport = class {
57049
57423
  });
57050
57424
  return promise2;
57051
57425
  }
57426
+ /**
57427
+ * Claude accepts the input with `queued`; Claude Code 2.1.280 then emits `started` after the
57428
+ * current tool call, when `priority: "next"` joins the running Turn. Waiting for `started` would
57429
+ * hold the caller for a whole tool call.
57430
+ *
57431
+ * Once written, the input cannot be recalled: Claude delivers it in this Turn or runs it next.
57432
+ * The Turn ending first therefore does not reject it, and a missing `queued` receipt resolves
57433
+ * after a bounded wait so callers that serialize requests are never held indefinitely.
57434
+ */
57435
+ steer(text2, messageId, onTakeover) {
57436
+ if (this.#closePromise || !this.#started || !this.#query || !this.canSteerActiveTurn()) {
57437
+ return Promise.reject(new ClaudeSteerMissedTurnError());
57438
+ }
57439
+ const promise2 = new Promise((resolve5, reject) => {
57440
+ this.#pendingSteers.set(messageId, { resolve: resolve5, reject, timer: void 0 });
57441
+ });
57442
+ try {
57443
+ this.#input.push({
57444
+ type: "user",
57445
+ message: { role: "user", content: text2 },
57446
+ parent_tool_use_id: null,
57447
+ session_id: this.sessionId,
57448
+ uuid: messageId,
57449
+ origin: { kind: "human" },
57450
+ priority: "next"
57451
+ });
57452
+ } catch {
57453
+ this.#pendingSteers.delete(messageId);
57454
+ return Promise.reject(new ClaudeSteerMissedTurnError());
57455
+ }
57456
+ if (onTakeover)
57457
+ this.#steerTakeovers.set(messageId, onTakeover);
57458
+ const pending = this.#pendingSteers.get(messageId);
57459
+ if (pending) {
57460
+ pending.timer = setTimeout(() => {
57461
+ this.#acceptSteer(messageId);
57462
+ this.#takeOverSteer(messageId, false);
57463
+ }, this.#steerQueuedTimeoutMs);
57464
+ pending.timer.unref?.();
57465
+ }
57466
+ return promise2;
57467
+ }
57468
+ #acceptSteer(messageId) {
57469
+ const pending = this.#pendingSteers.get(messageId);
57470
+ if (!pending)
57471
+ return;
57472
+ this.#pendingSteers.delete(messageId);
57473
+ clearTimeout(pending.timer);
57474
+ pending.resolve();
57475
+ }
57476
+ #takeOverSteer(messageId, started) {
57477
+ const onTakeover = this.#steerTakeovers.get(messageId);
57478
+ if (!onTakeover)
57479
+ return;
57480
+ this.#steerTakeovers.delete(messageId);
57481
+ onTakeover(started);
57482
+ }
57052
57483
  respondToInteraction(response) {
57053
57484
  const pending = this.#interactions.get(response.requestId);
57054
57485
  if (!pending) {
@@ -57220,6 +57651,7 @@ var ClaudeSdkTransport = class {
57220
57651
  }
57221
57652
  }
57222
57653
  async #close() {
57654
+ this.#rejectPendingSteers();
57223
57655
  const failures = [];
57224
57656
  this.#closeInteractions("all", "cancelled");
57225
57657
  try {
@@ -57273,6 +57705,7 @@ var ClaudeSdkTransport = class {
57273
57705
  }
57274
57706
  this.#query = null;
57275
57707
  const active = this.#active;
57708
+ this.#rootToolCalls.clear();
57276
57709
  this.#active = null;
57277
57710
  this.#autonomous = null;
57278
57711
  this.#idleAccumulator = null;
@@ -57327,6 +57760,37 @@ var ClaudeSdkTransport = class {
57327
57760
  await delay(10);
57328
57761
  }
57329
57762
  }
57763
+ #rejectPendingSteers() {
57764
+ for (const messageId of [...this.#steerTakeovers.keys()]) {
57765
+ this.#takeOverSteer(messageId, false);
57766
+ }
57767
+ const pending = [...this.#pendingSteers.values()];
57768
+ this.#pendingSteers.clear();
57769
+ const error52 = new Error("Claude Code steer receipt was lost after input was written");
57770
+ for (const entry of pending) {
57771
+ clearTimeout(entry.timer);
57772
+ entry.reject(error52);
57773
+ }
57774
+ }
57775
+ /**
57776
+ * `queued` is Claude's acceptance of this message into the running Session. `started` is its
57777
+ * drain into a native turn, folded into the running one or run as the next; a terminal state
57778
+ * without `started` means no native turn takes it over.
57779
+ */
57780
+ #observeSteer(message) {
57781
+ if (this.#pendingSteers.size === 0 && this.#steerTakeovers.size === 0 || !isRecord11(message) || message.type !== "command_lifecycle") {
57782
+ return;
57783
+ }
57784
+ if (typeof message.command_uuid !== "string" || message.command_uuid.length === 0)
57785
+ return;
57786
+ if (message.state === "queued") {
57787
+ this.#acceptSteer(message.command_uuid);
57788
+ return;
57789
+ }
57790
+ if (["started", "completed", "cancelled", "discarded", "refused"].includes(String(message.state))) {
57791
+ this.#takeOverSteer(message.command_uuid, message.state === "started");
57792
+ }
57793
+ }
57330
57794
  #observeBackgroundTasks(message) {
57331
57795
  if (!isRecord11(message) || message.type !== "system")
57332
57796
  return;
@@ -57367,6 +57831,7 @@ var ClaudeSdkTransport = class {
57367
57831
  this.#observeBackgroundTasks(message);
57368
57832
  this.#observeWorkflowAgents(message);
57369
57833
  this.#observeSlashCommands(message);
57834
+ this.#observeNativeCapabilities(message);
57370
57835
  const permissionMode = permissionModeFromMessage(message);
57371
57836
  if (permissionMode && permissionMode !== this.#permissionMode) {
57372
57837
  this.#permissionMode = permissionMode;
@@ -57375,13 +57840,16 @@ var ClaudeSdkTransport = class {
57375
57840
  const planLimit = parseClaudePlanLimitEvent(message);
57376
57841
  if (planLimit)
57377
57842
  this.#onPlanLimit(planLimit);
57843
+ this.#observeSteer(message);
57378
57844
  const active = this.#active;
57379
57845
  if (active) {
57846
+ this.#observeRootToolCalls(message);
57380
57847
  const interpreted2 = active.accumulator.consume(message);
57381
57848
  for (const event of interpreted2.events)
57382
57849
  active.onEvent(event);
57383
57850
  if (interpreted2.terminal) {
57384
57851
  this.#closeInteractions("root", "superseded");
57852
+ this.#rootToolCalls.clear();
57385
57853
  this.#active = null;
57386
57854
  active.resolve(interpreted2.terminal);
57387
57855
  }
@@ -57434,11 +57902,13 @@ var ClaudeSdkTransport = class {
57434
57902
  throw new Error("Claude SDK Query ended unexpectedly");
57435
57903
  } catch (error52) {
57436
57904
  const active = this.#active;
57905
+ if (!this.#closePromise)
57906
+ this.#onFault(error52);
57437
57907
  this.#closeInteractions("all", "cancelled");
57908
+ this.#rejectPendingSteers();
57909
+ this.#rootToolCalls.clear();
57438
57910
  this.#active = null;
57439
57911
  active?.reject(error52);
57440
- if (!this.#closePromise)
57441
- this.#onFault(error52);
57442
57912
  }
57443
57913
  }
57444
57914
  #spawn(options) {
@@ -57735,7 +58205,7 @@ var ClaudeSubagentLifecycle = class {
57735
58205
  });
57736
58206
  const outcome = cancellationRequested ? { status: "cancelled", reason: "Cancelled by user" } : event.isError ? { status: "failed", error: subagentFailure() } : { status: "succeeded" };
57737
58207
  this.#emit({ type: "item.completed", turnId, snapshot: { item, outcome } });
57738
- return subagent;
58208
+ return { operation: active.item.operation, subagent };
57739
58209
  }
57740
58210
  finalize(turnId, outcome) {
57741
58211
  for (const [callId, active] of this.#delegations) {
@@ -57943,9 +58413,9 @@ function stringField(value, keys) {
57943
58413
  if (!isRecord12(value))
57944
58414
  return void 0;
57945
58415
  for (const key of keys) {
57946
- const field = value[key];
57947
- if (typeof field === "string" && field.length > 0)
57948
- return field;
58416
+ const field2 = value[key];
58417
+ if (typeof field2 === "string" && field2.length > 0)
58418
+ return field2;
57949
58419
  }
57950
58420
  return void 0;
57951
58421
  }
@@ -58622,7 +59092,7 @@ function projectClaudePlanLimitToCredits(planLimit) {
58622
59092
  }
58623
59093
  var ClaudeHarnessSession = class {
58624
59094
  harnessId = claudeCodeHarnessId2;
58625
- capabilities = {
59095
+ capabilities = /* @__PURE__ */ ((session) => ({
58626
59096
  configuration: {
58627
59097
  selectModel: true,
58628
59098
  selectThinkingOption: true,
@@ -58630,11 +59100,18 @@ var ClaudeHarnessSession = class {
58630
59100
  permissionModeScope: "live"
58631
59101
  },
58632
59102
  history: { fork: true, forkAcrossCwd: false, rollbackLastTurn: true },
58633
- subagents: { observe: true, readTranscript: true }
58634
- };
59103
+ subagents: { observe: true, readTranscript: true },
59104
+ // Read live: native delivery joins this Turn while a root tool call runs, or while a held
59105
+ // Turn's continuation waits on background work, on a CLI that confirms steers
59106
+ // (`msg_lifecycle_v1`). A Turn whose cancellation is in flight must not take more input;
59107
+ // every other case stops and restarts.
59108
+ get steer() {
59109
+ return session.#transport?.canSteerActiveTurn?.() === true && session.#active?.cancellationRequested !== true;
59110
+ }
59111
+ }))(this);
58635
59112
  commands;
58636
59113
  initialState;
58637
- initialUsage = null;
59114
+ initialUsage;
58638
59115
  outputs;
58639
59116
  #channel = new HarnessOutputChannel();
58640
59117
  #cancelTimeoutMs;
@@ -58673,7 +59150,10 @@ var ClaudeHarnessSession = class {
58673
59150
  #hardCancelTask = null;
58674
59151
  #usageGeneration = 0;
58675
59152
  #latestUsage = null;
59153
+ #lastAssistantResponseAtUnix;
59154
+ #accountCreditsSupported;
58676
59155
  #minimumContextUsedTokens = null;
59156
+ #latestRequestModel = null;
58677
59157
  #calibratedInputTokens = 0;
58678
59158
  #calibratedOutputTokens = 0;
58679
59159
  #calibratedCostUsd = 0;
@@ -58691,6 +59171,11 @@ var ClaudeHarnessSession = class {
58691
59171
  #continuationQuiescence = null;
58692
59172
  constructor(cwd, dependencies, closeTimeoutMs, onClosed, onPlanLimitObserved, options) {
58693
59173
  this.#cwd = cwd;
59174
+ this.#lastAssistantResponseAtUnix = options.usageHistory.lastResponseAtUnix;
59175
+ this.#accountCreditsSupported = options.accountCreditsSupported;
59176
+ const composerIndicators = claudePromptCacheIndicators(this.#accountCreditsSupported, this.#lastAssistantResponseAtUnix);
59177
+ this.initialUsage = composerIndicators.length ? { composerIndicators } : null;
59178
+ this.#latestUsage = this.initialUsage;
58694
59179
  this.#pendingSessions = options.pendingSessions;
58695
59180
  const environment = options.environment;
58696
59181
  this.#createTransport = environment ? (input) => dependencies.createTransport({ ...input, environment }) : dependencies.createTransport;
@@ -58845,6 +59330,8 @@ var ClaudeHarnessSession = class {
58845
59330
  }
58846
59331
  if (command.type === "turn.cancel")
58847
59332
  return this.#cancel(command);
59333
+ if (command.type === "turn.steer")
59334
+ return this.#steer(command);
58848
59335
  if (command.type === "interaction.respond")
58849
59336
  return this.#respond(command);
58850
59337
  if (command.type === "model.select")
@@ -58946,6 +59433,7 @@ var ClaudeHarnessSession = class {
58946
59433
  nativeTurnKey,
58947
59434
  nativeTurnRef: null,
58948
59435
  cancellationRequested: false,
59436
+ steersAwaitingNative: /* @__PURE__ */ new Set(),
58949
59437
  usageRequestIds: /* @__PURE__ */ new Set(),
58950
59438
  estimatedInputTokens: 0,
58951
59439
  estimatedOutputTokens: 0,
@@ -58981,6 +59469,52 @@ var ClaudeHarnessSession = class {
58981
59469
  }
58982
59470
  return { ok: true, value: { turnId: command.turnId } };
58983
59471
  }
59472
+ async #steer(command) {
59473
+ const active = this.#active;
59474
+ if (!active || active.command.turnId !== command.turnId) {
59475
+ return { ok: false, error: invalidState("Claude Code steer target is not the active Turn") };
59476
+ }
59477
+ if (active.cancellationRequested) {
59478
+ return { ok: false, error: invalidState("Claude Code steer target is being cancelled") };
59479
+ }
59480
+ const text2 = command.input.map((input) => input.text).join("\n");
59481
+ if (text2.length === 0) {
59482
+ return {
59483
+ ok: false,
59484
+ error: {
59485
+ code: "invalidRequest",
59486
+ message: "Claude Code steer text must not be empty",
59487
+ retryable: false
59488
+ }
59489
+ };
59490
+ }
59491
+ const transport = this.#transport;
59492
+ if (!transport) {
59493
+ return { ok: false, error: invalidState("Claude Code steer missed the active Turn") };
59494
+ }
59495
+ if (transport.supportsNativeSteer?.() !== true) {
59496
+ return {
59497
+ ok: false,
59498
+ error: {
59499
+ code: "unsupported",
59500
+ message: "This Claude Code version does not confirm native steering",
59501
+ retryable: false
59502
+ }
59503
+ };
59504
+ }
59505
+ const messageId = this.#randomUUID();
59506
+ active.steersAwaitingNative.add(messageId);
59507
+ try {
59508
+ await transport.steer(text2, messageId, (started) => this.#takeOverSteer(active, messageId, started));
59509
+ } catch (error52) {
59510
+ if (error52 instanceof ClaudeSteerMissedTurnError) {
59511
+ this.#takeOverSteer(active, messageId, false);
59512
+ return { ok: false, error: invalidState("Claude Code steer missed the active Turn") };
59513
+ }
59514
+ throw error52;
59515
+ }
59516
+ return { ok: true, value: { accepted: true } };
59517
+ }
58984
59518
  /** Built-ins plus the live commands and skills of the started native Session. */
58985
59519
  #liveCommandCatalog() {
58986
59520
  return claudeLiveCommandCatalog(claudeCommandCatalog, this.#transport?.slashCommands?.() ?? null);
@@ -59077,6 +59611,7 @@ var ClaudeHarnessSession = class {
59077
59611
  nativeTurnKey,
59078
59612
  nativeTurnRef: null,
59079
59613
  cancellationRequested: false,
59614
+ steersAwaitingNative: /* @__PURE__ */ new Set(),
59080
59615
  usageRequestIds: /* @__PURE__ */ new Set(),
59081
59616
  estimatedInputTokens: 0,
59082
59617
  estimatedOutputTokens: 0,
@@ -59438,7 +59973,7 @@ var ClaudeHarnessSession = class {
59438
59973
  active.cancellationRequested = true;
59439
59974
  const transport = this.#transport;
59440
59975
  const taskIds = this.#backgroundTaskIds(active);
59441
- if (transport && (taskIds.length > 0 || active.held && (active.rootSegmentActive || this.#occupancy.awaitingContinuation))) {
59976
+ if (transport && (taskIds.length > 0 || active.held && (active.rootSegmentActive || this.#occupancy.awaitingContinuation || active.steersAwaitingNative.size > 0))) {
59442
59977
  await this.#cancelBackgroundWork(active, transport, taskIds);
59443
59978
  return { ok: true, value: { cancellationRequested: true } };
59444
59979
  }
@@ -59513,6 +60048,11 @@ var ClaudeHarnessSession = class {
59513
60048
  return;
59514
60049
  if (cancellation.stopping || cancellation.interrupting || active.rootSegmentActive)
59515
60050
  return;
60051
+ if (active.steersAwaitingNative.size > 0) {
60052
+ this.#armCancelEscalation(active);
60053
+ return;
60054
+ }
60055
+ this.#clearCancelEscalation();
59516
60056
  this.#clearCancellationQuiet(cancellation);
59517
60057
  const quiet = setTimeout(() => {
59518
60058
  cancellation.quiet = null;
@@ -59751,6 +60291,10 @@ var ClaudeHarnessSession = class {
59751
60291
  this.#completeReasoning(active, event.messageId, { status: "succeeded" });
59752
60292
  return;
59753
60293
  case "message.completed": {
60294
+ if (!event.localCommand) {
60295
+ this.#lastAssistantResponseAtUnix = Math.floor(Date.now() / 1e3);
60296
+ this.publishAccountCreditsSupport(this.#accountCreditsSupported);
60297
+ }
59754
60298
  this.#observeRootOutput(active);
59755
60299
  if (event.lastRequestUsage) {
59756
60300
  this.#requestUsageBoundary += 1;
@@ -59788,10 +60332,7 @@ var ClaudeHarnessSession = class {
59788
60332
  }
59789
60333
  this.#completeAgentItem(active, { status: "succeeded" }, false);
59790
60334
  active.subagents.start(active.command.turnId, event);
59791
- if (event.operation === "send") {
59792
- if (event.nativeSubagentId)
59793
- this.#occupancy.occupyAgent(event.nativeSubagentId);
59794
- } else if (event.background) {
60335
+ if (event.operation === "spawn" && event.background) {
59795
60336
  this.#occupancy.occupySpawn(event.callId, event.nativeSubagentId);
59796
60337
  }
59797
60338
  return;
@@ -59810,13 +60351,17 @@ var ClaudeHarnessSession = class {
59810
60351
  }
59811
60352
  return;
59812
60353
  case "subagent.completed": {
59813
- const subagent = active.subagents.complete(active.command.turnId, event, active.cancellationRequested);
59814
- if (subagent.status === "running") {
59815
- if (subagent.nativeSubagentId) {
59816
- this.#occupancy.bind(event.callId, subagent.nativeSubagentId);
60354
+ const { operation, subagent } = active.subagents.complete(active.command.turnId, event, active.cancellationRequested);
60355
+ if (operation === "send") {
60356
+ if (subagent.status === "running" && subagent.nativeSubagentId) {
60357
+ this.#occupancy.occupyAgent(subagent.nativeSubagentId);
59817
60358
  }
59818
60359
  return;
59819
60360
  }
60361
+ if (subagent.status === "running") {
60362
+ this.#occupancy.occupySpawn(event.callId, subagent.nativeSubagentId);
60363
+ return;
60364
+ }
59820
60365
  this.#occupancy.release(event.callId, subagent.nativeSubagentId);
59821
60366
  return;
59822
60367
  }
@@ -60124,6 +60669,7 @@ var ClaudeHarnessSession = class {
60124
60669
  const active = {
60125
60670
  command: { type: "turn.start", turnId, input: [] },
60126
60671
  compactionItem: null,
60672
+ steersAwaitingNative: /* @__PURE__ */ new Set(),
60127
60673
  item,
60128
60674
  agentMessageOrdinal: 1,
60129
60675
  assistantMessageId: null,
@@ -60373,6 +60919,8 @@ var ClaudeHarnessSession = class {
60373
60919
  const promptTokens = usage.inputTokens + usage.cacheCreationInputTokens + usage.cacheReadInputTokens;
60374
60920
  if (promptTokens > 0)
60375
60921
  this.#minimumContextUsedTokens = promptTokens;
60922
+ if (usage.model)
60923
+ this.#latestRequestModel = usage.model;
60376
60924
  const cacheHitRatePercent = claudeCacheHitRatePercent(usage);
60377
60925
  const contextWindowTokens = this.#latestUsage?.contextWindowTokens;
60378
60926
  this.#mergeAndPublishUsage({
@@ -60414,8 +60962,24 @@ var ClaudeHarnessSession = class {
60414
60962
  if (cacheHitRatePercent !== void 0)
60415
60963
  delta.cacheHitRatePercent = cacheHitRatePercent;
60416
60964
  }
60965
+ if (this.#latestUsage?.contextWindowTokens === void 0 && this.#minimumContextUsedTokens !== null) {
60966
+ const contextWindowTokens = this.#resultContextWindow(event.modelUsage);
60967
+ if (contextWindowTokens !== void 0) {
60968
+ delta.contextUsedTokens = this.#minimumContextUsedTokens;
60969
+ delta.contextWindowTokens = contextWindowTokens;
60970
+ }
60971
+ }
60417
60972
  this.#mergeAndPublishUsage(delta, active.command.turnId);
60418
60973
  }
60974
+ /** The latest request's Model, else the Model that carried the most prompt tokens. */
60975
+ #resultContextWindow(modelUsage) {
60976
+ if (!modelUsage?.length)
60977
+ return void 0;
60978
+ const latest = this.#latestRequestModel;
60979
+ const matched = latest ? modelUsage.find(({ model: model2 }) => model2 === latest) : void 0;
60980
+ const main = matched ?? modelUsage.reduce((best, entry) => (entry.promptTokens ?? entry.inputTokens) > (best.promptTokens ?? best.inputTokens) ? entry : best);
60981
+ return main.contextWindowTokens;
60982
+ }
60419
60983
  /**
60420
60984
  * Plan usage is account-wide, not Thread-scoped, so every observation is
60421
60985
  * offered to the Adapter's shared cache regardless of this Session's own
@@ -60428,6 +60992,15 @@ var ClaudeHarnessSession = class {
60428
60992
  if (effective)
60429
60993
  this.publishPlanLimit(effective);
60430
60994
  }
60995
+ publishAccountCreditsSupport(supported) {
60996
+ if (this.#phase !== "open")
60997
+ return;
60998
+ this.#accountCreditsSupported = supported;
60999
+ const composerIndicators = claudePromptCacheIndicators(supported, this.#lastAssistantResponseAtUnix);
61000
+ if (composerIndicators[0]?.expiresAtUnix === this.#latestUsage?.composerIndicators?.[0]?.expiresAtUnix)
61001
+ return;
61002
+ this.#mergeAndPublishUsage({ composerIndicators }, this.#active?.command.turnId);
61003
+ }
60431
61004
  publishPlanLimit(planLimit) {
60432
61005
  if (this.#phase !== "open")
60433
61006
  return;
@@ -60485,7 +61058,7 @@ var ClaudeHarnessSession = class {
60485
61058
  this.#clearContinuationQuiescence();
60486
61059
  const quiescence = setTimeout(() => {
60487
61060
  this.#continuationQuiescence = null;
60488
- if (this.#active !== active || !active.held || active.rootSegmentActive || this.#phase !== "open") {
61061
+ if (this.#active !== active || !active.held || active.rootSegmentActive || active.steersAwaitingNative.size > 0 || this.#phase !== "open") {
60489
61062
  return;
60490
61063
  }
60491
61064
  this.#occupancy.releaseContinuations();
@@ -60506,6 +61079,30 @@ var ClaudeHarnessSession = class {
60506
61079
  active.rootSegmentActive = true;
60507
61080
  this.#clearContinuationQuiescence();
60508
61081
  }
61082
+ /**
61083
+ * A drained steer runs in a native turn whose result still reaches this Turn, folded into the
61084
+ * running Root Segment or as the held Turn's next one. A steer that ends without one releases
61085
+ * its keep-open, so a Turn held only for it settles as if the steer had never been written.
61086
+ */
61087
+ #takeOverSteer(active, messageId, started) {
61088
+ if (!active.steersAwaitingNative.delete(messageId) || this.#active !== active)
61089
+ return;
61090
+ if (started) {
61091
+ this.#handleTurnEvent(active, { type: "segment.started" });
61092
+ return;
61093
+ }
61094
+ if (active.cancellation) {
61095
+ this.#settleCancellation(active);
61096
+ return;
61097
+ }
61098
+ if (!active.held || active.rootSegmentActive || active.steersAwaitingNative.size > 0 || this.#phase !== "open") {
61099
+ return;
61100
+ }
61101
+ if (this.#occupancy.awaitingContinuation)
61102
+ this.#armContinuationQuiescence(active);
61103
+ else if (!this.#occupancy.unsettled)
61104
+ this.#finish(active, { status: "succeeded" });
61105
+ }
60509
61106
  #finish(active, outcome) {
60510
61107
  if (this.#active !== active)
60511
61108
  return;
@@ -60516,7 +61113,7 @@ var ClaudeHarnessSession = class {
60516
61113
  active.cancellation = null;
60517
61114
  }
60518
61115
  this.#clearContinuationQuiescence();
60519
- const hold = outcome.status === "succeeded" && !active.cancellationRequested && this.#occupancy.unsettled;
61116
+ const hold = outcome.status === "succeeded" && !active.cancellationRequested && (this.#occupancy.unsettled || active.steersAwaitingNative.size > 0);
60520
61117
  this.#closeActiveInteractions(active, outcome.status === "succeeded" ? "superseded" : "cancelled", hold);
60521
61118
  const itemOutcome2 = outcome;
60522
61119
  if (active.compactionItem)
@@ -60703,6 +61300,7 @@ var ClaudeCodeAdapter = class {
60703
61300
  #closePromise = null;
60704
61301
  #latestPlanLimit = null;
60705
61302
  #accountInspection = null;
61303
+ #accountCreditsSupported = false;
60706
61304
  constructor(options = {}, dependencies) {
60707
61305
  const environment = options.environment ?? process.env;
60708
61306
  this.#environment = environment;
@@ -60781,7 +61379,7 @@ var ClaudeCodeAdapter = class {
60781
61379
  error: invalidState("Claude Code Adapter is closing")
60782
61380
  };
60783
61381
  }
60784
- const cwd = path16.resolve(input.cwd ?? process.cwd());
61382
+ const cwd = path15.resolve(input.cwd ?? process.cwd());
60785
61383
  if (!input.refresh) {
60786
61384
  const cached2 = this.#inspectionCache.get(cwd);
60787
61385
  if (cached2)
@@ -60814,12 +61412,20 @@ var ClaudeCodeAdapter = class {
60814
61412
  return this.#accountInspection;
60815
61413
  }
60816
61414
  async #readAccount() {
61415
+ const planLimitAtStart = this.#latestPlanLimit;
60817
61416
  let inspector;
60818
61417
  try {
60819
61418
  this.#dependencies.inspectInstallation();
60820
61419
  inspector = this.#dependencies.createInspector({ cwd: process.cwd() });
60821
61420
  this.#inspectors.add(inspector);
60822
- return await inspector.inspectAccount?.() ?? null;
61421
+ const account = await inspector.inspectAccount?.() ?? null;
61422
+ if (this.#latestPlanLimit === planLimitAtStart) {
61423
+ this.#accountCreditsSupported = account?.credits !== void 0;
61424
+ for (const session of this.#sessions) {
61425
+ session.publishAccountCreditsSupport(this.#accountCreditsSupported);
61426
+ }
61427
+ }
61428
+ return account;
60823
61429
  } catch {
60824
61430
  return null;
60825
61431
  } finally {
@@ -60977,7 +61583,7 @@ var ClaudeCodeAdapter = class {
60977
61583
  }
60978
61584
  requestedPermissionModeId = CLAUDE_DEFAULT_PERMISSION_MODE_ID;
60979
61585
  }
60980
- const cwd = path16.resolve(input.cwd);
61586
+ const cwd = path15.resolve(input.cwd);
60981
61587
  if (input.kind === "rollbackLastTurn") {
60982
61588
  for (const source of this.#sessions) {
60983
61589
  const ready = await source.prepareRollback(input.sourceRef.nativeSessionId);
@@ -61062,6 +61668,7 @@ var ClaudeCodeAdapter = class {
61062
61668
  ...durableRef ? { nativeRef: durableRef } : {},
61063
61669
  sessionId,
61064
61670
  usageHistory,
61671
+ accountCreditsSupported: this.#accountCreditsSupported,
61065
61672
  ...requestedModel ? { requestedModel } : {},
61066
61673
  requestedPermissionModeId,
61067
61674
  requestedThinkingOptionId,
@@ -61081,7 +61688,13 @@ var ClaudeCodeAdapter = class {
61081
61688
  return { requests: [], complete: true };
61082
61689
  try {
61083
61690
  const messages = await this.#dependencies.readSessionMessages({ cwd, sessionId });
61084
- return messages === null ? { requests: [], complete: false } : claudeUsageHistory(messages);
61691
+ if (messages === null)
61692
+ return { requests: [], complete: false };
61693
+ const lastResponseAtUnix = lastClaudeAssistantResponseUnix(messages);
61694
+ return {
61695
+ ...claudeUsageHistory(messages),
61696
+ ...lastResponseAtUnix !== void 0 ? { lastResponseAtUnix } : {}
61697
+ };
61085
61698
  } catch {
61086
61699
  return { requests: [], complete: false };
61087
61700
  }
@@ -61093,9 +61706,17 @@ var ClaudeCodeAdapter = class {
61093
61706
  next.fiveHour = planLimit.fiveHour;
61094
61707
  if (planLimit.sevenDay)
61095
61708
  next.sevenDay = planLimit.sevenDay;
61709
+ try {
61710
+ if (!accountCreditsSnapshotSchema.safeParse(projectClaudePlanLimitToCredits(next)).success)
61711
+ return null;
61712
+ } catch {
61713
+ return null;
61714
+ }
61096
61715
  this.#latestPlanLimit = next.fiveHour || next.sevenDay ? next : null;
61097
61716
  if (this.#latestPlanLimit) {
61717
+ this.#accountCreditsSupported = true;
61098
61718
  for (const session of this.#sessions) {
61719
+ session.publishAccountCreditsSupport(true);
61099
61720
  if (session !== origin)
61100
61721
  session.publishPlanLimit(this.#latestPlanLimit);
61101
61722
  }
@@ -61122,7 +61743,7 @@ var ClaudeCodeAdapter = class {
61122
61743
  // dist/installation.js
61123
61744
  import { readFile as readFile8, realpath as realpath5 } from "node:fs/promises";
61124
61745
  import { homedir as homedir2 } from "node:os";
61125
- import path17 from "node:path";
61746
+ import path16 from "node:path";
61126
61747
  async function readSettings(file2) {
61127
61748
  const text2 = await readFile8(file2, "utf8").catch((error52) => {
61128
61749
  if (error52.code === "ENOENT")
@@ -61143,9 +61764,9 @@ function createClaudeInstallation(environment, command) {
61143
61764
  ...command ? { command } : {}
61144
61765
  });
61145
61766
  const home = environment.HOME ?? environment.USERPROFILE ?? homedir2();
61146
- const config2 = environment.CLAUDE_CONFIG_DIR ? path17.resolve(home, environment.CLAUDE_CONFIG_DIR) : path17.join(home, ".claude");
61147
- const managedFile = process.platform === "darwin" ? "/Library/Application Support/ClaudeCode/managed-settings.json" : process.platform === "win32" ? path17.join(environment.ProgramFiles ?? "C:\\Program Files", "ClaudeCode", "managed-settings.json") : "/etc/claude-code/managed-settings.json";
61148
- const user = await readSettings(path17.join(config2, "settings.json"));
61767
+ const config2 = environment.CLAUDE_CONFIG_DIR ? path16.resolve(home, environment.CLAUDE_CONFIG_DIR) : path16.join(home, ".claude");
61768
+ const managedFile = process.platform === "darwin" ? "/Library/Application Support/ClaudeCode/managed-settings.json" : process.platform === "win32" ? path16.join(environment.ProgramFiles ?? "C:\\Program Files", "ClaudeCode", "managed-settings.json") : "/etc/claude-code/managed-settings.json";
61769
+ const user = await readSettings(path16.join(config2, "settings.json"));
61149
61770
  const managed = await readSettings(managedFile);
61150
61771
  const settings = { ...user, ...managed, env: { ...user.env, ...managed.env } };
61151
61772
  const env = { ...environment, ...settings.env };
@@ -61158,10 +61779,10 @@ function createClaudeInstallation(environment, command) {
61158
61779
  throw new Error("Unknown Claude release channel");
61159
61780
  const latestVersion = installationVersion(await fetchInstallationText(`https://downloads.claude.ai/claude-code-releases/${channel}`));
61160
61781
  const npm = await npmInstallation(executable, ["@anthropic-ai/claude-code"], env);
61161
- const launcher = path17.join(home, ".local", "bin", process.platform === "win32" ? "claude.exe" : "claude");
61782
+ const launcher = path16.join(home, ".local", "bin", process.platform === "win32" ? "claude.exe" : "claude");
61162
61783
  const selected = await realpath5(executable);
61163
- const versions = path17.join(home, ".local", "share", "claude", "versions") + path17.sep;
61164
- const native = path17.resolve(executable) === launcher && (selected.startsWith(versions) || process.platform === "win32" && selected === launcher);
61784
+ const versions = path16.join(home, ".local", "share", "claude", "versions") + path16.sep;
61785
+ const native = path16.resolve(executable) === launcher && (selected.startsWith(versions) || process.platform === "win32" && selected === launcher);
61165
61786
  const blocked = !!env.DISABLE_UPDATES && env.DISABLE_UPDATES !== "0" || !!settings.minimumVersion && newerInstallationVersion(latestVersion, installationVersion(settings.minimumVersion)) || !!settings.requiredMaximumVersion && newerInstallationVersion(installationVersion(settings.requiredMaximumVersion), latestVersion);
61166
61787
  const canUpdate = !blocked && (npm?.canUpdate ?? native);
61167
61788
  update = async () => {
@@ -61192,7 +61813,7 @@ function createClaudeInstallation(environment, command) {
61192
61813
  }
61193
61814
 
61194
61815
  // dist/user-shell-environment.js
61195
- import path18 from "node:path";
61816
+ import path17 from "node:path";
61196
61817
  import { execFile as execFile4 } from "node:child_process";
61197
61818
  var ENVIRONMENT_MARKER = Buffer.from("\0CODEXHOST_USER_SHELL_ENV_V1\0");
61198
61819
  var ENVIRONMENT_COMMAND = "printf '\\0CODEXHOST_USER_SHELL_ENV_V1\\0'; /usr/bin/env -0";
@@ -61235,7 +61856,7 @@ async function withUserShellEnvironment(environment, dependencies) {
61235
61856
  if (platform === "win32" || !environment.HOME)
61236
61857
  return environment;
61237
61858
  const shell = environment.SHELL?.trim() || defaultShell(platform);
61238
- if (!shell || !SUPPORTED_SHELLS.has(path18.basename(shell)))
61859
+ if (!shell || !SUPPORTED_SHELLS.has(path17.basename(shell)))
61239
61860
  return environment;
61240
61861
  const cacheKey = `${platform}\0${shell}\0${environment.HOME}`;
61241
61862
  const cached2 = dependencies ? void 0 : shellEnvironmentCache.get(cacheKey);
@@ -61273,6 +61894,7 @@ async function createHarnessAdapter(context) {
61273
61894
  const environment = await withUserShellEnvironment({ ...context.environment });
61274
61895
  if (context.platform === "darwin" && context.managedRemoteHost) {
61275
61896
  return new BrokeredHarnessAdapter({
61897
+ sessionImport: true,
61276
61898
  forwardDelegationEnvironment: true,
61277
61899
  commandCatalog: claudeCommandCatalog,
61278
61900
  liveCommandCatalog: true,