@codexhost/cli-linux-arm64 0.13.2 → 0.14.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.
Files changed (33) hide show
  1. package/README.md +1 -1
  2. package/app/codexhost-distribution.json +1 -1
  3. package/app/console-server.mjs +94 -8
  4. package/app/console-web.js +537 -146
  5. package/app/desktop-controller.mjs +108 -12
  6. package/app/host-runtime.mjs +847 -235
  7. package/app/plugins/antigravity/plugin.mjs +143 -20
  8. package/app/plugins/claude-code/plugin.mjs +601 -71
  9. package/app/plugins/codebuddy/plugin.mjs +227 -30
  10. package/app/plugins/codex-usage/plugin.mjs +212 -77
  11. package/app/plugins/copilot/assets/icon.png +0 -0
  12. package/app/plugins/copilot/manifest.json +26 -0
  13. package/app/plugins/copilot/plugin.mjs +34546 -0
  14. package/app/plugins/cursor-cli/plugin.mjs +20805 -44862
  15. package/app/plugins/deepseek-harness/manifest.json +2 -2
  16. package/app/plugins/deepseek-harness/plugin.mjs +202 -21
  17. package/app/plugins/enabled.json +1 -0
  18. package/app/plugins/grok/plugin.mjs +278 -29
  19. package/app/plugins/hermes/plugin.mjs +143 -12
  20. package/app/plugins/kimi-code/plugin.mjs +140 -16
  21. package/app/plugins/kiro-cli/plugin.mjs +121 -10
  22. package/app/plugins/omp/plugin.mjs +2200 -2002
  23. package/app/plugins/opencode/plugin.mjs +137 -16
  24. package/app/plugins/pi/plugin.mjs +2563 -2282
  25. package/app/plugins/qoder/plugin.mjs +133 -14
  26. package/app/plugins/qoder-cn/plugin.mjs +133 -14
  27. package/app/plugins/workbuddy/plugin.mjs +603 -56
  28. package/app/plugins/zcode/plugin.mjs +133 -14
  29. package/app/renderer-extension.js +1171 -529
  30. package/bin/codexhost +0 -0
  31. package/libexec/codexhost-shim +0 -0
  32. package/libexec/codexhost-updater +0 -0
  33. package/package.json +1 -1
@@ -14604,6 +14604,15 @@ var harnessDisplaySetSchema = external_exports.strictObject({
14604
14604
  initializeOnly: external_exports.boolean().optional()
14605
14605
  });
14606
14606
 
14607
+ // ../../shared-contracts/dist/harness-presentation.js
14608
+ var localeSchema = external_exports.string().max(64).regex(/^[a-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$/u);
14609
+ var displayText = (maximum) => external_exports.string().min(1).max(maximum).refine((text2) => text2.trim().length > 0);
14610
+ var harnessLocalizationsSchema = external_exports.record(localeSchema, external_exports.object({
14611
+ label: displayText(256).optional(),
14612
+ description: displayText(1024).optional()
14613
+ }).strict()).refine((entries) => Object.keys(entries).length <= 16, "Too many locales");
14614
+ var harnessLocalizedTextSchema = external_exports.record(localeSchema, displayText(4096)).refine((entries) => typeof entries.en === "string", "English fallback is required").refine((entries) => Object.keys(entries).length <= 16, "Too many locales");
14615
+
14607
14616
  // ../../shared-contracts/dist/model-price-overrides.js
14608
14617
  var usdPerMillionTokens = external_exports.number().finite().nonnegative();
14609
14618
  var modelPriceOverrideSchema = external_exports.strictObject({
@@ -14653,10 +14662,19 @@ var model = external_exports.string().min(1).max(512);
14653
14662
  var project = external_exports.string().min(1).max(4096);
14654
14663
  var usageStatisticsParamsSchema = external_exports.strictObject({
14655
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(),
14656
14674
  harness: harness.optional(),
14657
14675
  model: model.nullable().optional(),
14658
14676
  project: project.nullable().optional(),
14659
- /** One local date inside the range. */
14677
+ /** One date in the query timezone inside the range. */
14660
14678
  date: localDate.optional()
14661
14679
  });
14662
14680
  var usageStatisticsTotalsSchema = external_exports.strictObject({
@@ -14692,7 +14710,7 @@ var usageStatisticsSessionSchema = external_exports.strictObject({
14692
14710
  });
14693
14711
  var usageStatisticsResultSchema = external_exports.strictObject({
14694
14712
  range: external_exports.enum(USAGE_STATISTICS_RANGES),
14695
- /** 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. */
14696
14714
  from: localDate.nullable(),
14697
14715
  to: localDate,
14698
14716
  /** The filters these figures apply, echoed so a late answer to older filters is recognised. */
@@ -14732,7 +14750,7 @@ var usageStatisticsResultSchema = external_exports.strictObject({
14732
14750
  totals: usageStatisticsTotalsSchema,
14733
14751
  /** Each date and Harness of the range: every filter except the day. */
14734
14752
  daily: external_exports.array(external_exports.strictObject({ date: localDate, harness, ...totals })).max(2e5),
14735
- /** Local weekday (0 = Sunday) and hour, all filters applied. */
14753
+ /** Weekday (0 = Sunday) and hour in the query timezone, all filters applied. */
14736
14754
  hourly: external_exports.array(external_exports.strictObject({
14737
14755
  weekday: external_exports.number().int().min(0).max(6),
14738
14756
  hour: external_exports.number().int().min(0).max(23),
@@ -14792,6 +14810,8 @@ var CONSOLE_HOST_METHODS = Object.freeze([
14792
14810
  "codexhost/harness/display-settings/set",
14793
14811
  "codexhost/harness/inspect",
14794
14812
  "codexhost/harness/installation",
14813
+ "codexhost/harness/installation/start",
14814
+ "codexhost/harness/installation/status",
14795
14815
  "codexhost/harness/launch-settings/get",
14796
14816
  "codexhost/harness/launch-settings/set",
14797
14817
  "codexhost/harness/web-ui/open",
@@ -14867,7 +14887,18 @@ var threadManualCompactionStartedSchema = external_exports.strictObject({
14867
14887
  var nonNegativeSafeIntegerSchema = external_exports.number().int().safe().nonnegative();
14868
14888
  var finiteNonNegativeNumberSchema = external_exports.number().finite().nonnegative();
14869
14889
  var cacheHitRatePercentSchema = external_exports.number().finite().min(0).max(100);
14890
+ var indicatorTextSchema = (maximum) => harnessLocalizedTextSchema.refine((entries) => Object.values(entries).every((text2) => text2.length <= maximum));
14891
+ var composerIndicatorsSchema = external_exports.array(external_exports.object({
14892
+ kind: external_exports.literal("countdown"),
14893
+ id: external_exports.string().min(1).max(64),
14894
+ expiresAtUnix: nonNegativeSafeIntegerSchema,
14895
+ label: indicatorTextSchema(256).optional(),
14896
+ tooltip: indicatorTextSchema(1024).optional()
14897
+ }).strict()).max(2).refine((entries) => new Set(entries.map(({ id: id2 }) => id2)).size === entries.length, {
14898
+ message: "Composer indicator IDs must be unique"
14899
+ });
14870
14900
  var threadUsageSnapshotSchema = external_exports.object({
14901
+ composerIndicators: composerIndicatorsSchema.optional(),
14871
14902
  inputTokens: nonNegativeSafeIntegerSchema.optional(),
14872
14903
  cachedInputTokens: nonNegativeSafeIntegerSchema.optional(),
14873
14904
  cacheWriteInputTokens: nonNegativeSafeIntegerSchema.optional(),
@@ -14940,8 +14971,24 @@ var threadUsageSnapshotSchema = external_exports.object({
14940
14971
  }
14941
14972
  });
14942
14973
  var usagePercentSchema = external_exports.number().finite().min(0).max(100);
14974
+ var accountCreditsPeriodSchema = external_exports.enum([
14975
+ "weekly",
14976
+ "monthly",
14977
+ "five_hour",
14978
+ "seven_day",
14979
+ "unknown"
14980
+ ]);
14981
+ var accountCreditsScopeSchema = external_exports.object({
14982
+ id: external_exports.string().min(1).max(256),
14983
+ label: external_exports.string().min(1).max(256),
14984
+ localizations: harnessLocalizationsSchema.optional()
14985
+ }).strict();
14943
14986
  var accountCreditsProductUsageSchema = external_exports.object({
14944
14987
  product: external_exports.string().min(1),
14988
+ /** Native period and scope, never inferred from the display name. */
14989
+ periodType: accountCreditsPeriodSchema.optional(),
14990
+ scope: accountCreditsScopeSchema.optional(),
14991
+ localizations: harnessLocalizationsSchema.optional(),
14945
14992
  used: external_exports.number().finite().nonnegative().optional(),
14946
14993
  // Zero is a real empty cap, not an absent field.
14947
14994
  limit: external_exports.number().finite().nonnegative().optional(),
@@ -14961,9 +15008,11 @@ var accountCreditsSnapshotSchema = external_exports.object({
14961
15008
  unit: external_exports.string().min(1).max(32).optional(),
14962
15009
  /** Native label when the primary limit is scoped to a model or product group. */
14963
15010
  label: external_exports.string().min(1).optional(),
15011
+ scope: accountCreditsScopeSchema.optional(),
15012
+ localizations: harnessLocalizationsSchema.optional(),
14964
15013
  usedPercent: usagePercentSchema,
14965
15014
  resetsAt: external_exports.string().min(1).optional(),
14966
- periodType: external_exports.enum(["weekly", "monthly", "five_hour", "seven_day", "unknown"]),
15015
+ periodType: accountCreditsPeriodSchema,
14967
15016
  productUsage: external_exports.array(accountCreditsProductUsageSchema).min(1).optional(),
14968
15017
  resetCredits: accountResetCreditsSchema.optional()
14969
15018
  }).strict();
@@ -14974,7 +15023,9 @@ var threadUsageInspectionParamsSchema = external_exports.object({
14974
15023
  var threadUsageInspectionSchema = external_exports.object({
14975
15024
  threadId: hostThreadIdSchema,
14976
15025
  usage: threadUsageSnapshotSchema.nullable(),
14977
- accountCredits: accountCreditsSnapshotSchema.optional()
15026
+ accountCredits: accountCreditsSnapshotSchema.optional(),
15027
+ /** Whether this source can provide cached account quota independently of usage. */
15028
+ accountCreditsSupported: external_exports.boolean().optional()
14978
15029
  }).strict();
14979
15030
 
14980
15031
  // ../../shared-contracts/dist/harness-accounts.js
@@ -15101,7 +15152,8 @@ var harnessPermissionModeSchema = external_exports.object({
15101
15152
  id: harnessPermissionModeIdSchema,
15102
15153
  label: nonBlankTextSchema.max(HARNESS_PERMISSION_MODE_LABEL_MAX_LENGTH),
15103
15154
  description: nonBlankTextSchema.max(HARNESS_PERMISSION_MODE_DESCRIPTION_MAX_LENGTH).optional(),
15104
- dangerous: external_exports.boolean().optional()
15155
+ dangerous: external_exports.boolean().optional(),
15156
+ localizations: harnessLocalizationsSchema.optional()
15105
15157
  }).strict();
15106
15158
  var harnessPermissionModeCatalogSchema = external_exports.object({
15107
15159
  modes: external_exports.array(harnessPermissionModeSchema).min(1).max(HARNESS_PERMISSION_MODE_CATALOG_MAX_LENGTH),
@@ -15254,7 +15306,9 @@ var harnessSessionCapabilitiesSchema = external_exports.object({
15254
15306
  }).strict().optional(),
15255
15307
  autonomousTurns: external_exports.object({
15256
15308
  observe: external_exports.boolean()
15257
- }).strict().optional()
15309
+ }).strict().optional(),
15310
+ /** True only when `turn.steer` delivers input into the active Turn through a native primitive. */
15311
+ steer: external_exports.boolean().optional()
15258
15312
  }).strict();
15259
15313
  var harnessConfigurationStateSchema = external_exports.object({
15260
15314
  effectiveModel: harnessModelRefSchema.optional(),
@@ -15301,7 +15355,9 @@ var harnessInspectionSchema = external_exports.union([
15301
15355
  var harnessInspectParamsSchema = external_exports.object({
15302
15356
  harnessId: harnessIdSchema,
15303
15357
  cwd: nonBlankTextSchema2.max(16384).optional(),
15304
- refresh: external_exports.boolean().optional()
15358
+ refresh: external_exports.boolean().optional(),
15359
+ /** `availability` asks only whether the Harness can run; see `InspectHarnessInput.purpose`. */
15360
+ purpose: external_exports.literal("availability").optional()
15305
15361
  }).strict();
15306
15362
  var harnessWebUiOpenParamsSchema = external_exports.object({
15307
15363
  harnessId: harnessIdSchema
@@ -15384,6 +15440,15 @@ var threadOwnershipListResultSchema = external_exports.object({
15384
15440
  seen.add(thread.threadId);
15385
15441
  }
15386
15442
  });
15443
+ var threadSteeringInspectParamsSchema = external_exports.object({
15444
+ threadId: hostThreadIdSchema,
15445
+ /** The text about to be steered; a Harness command always stops and restarts. */
15446
+ text: external_exports.string().optional()
15447
+ }).strict();
15448
+ var threadSteerDeliverySchema = external_exports.enum(["activeTurn", "newTurn"]);
15449
+ var threadSteeringInspectResultSchema = external_exports.object({
15450
+ delivery: external_exports.enum(["official", "activeTurn", "newTurn"])
15451
+ }).strict();
15387
15452
 
15388
15453
  // ../../shared-contracts/dist/harness-plugins.js
15389
15454
  var HARNESS_PLUGIN_MANIFEST_MAX_BYTES = 32 * 1024;
@@ -15485,11 +15550,31 @@ var harnessInstallationStateSchema = external_exports.object({
15485
15550
  latestVersion: external_exports.string().min(1).max(128),
15486
15551
  updateAvailable: external_exports.boolean(),
15487
15552
  canUpdate: external_exports.boolean(),
15553
+ /** Defaults to CLI; some Harnesses ship only inside a desktop application. */
15554
+ versionKind: external_exports.enum(["cli", "application"]).optional(),
15555
+ /** Official download opened by the user; does not imply an automatic installation. */
15556
+ manualUpdateUrl: external_exports.url().max(2048).refine((value) => /^https:\/\/[^/?#@]+(?:[/?#]|$)/iu.test(value), "Manual updates require a credential-free HTTPS URL").optional(),
15488
15557
  // Adapter-owned diagnostic text; UI uses messageCode rather than displaying it verbatim.
15489
15558
  message: external_exports.string().max(2048).optional(),
15490
15559
  messageCode: external_exports.string().min(1).max(128).optional(),
15560
+ /** Safe plugin-owned explanation, distinct from raw diagnostic message. */
15561
+ notice: harnessLocalizedTextSchema.optional(),
15491
15562
  latestVersionKind: external_exports.enum(["unknown", "tracking-branch"]).optional()
15492
15563
  }).strict();
15564
+ var harnessInstallationTaskParamsSchema = external_exports.object({ taskId: external_exports.string().uuid() }).strict();
15565
+ var harnessInstallationTaskSchema = external_exports.discriminatedUnion("status", [
15566
+ external_exports.object({ taskId: external_exports.string().uuid(), status: external_exports.literal("running") }).strict(),
15567
+ external_exports.object({
15568
+ taskId: external_exports.string().uuid(),
15569
+ status: external_exports.literal("succeeded"),
15570
+ result: harnessInstallationStateSchema
15571
+ }).strict(),
15572
+ external_exports.object({
15573
+ taskId: external_exports.string().uuid(),
15574
+ status: external_exports.literal("failed"),
15575
+ error: external_exports.object({ code: external_exports.number().int(), message: external_exports.string().min(1).max(2048) }).strict()
15576
+ }).strict()
15577
+ ]);
15493
15578
 
15494
15579
  // ../../shared-contracts/dist/codex-accounts.js
15495
15580
  var accountIdSchema = external_exports.string().min(1).max(256).regex(/^[A-Za-z0-9._~-]+$/u);
@@ -15614,6 +15699,7 @@ var harnessCommandDescriptorSchema = external_exports.object({
15614
15699
  invocation: commandInvocationSchema,
15615
15700
  label: commandLabelSchema,
15616
15701
  description: commandDescriptionSchema.optional(),
15702
+ localizations: harnessLocalizationsSchema.optional(),
15617
15703
  argumentMode: external_exports.enum(["none", "text"]),
15618
15704
  /**
15619
15705
  * Native distinction reported by the Harness. Omitted when the Harness does
@@ -16001,6 +16087,7 @@ var usageFields = /* @__PURE__ */ new Set([
16001
16087
  ...safeIntegerFields,
16002
16088
  ...percentFields,
16003
16089
  "sessionCacheUsage",
16090
+ "composerIndicators",
16004
16091
  "totalCostUsd",
16005
16092
  "totalCredits",
16006
16093
  "contextUsagePercent",
@@ -16023,6 +16110,7 @@ function parseHostUsage(value) {
16023
16110
  throw new Error(`Harness Usage contains unknown field '${key}'`);
16024
16111
  }
16025
16112
  }
16113
+ const indicators = value.composerIndicators === void 0 ? {} : { composerIndicators: composerIndicatorsSchema.parse(value.composerIndicators) };
16026
16114
  for (const field of [
16027
16115
  "totalCredits",
16028
16116
  "contextUsagePercent",
@@ -16093,9 +16181,9 @@ function parseHostUsage(value) {
16093
16181
  if (value.costSource !== "publicPrice") {
16094
16182
  throw new Error("Harness Usage 'unpricedModels' must be provided with a 'publicPrice' cost");
16095
16183
  }
16096
- return { ...value, unpricedModels: [...models] };
16184
+ return { ...value, ...indicators, unpricedModels: [...models] };
16097
16185
  }
16098
- return { ...value };
16186
+ return { ...value, ...indicators };
16099
16187
  }
16100
16188
  var requestTokenFields = [
16101
16189
  "inputTokens",
@@ -16294,6 +16382,7 @@ var harnessBrokerMethodSchema = external_exports.enum([
16294
16382
  "adapter.open",
16295
16383
  "adapter.subagent.readSnapshot",
16296
16384
  "session.readSnapshot",
16385
+ "session.readCapabilities",
16297
16386
  "session.refreshUsage",
16298
16387
  "session.execute",
16299
16388
  "session.commands.list",
@@ -16474,6 +16563,11 @@ var turnStartSchema = external_exports.object({
16474
16563
  turnId: hostTurnIdSchema,
16475
16564
  input: external_exports.array(textInputSchema)
16476
16565
  }).strict();
16566
+ var turnSteerSchema = external_exports.object({
16567
+ type: external_exports.literal("turn.steer"),
16568
+ turnId: hostTurnIdSchema,
16569
+ input: external_exports.array(textInputSchema)
16570
+ }).strict();
16477
16571
  var turnCancelSchema = external_exports.object({ type: external_exports.literal("turn.cancel"), turnId: hostTurnIdSchema }).strict();
16478
16572
  var interactionResponseSchema = external_exports.union([
16479
16573
  external_exports.object({
@@ -16499,6 +16593,7 @@ var permissionSelectSchema = external_exports.object({
16499
16593
  }).strict();
16500
16594
  var brokerHostCommandSchema = external_exports.discriminatedUnion("type", [
16501
16595
  turnStartSchema,
16596
+ turnSteerSchema,
16502
16597
  turnCancelSchema,
16503
16598
  interactionRespondSchema,
16504
16599
  modelSelectSchema,
@@ -16691,6 +16786,7 @@ function parseSessionMetadata(value) {
16691
16786
  sessionId: candidate.sessionId,
16692
16787
  sessionGeneration: candidate.sessionGeneration,
16693
16788
  capabilities: harnessSessionCapabilitiesSchema.parse(candidate.capabilities),
16789
+ readCapabilities: candidate.readCapabilities === true,
16694
16790
  initialState: state,
16695
16791
  initialUsage: candidate.initialUsage === null ? null : parseHostUsage(candidate.initialUsage),
16696
16792
  commands: candidate.commands === true
@@ -17042,6 +17138,11 @@ var BrokeredHarnessSession = class {
17042
17138
  event: { type: "session.faulted", error: unavailable(error52.message) }
17043
17139
  });
17044
17140
  }
17141
+ async readCapabilities() {
17142
+ if (!this.#metadata.readCapabilities)
17143
+ return { ...this.capabilities, steer: false };
17144
+ return harnessSessionCapabilitiesSchema.parse(await this.#request("session.readCapabilities", {}));
17145
+ }
17045
17146
  async refreshUsage() {
17046
17147
  await this.#request("session.refreshUsage", {});
17047
17148
  }
@@ -17073,6 +17174,8 @@ var BrokeredHarnessSession = class {
17073
17174
  try {
17074
17175
  return parseHarnessResult(await this.#request("session.execute", { command }));
17075
17176
  } catch (error52) {
17177
+ if (command.type === "turn.steer")
17178
+ throw error52;
17076
17179
  return {
17077
17180
  ok: false,
17078
17181
  error: unavailable(error52 instanceof Error ? error52.message : String(error52))
@@ -17160,6 +17263,8 @@ var BrokeredHarnessAdapter = class {
17160
17263
  commandCatalog;
17161
17264
  liveCommandCatalog;
17162
17265
  harnessId;
17266
+ credits;
17267
+ refreshCredits;
17163
17268
  #descriptorPath;
17164
17269
  #forwardEnvironment;
17165
17270
  #isInstalled;
@@ -17180,6 +17285,10 @@ var BrokeredHarnessAdapter = class {
17180
17285
  };
17181
17286
  constructor(input = {}) {
17182
17287
  this.harnessId = harnessPluginIdSchema.parse(input.harnessId ?? "claude-code");
17288
+ if (input.accountCredits !== false) {
17289
+ this.credits = () => this.#credits;
17290
+ this.refreshCredits = () => this.#refreshAccountCredits();
17291
+ }
17183
17292
  this.#forwardEnvironment = input.forwardDelegationEnvironment === true;
17184
17293
  if (input.commandCatalog)
17185
17294
  this.commandCatalog = input.commandCatalog;
@@ -17191,10 +17300,7 @@ var BrokeredHarnessAdapter = class {
17191
17300
  this.#startBroker = input.startBroker === false ? void 0 : input.startBroker ?? (process.platform === "darwin" && !input.descriptorPath ? () => startBrokerLaunchAgent(this.harnessId, environment) : void 0);
17192
17301
  this.#startTimeoutMs = input.startTimeoutMs ?? BROKER_START_TIMEOUT_MS;
17193
17302
  }
17194
- credits() {
17195
- return this.#credits;
17196
- }
17197
- refreshCredits() {
17303
+ #refreshAccountCredits() {
17198
17304
  if (this.#closed)
17199
17305
  return Promise.resolve(null);
17200
17306
  if (this.#creditsRefresh)
@@ -17456,10 +17562,13 @@ function usageSessionTitle(value) {
17456
17562
  return void 0;
17457
17563
  if (normalized.length <= MAX_SESSION_TITLE_LENGTH)
17458
17564
  return normalized;
17459
- const characters = [...normalized];
17460
- if (characters.length <= MAX_SESSION_TITLE_LENGTH)
17461
- return normalized;
17462
- return `${characters.slice(0, MAX_SESSION_TITLE_LENGTH - 1).join("").trimEnd()}…`;
17565
+ let title = "";
17566
+ for (const character of normalized) {
17567
+ if (title.length + character.length >= MAX_SESSION_TITLE_LENGTH)
17568
+ break;
17569
+ title += character;
17570
+ }
17571
+ return `${title.trimEnd()}…`;
17463
17572
  }
17464
17573
  function sessionIdOk(value) {
17465
17574
  return typeof value === "string" && value.length > 0 && value.length <= MAX_SESSION_ID_LENGTH;
@@ -17612,8 +17721,33 @@ function createClaudeUsageStatistics(environment) {
17612
17721
  });
17613
17722
  }
17614
17723
 
17724
+ // dist/claude-prompt-cache.js
17725
+ function lastClaudeAssistantResponseUnix(messages) {
17726
+ let latest;
17727
+ for (const entry of messages) {
17728
+ 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")
17729
+ continue;
17730
+ const time3 = Math.floor(Date.parse(entry.timestamp) / 1e3);
17731
+ if (Number.isSafeInteger(time3) && time3 >= 0)
17732
+ latest = Math.max(latest ?? 0, time3);
17733
+ }
17734
+ return latest;
17735
+ }
17736
+ function claudePromptCacheIndicators(accountCreditsSupported, lastResponseAtUnix) {
17737
+ if (!accountCreditsSupported || lastResponseAtUnix === void 0)
17738
+ return [];
17739
+ return [
17740
+ {
17741
+ kind: "countdown",
17742
+ id: "prompt-cache",
17743
+ expiresAtUnix: lastResponseAtUnix + 3600,
17744
+ label: { en: "Prompt cache", "zh-CN": "提示词缓存" }
17745
+ }
17746
+ ];
17747
+ }
17748
+
17615
17749
  // dist/claude-code-adapter.js
17616
- import { randomUUID as randomUUID4 } from "node:crypto";
17750
+ import { randomUUID as randomUUID5 } from "node:crypto";
17617
17751
  import path16 from "node:path";
17618
17752
 
17619
17753
  // ../../../node_modules/@anthropic-ai/claude-agent-sdk/sdk.mjs
@@ -54412,11 +54546,20 @@ function parseResultModelUsage(value) {
54412
54546
  if (!isRecord7(value))
54413
54547
  return void 0;
54414
54548
  const usage = [];
54415
- for (const entry of Object.values(value)) {
54549
+ for (const [model2, entry] of Object.entries(value)) {
54416
54550
  if (!isRecord7(entry) || !safeNonNegativeInteger(entry.inputTokens) || !safeNonNegativeInteger(entry.outputTokens)) {
54417
54551
  return void 0;
54418
54552
  }
54419
- usage.push({ inputTokens: entry.inputTokens, outputTokens: entry.outputTokens });
54553
+ const cacheRead = safeNonNegativeInteger(entry.cacheReadInputTokens) ? entry.cacheReadInputTokens : 0;
54554
+ const cacheWrite = safeNonNegativeInteger(entry.cacheCreationInputTokens) ? entry.cacheCreationInputTokens : 0;
54555
+ const promptTokens = entry.inputTokens + cacheRead + cacheWrite;
54556
+ usage.push({
54557
+ model: model2,
54558
+ inputTokens: entry.inputTokens,
54559
+ outputTokens: entry.outputTokens,
54560
+ ...Number.isSafeInteger(promptTokens) ? { promptTokens } : {},
54561
+ ...safeNonNegativeInteger(entry.contextWindow) && entry.contextWindow > 0 ? { contextWindowTokens: entry.contextWindow } : {}
54562
+ });
54420
54563
  }
54421
54564
  return usage;
54422
54565
  }
@@ -54767,6 +54910,7 @@ var ClaudeNativeTurnAccumulator = class {
54767
54910
  events.push({
54768
54911
  type: "message.completed",
54769
54912
  messageId,
54913
+ localCommand: true,
54770
54914
  ...checkpointId ? { checkpointId } : {}
54771
54915
  });
54772
54916
  }
@@ -55247,6 +55391,10 @@ function conversationMessages(values, sessionId) {
55247
55391
  const messages = [];
55248
55392
  const ids = /* @__PURE__ */ new Set();
55249
55393
  let promptId = null;
55394
+ const occupancy = new ClaudeBackgroundOccupancy();
55395
+ let accumulator = new ClaudeNativeTurnAccumulator();
55396
+ const sends = /* @__PURE__ */ new Set();
55397
+ let pendingNotification = false;
55250
55398
  for (const value of values) {
55251
55399
  if (!isRecord8(value))
55252
55400
  throw new Error("Claude history contains a malformed message");
@@ -55265,8 +55413,46 @@ function conversationMessages(values, sessionId) {
55265
55413
  message: value.message,
55266
55414
  nested: typeof value.parent_tool_use_id === "string" && value.parent_tool_use_id.length > 0,
55267
55415
  interrupted,
55416
+ startsTurn: false,
55268
55417
  syntheticUser: value.type === "user" && (interrupted || value.isSynthetic === true || value.isMeta === true || isTaskNotificationOrigin(value) || value.toolUseResult !== void 0 && value.toolUseResult !== null)
55269
55418
  };
55419
+ const notification = message.type === "user" && !message.nested && (isTaskNotificationOrigin(value) || textParts(message.message.content).some(isTaskNotificationRecord));
55420
+ message.startsTurn = isHumanUser(message) || notification && !occupancy.unsettled && !pendingNotification;
55421
+ if (message.startsTurn) {
55422
+ occupancy.clear();
55423
+ sends.clear();
55424
+ accumulator = new ClaudeNativeTurnAccumulator();
55425
+ }
55426
+ for (const event of accumulator.consume(value).events) {
55427
+ if (event.type === "subagent.started") {
55428
+ if (event.operation === "send") {
55429
+ sends.add(event.callId);
55430
+ if (event.nativeSubagentId)
55431
+ occupancy.occupyAgent(event.nativeSubagentId);
55432
+ } else if (event.background)
55433
+ occupancy.occupySpawn(event.callId, event.nativeSubagentId);
55434
+ } else if (event.type === "subagent.completed") {
55435
+ if (!event.isError && (event.continuesInBackground || sends.has(event.callId))) {
55436
+ occupancy.occupySpawn(event.callId, event.nativeSubagentId);
55437
+ } else
55438
+ occupancy.release(event.callId, event.nativeSubagentId);
55439
+ sends.delete(event.callId);
55440
+ } else if (event.type === "workflow.launched" && event.background && !event.isError) {
55441
+ occupancy.occupySpawn(event.callId, event.taskId);
55442
+ } else if (event.type === "subagent.settled") {
55443
+ occupancy.notify(event.callId, event.nativeSubagentId);
55444
+ }
55445
+ }
55446
+ if (notification)
55447
+ pendingNotification = true;
55448
+ if (message.type === "assistant" && !message.nested) {
55449
+ pendingNotification = false;
55450
+ if (["end_turn", "stop_sequence", "max_tokens"].includes(String(message.message.stop_reason))) {
55451
+ occupancy.releaseContinuations();
55452
+ }
55453
+ }
55454
+ if (interrupted)
55455
+ occupancy.clear();
55270
55456
  messages.push(message);
55271
55457
  if (isHumanUser(message)) {
55272
55458
  promptId = typeof value.promptId === "string" && value.promptId.length > 0 ? value.promptId : null;
@@ -55323,17 +55509,17 @@ function mapClaudeSnapshot(values, sessionId) {
55323
55509
  const turns = [];
55324
55510
  for (let index = 0; index < messages.length; ) {
55325
55511
  const user = messages[index];
55326
- if (!user || !isHumanUser(user)) {
55512
+ if (!user || !user.startsTurn) {
55327
55513
  index += 1;
55328
55514
  continue;
55329
55515
  }
55330
55516
  let end = index + 1;
55331
- while (end < messages.length && !isHumanUser(messages[end]))
55517
+ while (end < messages.length && !messages[end]?.startsTurn)
55332
55518
  end += 1;
55333
55519
  const turnMessages = messages.slice(index, end);
55334
55520
  const outcome = turnOutcome(turnMessages);
55335
55521
  const results = toolResultBlocks(turnMessages);
55336
- const checkpointMessage = turnMessages.findLast(({ type, interrupted }) => type === "assistant" || interrupted);
55522
+ const checkpointMessage = turnMessages.findLast(({ type, interrupted, nested }) => !nested && (type === "assistant" || interrupted));
55337
55523
  let agentMessageOrdinal = 0;
55338
55524
  let reasoningOrdinal = 0;
55339
55525
  let toolOrdinal = 0;
@@ -55821,6 +56007,10 @@ async function forkClaudeSession(input) {
55821
56007
  return { ok: true, value: { sessionId: derivedSessionId } };
55822
56008
  }
55823
56009
 
56010
+ // dist/claude-fork-references.js
56011
+ import { randomUUID as randomUUID4 } from "node:crypto";
56012
+ import { readFile as readFile6, rename as rename4, rm as rm5, stat as stat5, writeFile as writeFile2 } from "node:fs/promises";
56013
+
55824
56014
  // dist/claude-transcript.js
55825
56015
  import os6 from "node:os";
55826
56016
  import path13 from "node:path";
@@ -55838,7 +56028,7 @@ async function existingFile(file2) {
55838
56028
  return false;
55839
56029
  }
55840
56030
  }
55841
- async function findTranscript(input) {
56031
+ async function findClaudeTranscript(input) {
55842
56032
  const projectsDirectory = path13.join(configDirectory(input.environment), "projects");
55843
56033
  const name = `${input.sessionId}.jsonl`;
55844
56034
  const expected = path13.join(projectsDirectory, projectDirectoryName(input.cwd), name);
@@ -55861,7 +56051,7 @@ function isRecord9(value) {
55861
56051
  return typeof value === "object" && value !== null && !Array.isArray(value);
55862
56052
  }
55863
56053
  async function readClaudeTranscript(input) {
55864
- const transcript = await findTranscript(input);
56054
+ const transcript = await findClaudeTranscript(input);
55865
56055
  if (!transcript)
55866
56056
  return null;
55867
56057
  const contents = await readFile5(transcript, "utf8");
@@ -55883,9 +56073,83 @@ async function readClaudeTranscript(input) {
55883
56073
  return [...messages.values()];
55884
56074
  }
55885
56075
 
56076
+ // dist/claude-fork-references.js
56077
+ function isRecord10(value) {
56078
+ return typeof value === "object" && value !== null && !Array.isArray(value);
56079
+ }
56080
+ function parseEntry(line) {
56081
+ if (line.trim().length === 0)
56082
+ return null;
56083
+ try {
56084
+ const entry = JSON.parse(line);
56085
+ return isRecord10(entry) ? entry : null;
56086
+ } catch {
56087
+ return null;
56088
+ }
56089
+ }
56090
+ function remapSameAs(value, copies) {
56091
+ if (Array.isArray(value)) {
56092
+ return value.reduce((count4, item) => count4 + remapSameAs(item, copies), 0);
56093
+ }
56094
+ if (!isRecord10(value))
56095
+ return 0;
56096
+ let count3 = 0;
56097
+ for (const [key, child] of Object.entries(value)) {
56098
+ const copy = key === "sameAs" && typeof child === "string" ? copies.get(child) : void 0;
56099
+ if (copy) {
56100
+ value[key] = copy;
56101
+ count3 += 1;
56102
+ } else {
56103
+ count3 += remapSameAs(child, copies);
56104
+ }
56105
+ }
56106
+ return count3;
56107
+ }
56108
+ async function remapForkedSessionReferences(input) {
56109
+ const transcript = await findClaudeTranscript(input);
56110
+ if (!transcript)
56111
+ return 0;
56112
+ const contents = await readFile6(transcript, "utf8");
56113
+ if (!contents.includes('"sameAs"'))
56114
+ return 0;
56115
+ const lines = contents.split("\n");
56116
+ const entries = lines.map(parseEntry);
56117
+ const copies = /* @__PURE__ */ new Map();
56118
+ for (const entry of entries) {
56119
+ const source = entry?.forkedFrom;
56120
+ if (typeof entry?.uuid === "string" && isRecord10(source) && typeof source.messageUuid === "string") {
56121
+ copies.set(source.messageUuid, entry.uuid);
56122
+ }
56123
+ }
56124
+ let remapped = 0;
56125
+ const output = lines.map((line, index) => {
56126
+ const entry = entries[index];
56127
+ if (entry?.type !== "attachment")
56128
+ return line;
56129
+ const count3 = remapSameAs(entry.attachment, copies);
56130
+ if (count3 === 0)
56131
+ return line;
56132
+ remapped += count3;
56133
+ return JSON.stringify(entry);
56134
+ });
56135
+ if (remapped === 0)
56136
+ return 0;
56137
+ const temporary = `${transcript}.${randomUUID4()}.tmp`;
56138
+ try {
56139
+ await writeFile2(temporary, output.join("\n"), {
56140
+ flag: "wx",
56141
+ mode: (await stat5(transcript)).mode & 511
56142
+ });
56143
+ await rename4(temporary, transcript);
56144
+ } finally {
56145
+ await rm5(temporary, { force: true });
56146
+ }
56147
+ return remapped;
56148
+ }
56149
+
55886
56150
  // dist/model-catalog.js
55887
56151
  import { Buffer as Buffer2 } from "node:buffer";
55888
- import { readFile as readFile6 } from "node:fs/promises";
56152
+ import { readFile as readFile7 } from "node:fs/promises";
55889
56153
  import os7 from "node:os";
55890
56154
  import path14 from "node:path";
55891
56155
 
@@ -56025,7 +56289,7 @@ async function readClaudeUserModelPicker(environment = process.env) {
56025
56289
  const settingsPath = path14.join(resolveClaudeConfigDirectory(environment), "settings.json");
56026
56290
  let raw;
56027
56291
  try {
56028
- raw = await readFile6(settingsPath, "utf8");
56292
+ raw = await readFile7(settingsPath, "utf8");
56029
56293
  } catch {
56030
56294
  return void 0;
56031
56295
  }
@@ -56184,26 +56448,38 @@ var claudePermissionModes = [
56184
56448
  {
56185
56449
  id: "plan",
56186
56450
  label: "Plan mode",
56451
+ localizations: {
56452
+ "zh-CN": {
56453
+ label: "规划模式",
56454
+ description: "探索并制定计划;批准计划后退出规划,恢复此前的权限模式。"
56455
+ }
56456
+ },
56187
56457
  description: "Explore and prepare a plan; approval exits planning and resumes the previous permission mode."
56188
56458
  },
56189
56459
  {
56190
56460
  id: "default",
56191
56461
  label: "Default",
56462
+ localizations: { "zh-CN": { label: "默认", description: "编辑和其他受保护操作前询问。" } },
56192
56463
  description: "Ask before edits and other protected actions."
56193
56464
  },
56194
56465
  {
56195
56466
  id: "acceptEdits",
56196
56467
  label: "Accept edits",
56468
+ localizations: {
56469
+ "zh-CN": { label: "接受编辑", description: "允许文件编辑;其他受保护操作前询问。" }
56470
+ },
56197
56471
  description: "Allow file edits and ask for other protected actions."
56198
56472
  },
56199
56473
  {
56200
56474
  id: "auto",
56201
56475
  label: "Auto mode",
56476
+ localizations: { "zh-CN": { label: "自动模式", description: "由 Claude 判断权限请求。" } },
56202
56477
  description: "Let Claude classify permission requests."
56203
56478
  },
56204
56479
  {
56205
56480
  id: "bypassPermissions",
56206
56481
  label: "Bypass permissions",
56482
+ localizations: { "zh-CN": { label: "绕过权限", description: "跳过 Claude Code 权限检查。" } },
56207
56483
  description: "Skip Claude Code permission checks.",
56208
56484
  dangerous: true
56209
56485
  }
@@ -56310,23 +56586,24 @@ function projectClaudeAccountUsage(usage, account) {
56310
56586
  return null;
56311
56587
  const limits = usage.rate_limits;
56312
56588
  const windows = [];
56313
- const add = (product, periodType, value) => {
56589
+ const add = (product, periodType, value, scope) => {
56314
56590
  if (!value || typeof value.utilization !== "number" || !Number.isFinite(value.utilization) || value.utilization < 0 || value.utilization > 100)
56315
56591
  return;
56316
56592
  windows.push({
56317
56593
  product,
56318
56594
  periodType,
56595
+ ...scope ? { scope: { id: scope, label: scope } } : {},
56319
56596
  usagePercent: value.utilization,
56320
56597
  ...value.resets_at && Number.isFinite(Date.parse(value.resets_at)) ? { resetsAt: value.resets_at } : {}
56321
56598
  });
56322
56599
  };
56323
56600
  add("5-hour window", "five_hour", limits.five_hour);
56324
56601
  add("7-day window", "seven_day", limits.seven_day);
56325
- add("OAuth apps · 7-day", "seven_day", limits.seven_day_oauth_apps);
56326
- add("Opus · 7-day", "seven_day", limits.seven_day_opus);
56327
- add("Sonnet · 7-day", "seven_day", limits.seven_day_sonnet);
56602
+ add("OAuth apps · 7-day", "seven_day", limits.seven_day_oauth_apps, "OAuth apps");
56603
+ add("Opus · 7-day", "seven_day", limits.seven_day_opus, "Opus");
56604
+ add("Sonnet · 7-day", "seven_day", limits.seven_day_sonnet, "Sonnet");
56328
56605
  for (const window2 of limits.model_scoped ?? [])
56329
- add(`${window2.display_name} · 7-day`, "seven_day", window2);
56606
+ add(`${window2.display_name} · 7-day`, "seven_day", window2, window2.display_name);
56330
56607
  const [primary, ...others] = windows;
56331
56608
  if (!primary)
56332
56609
  return null;
@@ -56337,11 +56614,14 @@ function projectClaudeAccountUsage(usage, account) {
56337
56614
  credits: {
56338
56615
  usedPercent: primary.usagePercent,
56339
56616
  periodType: primary.periodType,
56617
+ ...primary.scope ? { scope: primary.scope } : {},
56340
56618
  ...!genericPrimary ? { label: primary.product } : {},
56341
56619
  ...primary.resetsAt ? { resetsAt: primary.resetsAt } : {},
56342
56620
  ...others.length ? {
56343
- productUsage: others.map(({ product, usagePercent, resetsAt }) => ({
56621
+ productUsage: others.map(({ product, periodType, scope, usagePercent, resetsAt }) => ({
56344
56622
  product,
56623
+ periodType,
56624
+ ...scope ? { scope } : {},
56345
56625
  usagePercent,
56346
56626
  ...resetsAt ? { resetsAt } : {}
56347
56627
  }))
@@ -56403,12 +56683,21 @@ async function closeClaudeProcessGroup(child, timeoutMs) {
56403
56683
  throw new Error("Claude SDK process group did not exit");
56404
56684
  }
56405
56685
 
56686
+ // dist/transport.js
56687
+ var ClaudeSteerMissedTurnError = class extends Error {
56688
+ constructor() {
56689
+ super("Claude Code steer missed the active Turn");
56690
+ this.name = "ClaudeSteerMissedTurnError";
56691
+ }
56692
+ };
56693
+
56406
56694
  // dist/sdk-transport.js
56407
56695
  var CLIENT_APP = "codexhost-claude-code-adapter/0.0.0";
56408
56696
  var SESSION_ENTRYPOINT = "codexhost-sdk";
56409
56697
  var APPROVAL_TITLE_MAX_LENGTH = 120;
56410
56698
  var APPROVAL_DESCRIPTION_MAX_LENGTH = 500;
56411
56699
  var DEFAULT_ABORT_TIMEOUT_MS = 2e3;
56700
+ var DEFAULT_STEER_QUEUED_TIMEOUT_MS = 5e3;
56412
56701
  var WORKFLOW_AGENT_LABEL_LIMIT = 1e3;
56413
56702
  var INTERRUPT_TIMEOUT_MESSAGE = "Claude SDK interrupt timed out";
56414
56703
  var PushableInput = class {
@@ -56463,17 +56752,17 @@ function rejectAfter(milliseconds, message) {
56463
56752
  function processExited(child) {
56464
56753
  return child.exitCode !== null || child.signalCode !== null;
56465
56754
  }
56466
- function isRecord10(value) {
56755
+ function isRecord11(value) {
56467
56756
  return typeof value === "object" && value !== null && !Array.isArray(value);
56468
56757
  }
56469
56758
  function permissionModeFromMessage(value) {
56470
- if (!isRecord10(value) || value.type !== "system" || value.subtype !== "init" && value.subtype !== "status" || !("permissionMode" in value) || value.permissionMode === void 0) {
56759
+ if (!isRecord11(value) || value.type !== "system" || value.subtype !== "init" && value.subtype !== "status" || !("permissionMode" in value) || value.permissionMode === void 0) {
56471
56760
  return void 0;
56472
56761
  }
56473
56762
  return isClaudePermissionMode(value.permissionMode) ? value.permissionMode : void 0;
56474
56763
  }
56475
56764
  function parseContextUsage(value) {
56476
- if (!isRecord10(value))
56765
+ if (!isRecord11(value))
56477
56766
  throw new Error("Claude SDK context Usage is invalid");
56478
56767
  const usedTokens = value.totalTokens;
56479
56768
  const maxTokens = value.maxTokens;
@@ -56490,7 +56779,7 @@ function parseQuestions(input) {
56490
56779
  const questions = [];
56491
56780
  const questionTexts = /* @__PURE__ */ new Set();
56492
56781
  for (const value of input.questions) {
56493
- if (!isRecord10(value))
56782
+ if (!isRecord11(value))
56494
56783
  return null;
56495
56784
  const question = value.question;
56496
56785
  const header = value.header;
@@ -56501,7 +56790,7 @@ function parseQuestions(input) {
56501
56790
  const labels = /* @__PURE__ */ new Set();
56502
56791
  const options = [];
56503
56792
  for (const option2 of value.options) {
56504
- if (!isRecord10(option2) || typeof option2.label !== "string" || option2.label.length === 0 || labels.has(option2.label) || typeof option2.description !== "string") {
56793
+ if (!isRecord11(option2) || typeof option2.label !== "string" || option2.label.length === 0 || labels.has(option2.label) || typeof option2.description !== "string") {
56505
56794
  return null;
56506
56795
  }
56507
56796
  labels.add(option2.label);
@@ -56543,7 +56832,7 @@ function permissionUpdateDestination(value) {
56543
56832
  return void 0;
56544
56833
  }
56545
56834
  function isPermissionUpdate(value) {
56546
- if (!isRecord10(value) || !permissionUpdateDestination(value.destination))
56835
+ if (!isRecord11(value) || !permissionUpdateDestination(value.destination))
56547
56836
  return false;
56548
56837
  if (value.type === "setMode") {
56549
56838
  return typeof value.mode === "string" && PERMISSION_MODES.has(value.mode);
@@ -56552,7 +56841,7 @@ function isPermissionUpdate(value) {
56552
56841
  return Array.isArray(value.directories) && value.directories.every((directory) => typeof directory === "string");
56553
56842
  }
56554
56843
  if (value.type === "addRules" || value.type === "replaceRules" || value.type === "removeRules") {
56555
- return typeof value.behavior === "string" && PERMISSION_BEHAVIORS.has(value.behavior) && Array.isArray(value.rules) && value.rules.every((rule) => isRecord10(rule) && typeof rule.toolName === "string" && (rule.ruleContent === void 0 || typeof rule.ruleContent === "string"));
56844
+ return typeof value.behavior === "string" && PERMISSION_BEHAVIORS.has(value.behavior) && Array.isArray(value.rules) && value.rules.every((rule) => isRecord11(rule) && typeof rule.toolName === "string" && (rule.ruleContent === void 0 || typeof rule.ruleContent === "string"));
56556
56845
  }
56557
56846
  return false;
56558
56847
  }
@@ -56664,6 +56953,11 @@ var ClaudeSdkTransport = class {
56664
56953
  #queryFactory;
56665
56954
  #thinkingOptionId;
56666
56955
  #active = null;
56956
+ #steerQueuedTimeoutMs;
56957
+ #nativeSteer = false;
56958
+ /** Root tool calls of the requested Turn that have started and not yet returned a result. */
56959
+ #rootToolCalls = /* @__PURE__ */ new Set();
56960
+ #pendingSteers = /* @__PURE__ */ new Map();
56667
56961
  #autonomous = null;
56668
56962
  #autonomousTurnHandler = null;
56669
56963
  #idleHandler = null;
@@ -56687,6 +56981,7 @@ var ClaudeSdkTransport = class {
56687
56981
  this.sessionId = options.sessionId;
56688
56982
  this.#cwd = options.cwd;
56689
56983
  this.#abortTimeoutMs = options.abortTimeoutMs ?? DEFAULT_ABORT_TIMEOUT_MS;
56984
+ this.#steerQueuedTimeoutMs = options.steerQueuedTimeoutMs ?? DEFAULT_STEER_QUEUED_TIMEOUT_MS;
56690
56985
  this.#closeTimeoutMs = options.closeTimeoutMs;
56691
56986
  this.#command = options.command;
56692
56987
  this.#environment = options.environment ?? process.env;
@@ -56741,7 +57036,8 @@ var ClaudeSdkTransport = class {
56741
57036
  thinking: thinking.enabled ? { type: "adaptive", display: "summarized" } : { type: "disabled" },
56742
57037
  ...thinking.effort ? { effort: thinking.effort } : {},
56743
57038
  pathToClaudeCodeExecutable: executable,
56744
- settingSources: ["user"],
57039
+ // Omitted settingSources loads user, project and local settings like the
57040
+ // Claude Code CLI, so project CLAUDE.md and .claude/skills apply.
56745
57041
  permissionMode: this.#permissionMode,
56746
57042
  ...this.#allowDangerouslySkipPermissions ? { allowDangerouslySkipPermissions: true } : {},
56747
57043
  canUseTool: (toolName, input, options) => this.#canUseTool(toolName, input, options),
@@ -56778,8 +57074,42 @@ var ClaudeSdkTransport = class {
56778
57074
  return null;
56779
57075
  return { commands: this.#slashCommands, skillNames: this.#skillNames };
56780
57076
  }
57077
+ supportsNativeSteer() {
57078
+ return this.#nativeSteer;
57079
+ }
57080
+ /**
57081
+ * `priority: "next"` joins after the current tool call, and a tool result is always followed by
57082
+ * another model request. So a steer written while a root tool call runs folds into this Turn;
57083
+ * one written while Claude streams its final text may instead run as the next Turn.
57084
+ */
57085
+ canSteerActiveTurn() {
57086
+ return this.#nativeSteer && this.#active !== null && this.#rootToolCalls.size > 0;
57087
+ }
57088
+ #observeRootToolCalls(message) {
57089
+ if (!isRecord11(message) || message.parent_tool_use_id != null)
57090
+ return;
57091
+ if (message.type !== "assistant" && message.type !== "user")
57092
+ return;
57093
+ const body = message.message;
57094
+ if (!isRecord11(body) || !Array.isArray(body.content))
57095
+ return;
57096
+ for (const block of body.content) {
57097
+ if (!isRecord11(block))
57098
+ continue;
57099
+ if (message.type === "assistant" && block.type === "tool_use" && typeof block.id === "string") {
57100
+ this.#rootToolCalls.add(block.id);
57101
+ } else if (message.type === "user" && block.type === "tool_result" && typeof block.tool_use_id === "string") {
57102
+ this.#rootToolCalls.delete(block.tool_use_id);
57103
+ }
57104
+ }
57105
+ }
57106
+ #observeNativeCapabilities(message) {
57107
+ if (!isRecord11(message) || message.type !== "system" || message.subtype !== "init")
57108
+ return;
57109
+ this.#nativeSteer = Array.isArray(message.capabilities) && message.capabilities.includes("msg_lifecycle_v1");
57110
+ }
56781
57111
  #observeSlashCommands(message) {
56782
- if (!isRecord10(message) || message.type !== "system")
57112
+ if (!isRecord11(message) || message.type !== "system")
56783
57113
  return;
56784
57114
  if (message.subtype === "init" && Array.isArray(message.skills)) {
56785
57115
  this.#skillNames = new Set(message.skills.filter((name) => typeof name === "string"));
@@ -56900,6 +57230,7 @@ var ClaudeSdkTransport = class {
56900
57230
  const unclaimed = this.#autonomous?.events ?? [];
56901
57231
  this.#autonomous = null;
56902
57232
  const promise2 = new Promise((resolve5, reject) => {
57233
+ this.#rootToolCalls.clear();
56903
57234
  this.#active = {
56904
57235
  accumulator: new ClaudeNativeTurnAccumulator(this.#provider ? { provider: this.#provider } : {}),
56905
57236
  onEvent,
@@ -56919,6 +57250,51 @@ var ClaudeSdkTransport = class {
56919
57250
  });
56920
57251
  return promise2;
56921
57252
  }
57253
+ /**
57254
+ * Claude accepts the input with `queued`; Claude Code 2.1.280 then emits `started` after the
57255
+ * current tool call, when `priority: "next"` joins the running Turn. Waiting for `started` would
57256
+ * hold the caller for a whole tool call.
57257
+ *
57258
+ * Once written, the input cannot be recalled: Claude delivers it in this Turn or runs it next.
57259
+ * The Turn ending first therefore does not reject it, and a missing `queued` receipt resolves
57260
+ * after a bounded wait so callers that serialize requests are never held indefinitely.
57261
+ */
57262
+ steer(text2, messageId) {
57263
+ if (this.#closePromise || !this.#started || !this.#query || !this.canSteerActiveTurn()) {
57264
+ return Promise.reject(new ClaudeSteerMissedTurnError());
57265
+ }
57266
+ const promise2 = new Promise((resolve5, reject) => {
57267
+ this.#pendingSteers.set(messageId, { resolve: resolve5, reject, timer: void 0 });
57268
+ });
57269
+ try {
57270
+ this.#input.push({
57271
+ type: "user",
57272
+ message: { role: "user", content: text2 },
57273
+ parent_tool_use_id: null,
57274
+ session_id: this.sessionId,
57275
+ uuid: messageId,
57276
+ origin: { kind: "human" },
57277
+ priority: "next"
57278
+ });
57279
+ } catch {
57280
+ this.#pendingSteers.delete(messageId);
57281
+ return Promise.reject(new ClaudeSteerMissedTurnError());
57282
+ }
57283
+ const pending = this.#pendingSteers.get(messageId);
57284
+ if (pending) {
57285
+ pending.timer = setTimeout(() => this.#acceptSteer(messageId), this.#steerQueuedTimeoutMs);
57286
+ pending.timer.unref?.();
57287
+ }
57288
+ return promise2;
57289
+ }
57290
+ #acceptSteer(messageId) {
57291
+ const pending = this.#pendingSteers.get(messageId);
57292
+ if (!pending)
57293
+ return;
57294
+ this.#pendingSteers.delete(messageId);
57295
+ clearTimeout(pending.timer);
57296
+ pending.resolve();
57297
+ }
56922
57298
  respondToInteraction(response) {
56923
57299
  const pending = this.#interactions.get(response.requestId);
56924
57300
  if (!pending) {
@@ -57090,6 +57466,7 @@ var ClaudeSdkTransport = class {
57090
57466
  }
57091
57467
  }
57092
57468
  async #close() {
57469
+ this.#rejectPendingSteers();
57093
57470
  const failures = [];
57094
57471
  this.#closeInteractions("all", "cancelled");
57095
57472
  try {
@@ -57143,6 +57520,7 @@ var ClaudeSdkTransport = class {
57143
57520
  }
57144
57521
  this.#query = null;
57145
57522
  const active = this.#active;
57523
+ this.#rootToolCalls.clear();
57146
57524
  this.#active = null;
57147
57525
  this.#autonomous = null;
57148
57526
  this.#idleAccumulator = null;
@@ -57197,11 +57575,31 @@ var ClaudeSdkTransport = class {
57197
57575
  await delay(10);
57198
57576
  }
57199
57577
  }
57578
+ #rejectPendingSteers() {
57579
+ const pending = [...this.#pendingSteers.values()];
57580
+ this.#pendingSteers.clear();
57581
+ const error52 = new Error("Claude Code steer receipt was lost after input was written");
57582
+ for (const entry of pending) {
57583
+ clearTimeout(entry.timer);
57584
+ entry.reject(error52);
57585
+ }
57586
+ }
57587
+ /** `queued` is Claude's acceptance of this message into the running Session. */
57588
+ #observeSteer(message) {
57589
+ if (this.#pendingSteers.size === 0 || !isRecord11(message) || message.type !== "command_lifecycle") {
57590
+ return;
57591
+ }
57592
+ if (message.state !== "queued")
57593
+ return;
57594
+ if (typeof message.command_uuid !== "string" || message.command_uuid.length === 0)
57595
+ return;
57596
+ this.#acceptSteer(message.command_uuid);
57597
+ }
57200
57598
  #observeBackgroundTasks(message) {
57201
- if (!isRecord10(message) || message.type !== "system")
57599
+ if (!isRecord11(message) || message.type !== "system")
57202
57600
  return;
57203
57601
  if (message.subtype === "background_tasks_changed" && Array.isArray(message.tasks)) {
57204
- this.#backgroundTasks = new Set(message.tasks.flatMap((task) => isRecord10(task) && typeof task.task_id === "string" ? [task.task_id] : []));
57602
+ this.#backgroundTasks = new Set(message.tasks.flatMap((task) => isRecord11(task) && typeof task.task_id === "string" ? [task.task_id] : []));
57205
57603
  } else if (message.subtype === "task_started" && typeof message.task_id === "string") {
57206
57604
  this.#backgroundTasks.add(message.task_id);
57207
57605
  } else if (message.subtype === "task_notification" && typeof message.task_id === "string" && ["completed", "failed", "stopped"].includes(String(message.status))) {
@@ -57217,7 +57615,7 @@ var ClaudeSdkTransport = class {
57217
57615
  }
57218
57616
  /** Remembers Workflow agent labels so their approvals can name the agent asking. */
57219
57617
  #observeWorkflowAgents(message) {
57220
- if (!isRecord10(message) || message.type !== "system" || message.subtype !== "task_progress") {
57618
+ if (!isRecord11(message) || message.type !== "system" || message.subtype !== "task_progress") {
57221
57619
  return;
57222
57620
  }
57223
57621
  for (const agent of parseClaudeWorkflowAgents(message.workflow_progress) ?? []) {
@@ -57237,6 +57635,7 @@ var ClaudeSdkTransport = class {
57237
57635
  this.#observeBackgroundTasks(message);
57238
57636
  this.#observeWorkflowAgents(message);
57239
57637
  this.#observeSlashCommands(message);
57638
+ this.#observeNativeCapabilities(message);
57240
57639
  const permissionMode = permissionModeFromMessage(message);
57241
57640
  if (permissionMode && permissionMode !== this.#permissionMode) {
57242
57641
  this.#permissionMode = permissionMode;
@@ -57245,13 +57644,16 @@ var ClaudeSdkTransport = class {
57245
57644
  const planLimit = parseClaudePlanLimitEvent(message);
57246
57645
  if (planLimit)
57247
57646
  this.#onPlanLimit(planLimit);
57647
+ this.#observeSteer(message);
57248
57648
  const active = this.#active;
57249
57649
  if (active) {
57650
+ this.#observeRootToolCalls(message);
57250
57651
  const interpreted2 = active.accumulator.consume(message);
57251
57652
  for (const event of interpreted2.events)
57252
57653
  active.onEvent(event);
57253
57654
  if (interpreted2.terminal) {
57254
57655
  this.#closeInteractions("root", "superseded");
57656
+ this.#rootToolCalls.clear();
57255
57657
  this.#active = null;
57256
57658
  active.resolve(interpreted2.terminal);
57257
57659
  }
@@ -57278,7 +57680,7 @@ var ClaudeSdkTransport = class {
57278
57680
  userMessageId: null,
57279
57681
  live: false
57280
57682
  });
57281
- if (autonomous.userMessageId === null && isRecord10(message) && message.type === "user" && (message.parent_tool_use_id === null || message.parent_tool_use_id === void 0) && typeof message.uuid === "string" && message.uuid.length > 0) {
57683
+ if (autonomous.userMessageId === null && isRecord11(message) && message.type === "user" && (message.parent_tool_use_id === null || message.parent_tool_use_id === void 0) && typeof message.uuid === "string" && message.uuid.length > 0) {
57282
57684
  autonomous.userMessageId = message.uuid;
57283
57685
  }
57284
57686
  const interpreted = autonomous.accumulator.consume(message);
@@ -57305,6 +57707,8 @@ var ClaudeSdkTransport = class {
57305
57707
  } catch (error52) {
57306
57708
  const active = this.#active;
57307
57709
  this.#closeInteractions("all", "cancelled");
57710
+ this.#rejectPendingSteers();
57711
+ this.#rootToolCalls.clear();
57308
57712
  this.#active = null;
57309
57713
  active?.reject(error52);
57310
57714
  if (!this.#closePromise)
@@ -57806,11 +58210,11 @@ var ClaudeWorkflowLifecycle = class {
57806
58210
  };
57807
58211
 
57808
58212
  // dist/task-tracker.js
57809
- function isRecord11(value) {
58213
+ function isRecord12(value) {
57810
58214
  return typeof value === "object" && value !== null && !Array.isArray(value);
57811
58215
  }
57812
58216
  function stringField(value, keys) {
57813
- if (!isRecord11(value))
58217
+ if (!isRecord12(value))
57814
58218
  return void 0;
57815
58219
  for (const key of keys) {
57816
58220
  const field = value[key];
@@ -57845,7 +58249,7 @@ var ClaudeTaskTracker = class {
57845
58249
  };
57846
58250
  }
57847
58251
  #create(args, result) {
57848
- if (!isRecord11(result) || !isRecord11(result.task))
58252
+ if (!isRecord12(result) || !isRecord12(result.task))
57849
58253
  return;
57850
58254
  const id2 = stringField(result.task, ["id"]);
57851
58255
  const subject = stringField(args, ["subject"]) ?? stringField(result.task, ["subject"]);
@@ -57863,7 +58267,7 @@ var ClaudeTaskTracker = class {
57863
58267
  const id2 = stringField(args, ["taskId", "id", "task_id"]);
57864
58268
  if (!id2)
57865
58269
  return;
57866
- const status = isRecord11(args) ? taskStatus2(args.status) : void 0;
58270
+ const status = isRecord12(args) ? taskStatus2(args.status) : void 0;
57867
58271
  if (status === "deleted") {
57868
58272
  this.#tasks.delete(id2);
57869
58273
  return;
@@ -57881,13 +58285,13 @@ var ClaudeTaskTracker = class {
57881
58285
  });
57882
58286
  }
57883
58287
  #replace(result) {
57884
- if (!isRecord11(result) || !Array.isArray(result.tasks))
58288
+ if (!isRecord12(result) || !Array.isArray(result.tasks))
57885
58289
  return;
57886
58290
  const next = /* @__PURE__ */ new Map();
57887
58291
  for (const value of result.tasks) {
57888
58292
  const id2 = stringField(value, ["id"]);
57889
58293
  const subject = stringField(value, ["subject"]);
57890
- const status = isRecord11(value) ? taskStatus2(value.status) : void 0;
58294
+ const status = isRecord12(value) ? taskStatus2(value.status) : void 0;
57891
58295
  if (!id2 || !subject || !status || status === "deleted")
57892
58296
  continue;
57893
58297
  const existing = this.#tasks.get(id2);
@@ -58054,11 +58458,11 @@ var ClaudeBackgroundCommandItems = class {
58054
58458
  };
58055
58459
 
58056
58460
  // dist/tool-lifecycle.js
58057
- function isRecord12(value) {
58461
+ function isRecord13(value) {
58058
58462
  return typeof value === "object" && value !== null && !Array.isArray(value);
58059
58463
  }
58060
58464
  function stringField2(value, key) {
58061
- return isRecord12(value) && typeof value[key] === "string" ? value[key] : void 0;
58465
+ return isRecord13(value) && typeof value[key] === "string" ? value[key] : void 0;
58062
58466
  }
58063
58467
  function toolFailure(toolName) {
58064
58468
  return {
@@ -58248,6 +58652,7 @@ var claudeCommandCatalog = harnessCommandCatalogSchema.parse({
58248
58652
  {
58249
58653
  id: "claude.compact",
58250
58654
  invocation: "/compact",
58655
+ localizations: { "zh-CN": { label: "压缩上下文", description: "压缩当前对话上下文" } },
58251
58656
  label: "Compact context",
58252
58657
  description: "Compact the current conversation context",
58253
58658
  argumentMode: "text"
@@ -58324,7 +58729,7 @@ var CONTEXT_USAGE_TTL_MS = 1e4;
58324
58729
  var CONTEXT_USAGE_FAILURE_COOLDOWN_MS = 5e3;
58325
58730
  var REQUEST_USAGE_RETRY_DELAYS_MS = [0, 100, 250, 500, 1e3];
58326
58731
  var DEFAULT_CONTINUATION_QUIESCENCE_MS = 2e3;
58327
- function isRecord13(value) {
58732
+ function isRecord14(value) {
58328
58733
  return typeof value === "object" && value !== null && !Array.isArray(value);
58329
58734
  }
58330
58735
  function safeNonNegativeInteger2(value) {
@@ -58333,7 +58738,7 @@ function safeNonNegativeInteger2(value) {
58333
58738
  function transcriptRequestUsage(messages, messageId) {
58334
58739
  for (let index = messages.length - 1; index >= 0; index -= 1) {
58335
58740
  const entry = messages[index];
58336
- if (!isRecord13(entry) || entry.type !== "assistant" || entry.parent_tool_use_id !== null && entry.parent_tool_use_id !== void 0 || !isRecord13(entry.message) || entry.message.id !== messageId || !isRecord13(entry.message.usage)) {
58741
+ if (!isRecord14(entry) || entry.type !== "assistant" || entry.parent_tool_use_id !== null && entry.parent_tool_use_id !== void 0 || !isRecord14(entry.message) || entry.message.id !== messageId || !isRecord14(entry.message.usage)) {
58337
58742
  continue;
58338
58743
  }
58339
58744
  const inputTokens = entry.message.usage.input_tokens;
@@ -58481,6 +58886,7 @@ function projectClaudePlanLimitToCredits(planLimit) {
58481
58886
  productUsage: [
58482
58887
  {
58483
58888
  product: "7-day window",
58889
+ periodType: "seven_day",
58484
58890
  usagePercent: other.utilizationPercent,
58485
58891
  ...other.resetsAtUnix !== void 0 ? { resetsAt: isoFromUnix(other.resetsAtUnix) } : {}
58486
58892
  }
@@ -58490,7 +58896,7 @@ function projectClaudePlanLimitToCredits(planLimit) {
58490
58896
  }
58491
58897
  var ClaudeHarnessSession = class {
58492
58898
  harnessId = claudeCodeHarnessId2;
58493
- capabilities = {
58899
+ capabilities = /* @__PURE__ */ ((session) => ({
58494
58900
  configuration: {
58495
58901
  selectModel: true,
58496
58902
  selectThinkingOption: true,
@@ -58498,11 +58904,16 @@ var ClaudeHarnessSession = class {
58498
58904
  permissionModeScope: "live"
58499
58905
  },
58500
58906
  history: { fork: true, forkAcrossCwd: false, rollbackLastTurn: true },
58501
- subagents: { observe: true, readTranscript: true }
58502
- };
58907
+ subagents: { observe: true, readTranscript: true },
58908
+ // Read live: native delivery joins this Turn only while a requested Turn runs a root tool call
58909
+ // on a CLI that confirms steers (`msg_lifecycle_v1`). Otherwise the Host stops and restarts.
58910
+ get steer() {
58911
+ return session.#transport?.canSteerActiveTurn?.() === true;
58912
+ }
58913
+ }))(this);
58503
58914
  commands;
58504
58915
  initialState;
58505
- initialUsage = null;
58916
+ initialUsage;
58506
58917
  outputs;
58507
58918
  #channel = new HarnessOutputChannel();
58508
58919
  #cancelTimeoutMs;
@@ -58541,7 +58952,10 @@ var ClaudeHarnessSession = class {
58541
58952
  #hardCancelTask = null;
58542
58953
  #usageGeneration = 0;
58543
58954
  #latestUsage = null;
58955
+ #lastAssistantResponseAtUnix;
58956
+ #accountCreditsSupported;
58544
58957
  #minimumContextUsedTokens = null;
58958
+ #latestRequestModel = null;
58545
58959
  #calibratedInputTokens = 0;
58546
58960
  #calibratedOutputTokens = 0;
58547
58961
  #calibratedCostUsd = 0;
@@ -58559,6 +58973,11 @@ var ClaudeHarnessSession = class {
58559
58973
  #continuationQuiescence = null;
58560
58974
  constructor(cwd, dependencies, closeTimeoutMs, onClosed, onPlanLimitObserved, options) {
58561
58975
  this.#cwd = cwd;
58976
+ this.#lastAssistantResponseAtUnix = options.usageHistory.lastResponseAtUnix;
58977
+ this.#accountCreditsSupported = options.accountCreditsSupported;
58978
+ const composerIndicators = claudePromptCacheIndicators(this.#accountCreditsSupported, this.#lastAssistantResponseAtUnix);
58979
+ this.initialUsage = composerIndicators.length ? { composerIndicators } : null;
58980
+ this.#latestUsage = this.initialUsage;
58562
58981
  this.#pendingSessions = options.pendingSessions;
58563
58982
  const environment = options.environment;
58564
58983
  this.#createTransport = environment ? (input) => dependencies.createTransport({ ...input, environment }) : dependencies.createTransport;
@@ -58635,7 +59054,7 @@ var ClaudeHarnessSession = class {
58635
59054
  cwd: this.#cwd,
58636
59055
  sessionId: this.#sessionId
58637
59056
  }) ?? [];
58638
- const ids = new Set(messages.flatMap((message) => isRecord13(message) && typeof message.uuid === "string" ? [message.uuid] : []));
59057
+ const ids = new Set(messages.flatMap((message) => isRecord14(message) && typeof message.uuid === "string" ? [message.uuid] : []));
58639
59058
  if (this.#unpersistedMessageIds.every((id2) => ids.has(id2))) {
58640
59059
  this.#unpersistedMessageIds = [];
58641
59060
  break;
@@ -58713,6 +59132,8 @@ var ClaudeHarnessSession = class {
58713
59132
  }
58714
59133
  if (command.type === "turn.cancel")
58715
59134
  return this.#cancel(command);
59135
+ if (command.type === "turn.steer")
59136
+ return this.#steer(command);
58716
59137
  if (command.type === "interaction.respond")
58717
59138
  return this.#respond(command);
58718
59139
  if (command.type === "model.select")
@@ -58849,6 +59270,45 @@ var ClaudeHarnessSession = class {
58849
59270
  }
58850
59271
  return { ok: true, value: { turnId: command.turnId } };
58851
59272
  }
59273
+ async #steer(command) {
59274
+ if (!this.#active || this.#active.command.turnId !== command.turnId) {
59275
+ return { ok: false, error: invalidState("Claude Code steer target is not the active Turn") };
59276
+ }
59277
+ const text2 = command.input.map((input) => input.text).join("\n");
59278
+ if (text2.length === 0) {
59279
+ return {
59280
+ ok: false,
59281
+ error: {
59282
+ code: "invalidRequest",
59283
+ message: "Claude Code steer text must not be empty",
59284
+ retryable: false
59285
+ }
59286
+ };
59287
+ }
59288
+ const transport = this.#transport;
59289
+ if (!transport) {
59290
+ return { ok: false, error: invalidState("Claude Code steer missed the active Turn") };
59291
+ }
59292
+ if (transport.supportsNativeSteer?.() !== true) {
59293
+ return {
59294
+ ok: false,
59295
+ error: {
59296
+ code: "unsupported",
59297
+ message: "This Claude Code version does not confirm native steering",
59298
+ retryable: false
59299
+ }
59300
+ };
59301
+ }
59302
+ try {
59303
+ await transport.steer(text2, this.#randomUUID());
59304
+ } catch (error52) {
59305
+ if (error52 instanceof ClaudeSteerMissedTurnError) {
59306
+ return { ok: false, error: invalidState("Claude Code steer missed the active Turn") };
59307
+ }
59308
+ throw error52;
59309
+ }
59310
+ return { ok: true, value: { accepted: true } };
59311
+ }
58852
59312
  /** Built-ins plus the live commands and skills of the started native Session. */
58853
59313
  #liveCommandCatalog() {
58854
59314
  return claudeLiveCommandCatalog(claudeCommandCatalog, this.#transport?.slashCommands?.() ?? null);
@@ -59619,6 +60079,10 @@ var ClaudeHarnessSession = class {
59619
60079
  this.#completeReasoning(active, event.messageId, { status: "succeeded" });
59620
60080
  return;
59621
60081
  case "message.completed": {
60082
+ if (!event.localCommand) {
60083
+ this.#lastAssistantResponseAtUnix = Math.floor(Date.now() / 1e3);
60084
+ this.publishAccountCreditsSupport(this.#accountCreditsSupported);
60085
+ }
59622
60086
  this.#observeRootOutput(active);
59623
60087
  if (event.lastRequestUsage) {
59624
60088
  this.#requestUsageBoundary += 1;
@@ -59680,9 +60144,7 @@ var ClaudeHarnessSession = class {
59680
60144
  case "subagent.completed": {
59681
60145
  const subagent = active.subagents.complete(active.command.turnId, event, active.cancellationRequested);
59682
60146
  if (subagent.status === "running") {
59683
- if (subagent.nativeSubagentId) {
59684
- this.#occupancy.bind(event.callId, subagent.nativeSubagentId);
59685
- }
60147
+ this.#occupancy.occupySpawn(event.callId, subagent.nativeSubagentId);
59686
60148
  return;
59687
60149
  }
59688
60150
  this.#occupancy.release(event.callId, subagent.nativeSubagentId);
@@ -60241,6 +60703,8 @@ var ClaudeHarnessSession = class {
60241
60703
  const promptTokens = usage.inputTokens + usage.cacheCreationInputTokens + usage.cacheReadInputTokens;
60242
60704
  if (promptTokens > 0)
60243
60705
  this.#minimumContextUsedTokens = promptTokens;
60706
+ if (usage.model)
60707
+ this.#latestRequestModel = usage.model;
60244
60708
  const cacheHitRatePercent = claudeCacheHitRatePercent(usage);
60245
60709
  const contextWindowTokens = this.#latestUsage?.contextWindowTokens;
60246
60710
  this.#mergeAndPublishUsage({
@@ -60282,8 +60746,24 @@ var ClaudeHarnessSession = class {
60282
60746
  if (cacheHitRatePercent !== void 0)
60283
60747
  delta.cacheHitRatePercent = cacheHitRatePercent;
60284
60748
  }
60749
+ if (this.#latestUsage?.contextWindowTokens === void 0 && this.#minimumContextUsedTokens !== null) {
60750
+ const contextWindowTokens = this.#resultContextWindow(event.modelUsage);
60751
+ if (contextWindowTokens !== void 0) {
60752
+ delta.contextUsedTokens = this.#minimumContextUsedTokens;
60753
+ delta.contextWindowTokens = contextWindowTokens;
60754
+ }
60755
+ }
60285
60756
  this.#mergeAndPublishUsage(delta, active.command.turnId);
60286
60757
  }
60758
+ /** The latest request's Model, else the Model that carried the most prompt tokens. */
60759
+ #resultContextWindow(modelUsage) {
60760
+ if (!modelUsage?.length)
60761
+ return void 0;
60762
+ const latest = this.#latestRequestModel;
60763
+ const matched = latest ? modelUsage.find(({ model: model2 }) => model2 === latest) : void 0;
60764
+ const main = matched ?? modelUsage.reduce((best, entry) => (entry.promptTokens ?? entry.inputTokens) > (best.promptTokens ?? best.inputTokens) ? entry : best);
60765
+ return main.contextWindowTokens;
60766
+ }
60287
60767
  /**
60288
60768
  * Plan usage is account-wide, not Thread-scoped, so every observation is
60289
60769
  * offered to the Adapter's shared cache regardless of this Session's own
@@ -60296,6 +60776,15 @@ var ClaudeHarnessSession = class {
60296
60776
  if (effective)
60297
60777
  this.publishPlanLimit(effective);
60298
60778
  }
60779
+ publishAccountCreditsSupport(supported) {
60780
+ if (this.#phase !== "open")
60781
+ return;
60782
+ this.#accountCreditsSupported = supported;
60783
+ const composerIndicators = claudePromptCacheIndicators(supported, this.#lastAssistantResponseAtUnix);
60784
+ if (composerIndicators[0]?.expiresAtUnix === this.#latestUsage?.composerIndicators?.[0]?.expiresAtUnix)
60785
+ return;
60786
+ this.#mergeAndPublishUsage({ composerIndicators }, this.#active?.command.turnId);
60787
+ }
60299
60788
  publishPlanLimit(planLimit) {
60300
60789
  if (this.#phase !== "open")
60301
60790
  return;
@@ -60571,6 +61060,7 @@ var ClaudeCodeAdapter = class {
60571
61060
  #closePromise = null;
60572
61061
  #latestPlanLimit = null;
60573
61062
  #accountInspection = null;
61063
+ #accountCreditsSupported = false;
60574
61064
  constructor(options = {}, dependencies) {
60575
61065
  const environment = options.environment ?? process.env;
60576
61066
  this.#environment = environment;
@@ -60591,7 +61081,7 @@ var ClaudeCodeAdapter = class {
60591
61081
  throw new RangeError("Claude Code continuation quiescence must be a positive safe integer");
60592
61082
  }
60593
61083
  this.#dependencies = dependencies ?? {
60594
- randomUUID: randomUUID4,
61084
+ randomUUID: randomUUID5,
60595
61085
  bypassPermissionsAvailable: (environment2) => claudeBypassPermissionsAvailable(environment2 ?? options.environment ?? process.env),
60596
61086
  inspectInstallation: () => {
60597
61087
  resolveClaudeCodeExecutable({
@@ -60613,7 +61103,18 @@ var ClaudeCodeAdapter = class {
60613
61103
  abortTimeoutMs: this.#cancelTimeoutMs
60614
61104
  }),
60615
61105
  deleteSession: ({ cwd, sessionId }) => M5t(sessionId, { dir: cwd }),
60616
- forkSession: ({ checkpointId, cwd, sourceSessionId }) => U5t(sourceSessionId, { dir: cwd, upToMessageId: checkpointId }),
61106
+ forkSession: async ({ checkpointId, cwd, sourceSessionId }) => {
61107
+ const forked = await U5t(sourceSessionId, {
61108
+ dir: cwd,
61109
+ upToMessageId: checkpointId
61110
+ });
61111
+ await remapForkedSessionReferences({
61112
+ cwd,
61113
+ environment: options.environment ?? process.env,
61114
+ sessionId: forked.sessionId
61115
+ }).catch(() => void 0);
61116
+ return forked;
61117
+ },
60617
61118
  getSessionInfo: async ({ sessionId }) => {
60618
61119
  const info = await D5t(sessionId);
60619
61120
  if (!info)
@@ -60671,12 +61172,20 @@ var ClaudeCodeAdapter = class {
60671
61172
  return this.#accountInspection;
60672
61173
  }
60673
61174
  async #readAccount() {
61175
+ const planLimitAtStart = this.#latestPlanLimit;
60674
61176
  let inspector;
60675
61177
  try {
60676
61178
  this.#dependencies.inspectInstallation();
60677
61179
  inspector = this.#dependencies.createInspector({ cwd: process.cwd() });
60678
61180
  this.#inspectors.add(inspector);
60679
- return await inspector.inspectAccount?.() ?? null;
61181
+ const account = await inspector.inspectAccount?.() ?? null;
61182
+ if (this.#latestPlanLimit === planLimitAtStart) {
61183
+ this.#accountCreditsSupported = account?.credits !== void 0;
61184
+ for (const session of this.#sessions) {
61185
+ session.publishAccountCreditsSupport(this.#accountCreditsSupported);
61186
+ }
61187
+ }
61188
+ return account;
60680
61189
  } catch {
60681
61190
  return null;
60682
61191
  } finally {
@@ -60919,6 +61428,7 @@ var ClaudeCodeAdapter = class {
60919
61428
  ...durableRef ? { nativeRef: durableRef } : {},
60920
61429
  sessionId,
60921
61430
  usageHistory,
61431
+ accountCreditsSupported: this.#accountCreditsSupported,
60922
61432
  ...requestedModel ? { requestedModel } : {},
60923
61433
  requestedPermissionModeId,
60924
61434
  requestedThinkingOptionId,
@@ -60938,7 +61448,13 @@ var ClaudeCodeAdapter = class {
60938
61448
  return { requests: [], complete: true };
60939
61449
  try {
60940
61450
  const messages = await this.#dependencies.readSessionMessages({ cwd, sessionId });
60941
- return messages === null ? { requests: [], complete: false } : claudeUsageHistory(messages);
61451
+ if (messages === null)
61452
+ return { requests: [], complete: false };
61453
+ const lastResponseAtUnix = lastClaudeAssistantResponseUnix(messages);
61454
+ return {
61455
+ ...claudeUsageHistory(messages),
61456
+ ...lastResponseAtUnix !== void 0 ? { lastResponseAtUnix } : {}
61457
+ };
60942
61458
  } catch {
60943
61459
  return { requests: [], complete: false };
60944
61460
  }
@@ -60950,9 +61466,17 @@ var ClaudeCodeAdapter = class {
60950
61466
  next.fiveHour = planLimit.fiveHour;
60951
61467
  if (planLimit.sevenDay)
60952
61468
  next.sevenDay = planLimit.sevenDay;
61469
+ try {
61470
+ if (!accountCreditsSnapshotSchema.safeParse(projectClaudePlanLimitToCredits(next)).success)
61471
+ return null;
61472
+ } catch {
61473
+ return null;
61474
+ }
60953
61475
  this.#latestPlanLimit = next.fiveHour || next.sevenDay ? next : null;
60954
61476
  if (this.#latestPlanLimit) {
61477
+ this.#accountCreditsSupported = true;
60955
61478
  for (const session of this.#sessions) {
61479
+ session.publishAccountCreditsSupport(true);
60956
61480
  if (session !== origin)
60957
61481
  session.publishPlanLimit(this.#latestPlanLimit);
60958
61482
  }
@@ -60977,11 +61501,11 @@ var ClaudeCodeAdapter = class {
60977
61501
  };
60978
61502
 
60979
61503
  // dist/installation.js
60980
- import { readFile as readFile7, realpath as realpath5 } from "node:fs/promises";
61504
+ import { readFile as readFile8, realpath as realpath5 } from "node:fs/promises";
60981
61505
  import { homedir as homedir2 } from "node:os";
60982
61506
  import path17 from "node:path";
60983
61507
  async function readSettings(file2) {
60984
- const text2 = await readFile7(file2, "utf8").catch((error52) => {
61508
+ const text2 = await readFile8(file2, "utf8").catch((error52) => {
60985
61509
  if (error52.code === "ENOENT")
60986
61510
  return "{}";
60987
61511
  throw error52;
@@ -61032,6 +61556,12 @@ function createClaudeInstallation(environment, command) {
61032
61556
  canUpdate,
61033
61557
  ...!canUpdate ? {
61034
61558
  messageCode: blocked ? "claude-policy-restricted" : "original-installer",
61559
+ ...blocked ? {
61560
+ notice: {
61561
+ en: "Claude updates are restricted by the installation's settings or policy.",
61562
+ "zh-CN": "此 Claude 安装的设置或策略限制了更新。"
61563
+ }
61564
+ } : {},
61035
61565
  message: blocked ? "Claude updates are restricted by the installation's settings or policy." : "Use the original installer or package manager for this Claude installation."
61036
61566
  } : {}
61037
61567
  };