@codexhost/cli-win32-arm64 0.10.2 → 0.12.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 (34) hide show
  1. package/README.md +1 -1
  2. package/THIRD_PARTY_NOTICES.txt +4 -0
  3. package/app/codexhost-distribution.json +1 -1
  4. package/app/console-server.mjs +18001 -0
  5. package/app/console-web.js +27674 -0
  6. package/app/desktop-controller.mjs +452 -110
  7. package/app/host-runtime.mjs +6670 -1272
  8. package/app/plugins/antigravity/plugin.mjs +686 -305
  9. package/app/plugins/claude-code/plugin.mjs +2283 -1450
  10. package/app/plugins/codebuddy/plugin.mjs +1272 -506
  11. package/app/plugins/cursor-cli/manifest.json +1 -1
  12. package/app/plugins/cursor-cli/plugin.mjs +1295 -497
  13. package/app/plugins/deepseek-harness/plugin.mjs +4718 -4925
  14. package/app/plugins/enabled.json +2 -1
  15. package/app/plugins/grok/plugin.mjs +1012 -369
  16. package/app/plugins/hermes/plugin.mjs +18587 -22714
  17. package/app/plugins/kimi-code/plugin.mjs +1283 -355
  18. package/app/plugins/kiro-cli/plugin.mjs +840 -299
  19. package/app/plugins/omp/plugin.mjs +1045 -328
  20. package/app/plugins/opencode/plugin.mjs +5341 -1686
  21. package/app/plugins/pi/plugin.mjs +1343 -534
  22. package/app/plugins/qoder/plugin.mjs +913 -258
  23. package/app/plugins/qoder-cn/plugin.mjs +712 -49
  24. package/app/plugins/workbuddy/plugin.mjs +531 -44
  25. package/app/plugins/zcode/assets/icon.svg +8 -0
  26. package/app/plugins/zcode/manifest.json +14 -0
  27. package/app/plugins/zcode/plugin.mjs +19202 -0
  28. package/app/renderer-extension.js +5011 -1899
  29. package/bin/codexhost.exe +0 -0
  30. package/libexec/codexhost-node-repl.exe +0 -0
  31. package/libexec/codexhost-shim.exe +0 -0
  32. package/libexec/codexhost-updater.exe +0 -0
  33. package/licenses/OpenCode-v2-Client-LICENSE.txt +21 -0
  34. package/package.json +1 -1
@@ -776,10 +776,10 @@ function mergeDefs(...defs) {
776
776
  function cloneDef(schema) {
777
777
  return mergeDefs(schema._zod.def);
778
778
  }
779
- function getElementAtPath(obj, path14) {
780
- if (!path14)
779
+ function getElementAtPath(obj, path17) {
780
+ if (!path17)
781
781
  return obj;
782
- return path14.reduce((acc, key) => acc?.[key], obj);
782
+ return path17.reduce((acc, key) => acc?.[key], obj);
783
783
  }
784
784
  function promiseAllObject(promisesObj) {
785
785
  const keys = Object.keys(promisesObj);
@@ -1188,11 +1188,11 @@ function explicitlyAborted(x2, startIndex = 0) {
1188
1188
  }
1189
1189
  return false;
1190
1190
  }
1191
- function prefixIssues(path14, issues) {
1191
+ function prefixIssues(path17, issues) {
1192
1192
  return issues.map((iss) => {
1193
1193
  var _a4;
1194
1194
  (_a4 = iss).path ?? (_a4.path = []);
1195
- iss.path.unshift(path14);
1195
+ iss.path.unshift(path17);
1196
1196
  return iss;
1197
1197
  });
1198
1198
  }
@@ -1339,16 +1339,16 @@ function flattenError(error52, mapper = (issue2) => issue2.message) {
1339
1339
  }
1340
1340
  function formatError(error52, mapper = (issue2) => issue2.message) {
1341
1341
  const fieldErrors = { _errors: [] };
1342
- const processError = (error53, path14 = []) => {
1342
+ const processError = (error53, path17 = []) => {
1343
1343
  for (const issue2 of error53.issues) {
1344
1344
  if (issue2.code === "invalid_union" && issue2.errors.length) {
1345
- issue2.errors.map((issues) => processError({ issues }, [...path14, ...issue2.path]));
1345
+ issue2.errors.map((issues) => processError({ issues }, [...path17, ...issue2.path]));
1346
1346
  } else if (issue2.code === "invalid_key") {
1347
- processError({ issues: issue2.issues }, [...path14, ...issue2.path]);
1347
+ processError({ issues: issue2.issues }, [...path17, ...issue2.path]);
1348
1348
  } else if (issue2.code === "invalid_element") {
1349
- processError({ issues: issue2.issues }, [...path14, ...issue2.path]);
1349
+ processError({ issues: issue2.issues }, [...path17, ...issue2.path]);
1350
1350
  } else {
1351
- const fullpath = [...path14, ...issue2.path];
1351
+ const fullpath = [...path17, ...issue2.path];
1352
1352
  if (fullpath.length === 0) {
1353
1353
  fieldErrors._errors.push(mapper(issue2));
1354
1354
  } else {
@@ -1375,17 +1375,17 @@ function formatError(error52, mapper = (issue2) => issue2.message) {
1375
1375
  }
1376
1376
  function treeifyError(error52, mapper = (issue2) => issue2.message) {
1377
1377
  const result = { errors: [] };
1378
- const processError = (error53, path14 = []) => {
1378
+ const processError = (error53, path17 = []) => {
1379
1379
  var _a4, _b2;
1380
1380
  for (const issue2 of error53.issues) {
1381
1381
  if (issue2.code === "invalid_union" && issue2.errors.length) {
1382
- issue2.errors.map((issues) => processError({ issues }, [...path14, ...issue2.path]));
1382
+ issue2.errors.map((issues) => processError({ issues }, [...path17, ...issue2.path]));
1383
1383
  } else if (issue2.code === "invalid_key") {
1384
- processError({ issues: issue2.issues }, [...path14, ...issue2.path]);
1384
+ processError({ issues: issue2.issues }, [...path17, ...issue2.path]);
1385
1385
  } else if (issue2.code === "invalid_element") {
1386
- processError({ issues: issue2.issues }, [...path14, ...issue2.path]);
1386
+ processError({ issues: issue2.issues }, [...path17, ...issue2.path]);
1387
1387
  } else {
1388
- const fullpath = [...path14, ...issue2.path];
1388
+ const fullpath = [...path17, ...issue2.path];
1389
1389
  if (fullpath.length === 0) {
1390
1390
  result.errors.push(mapper(issue2));
1391
1391
  continue;
@@ -1417,8 +1417,8 @@ function treeifyError(error52, mapper = (issue2) => issue2.message) {
1417
1417
  }
1418
1418
  function toDotPath(_path) {
1419
1419
  const segs = [];
1420
- const path14 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
1421
- for (const seg of path14) {
1420
+ const path17 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
1421
+ for (const seg of path17) {
1422
1422
  if (typeof seg === "number")
1423
1423
  segs.push(`[${seg}]`);
1424
1424
  else if (typeof seg === "symbol")
@@ -14110,13 +14110,13 @@ function resolveRef(ref, ctx) {
14110
14110
  if (!ref.startsWith("#")) {
14111
14111
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
14112
14112
  }
14113
- const path14 = ref.slice(1).split("/").filter(Boolean);
14114
- if (path14.length === 0) {
14113
+ const path17 = ref.slice(1).split("/").filter(Boolean);
14114
+ if (path17.length === 0) {
14115
14115
  return ctx.rootSchema;
14116
14116
  }
14117
14117
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
14118
- if (path14[0] === defsKey) {
14119
- const key = path14[1];
14118
+ if (path17[0] === defsKey) {
14119
+ const key = path17[1];
14120
14120
  if (!key || !ctx.defs[key]) {
14121
14121
  throw new Error(`Reference not found: ${ref}`);
14122
14122
  }
@@ -14579,6 +14579,56 @@ var credentialImportsParamsSchema = external_exports.object({
14579
14579
  request: credentialImportsRequestSchema
14580
14580
  }).strict();
14581
14581
 
14582
+ // ../../shared-contracts/dist/harness-display-settings.js
14583
+ var harnessDisplayEntriesSchema = external_exports.array(external_exports.strictObject({
14584
+ agent: external_exports.string().min(1).max(128),
14585
+ section: external_exports.enum(["main", "more", "auto"])
14586
+ })).max(256).refine((entries) => new Set(entries.map((entry) => entry.agent)).size === entries.length, "Duplicate Harness IDs");
14587
+ var harnessDisplaySettingsSchema = external_exports.strictObject({
14588
+ entries: harnessDisplayEntriesSchema.nullable()
14589
+ });
14590
+ var harnessDisplayGetSchema = external_exports.strictObject({});
14591
+ var harnessDisplaySetSchema = external_exports.strictObject({
14592
+ entries: harnessDisplayEntriesSchema,
14593
+ /** Import legacy Desktop preferences only if no shared settings exist yet. */
14594
+ initializeOnly: external_exports.boolean().optional()
14595
+ });
14596
+
14597
+ // ../../shared-contracts/dist/console.js
14598
+ var consoleAnnouncementSchema = external_exports.strictObject({
14599
+ title: external_exports.string().trim().min(1).max(200),
14600
+ type: external_exports.enum(["info", "warning", "danger"]),
14601
+ body: external_exports.string().trim().min(1).max(16 * 1024)
14602
+ });
14603
+ var consoleOpenParamsSchema = external_exports.strictObject({});
14604
+ var consoleOpenResultSchema = external_exports.strictObject({
14605
+ /** The console address. */
14606
+ url: external_exports.string().max(2048).regex(/^http:\/\/(?:127\.0\.0\.1|localhost):\d{1,5}\/(?:\?.*)?$/u)
14607
+ });
14608
+ var CONSOLE_HOST_METHODS = Object.freeze([
14609
+ "codexhost/harness/plugins/list",
14610
+ "codexhost/harness/display-settings/get",
14611
+ "codexhost/harness/display-settings/set",
14612
+ "codexhost/harness/inspect",
14613
+ "codexhost/harness/installation",
14614
+ "codexhost/harness/launch-settings/get",
14615
+ "codexhost/harness/launch-settings/set",
14616
+ "codexhost/harness/web-ui/open",
14617
+ "codexhost/harness/accounts/sources",
14618
+ "codexhost/harness/accounts/list",
14619
+ "codexhost/harness/accounts/inspect",
14620
+ "codexhost/harness/credential-imports",
14621
+ "codexhost/harness/session-import/sources",
14622
+ "codexhost/harness/session-import/list",
14623
+ "codexhost/harness/session-import/import",
14624
+ "codexhost/account/list",
14625
+ "codexhost/account/refresh",
14626
+ "codexhost/account/usage/inspect",
14627
+ "codexhost/update/check",
14628
+ "codexhost/update/start",
14629
+ "codexhost/update/status"
14630
+ ]);
14631
+
14582
14632
  // ../../shared-contracts/dist/version.js
14583
14633
  var WORKSPACE_CONTRACT_VERSION = 1;
14584
14634
 
@@ -14632,6 +14682,12 @@ var hostTurnIdSchema = opaqueIdSchema.brand();
14632
14682
  var hostItemIdSchema = opaqueIdSchema.brand();
14633
14683
  var hostInteractionIdSchema = opaqueIdSchema.brand();
14634
14684
 
14685
+ // ../../shared-contracts/dist/manual-compaction.js
14686
+ var threadManualCompactionStartedSchema = external_exports.strictObject({
14687
+ threadId: hostThreadIdSchema,
14688
+ turnId: hostTurnIdSchema
14689
+ });
14690
+
14635
14691
  // ../../shared-contracts/dist/thread-usage.js
14636
14692
  var nonNegativeSafeIntegerSchema = external_exports.number().int().safe().nonnegative();
14637
14693
  var finiteNonNegativeNumberSchema = external_exports.number().finite().nonnegative();
@@ -14692,6 +14748,10 @@ var threadUsageSnapshotSchema = external_exports.object({
14692
14748
  var usagePercentSchema = external_exports.number().finite().min(0).max(100);
14693
14749
  var accountCreditsProductUsageSchema = external_exports.object({
14694
14750
  product: external_exports.string().min(1),
14751
+ used: external_exports.number().finite().nonnegative().optional(),
14752
+ // Zero is a real empty cap, not an absent field.
14753
+ limit: external_exports.number().finite().nonnegative().optional(),
14754
+ unit: external_exports.string().min(1).max(32).optional(),
14695
14755
  usagePercent: usagePercentSchema,
14696
14756
  resetsAt: external_exports.string().min(1).optional()
14697
14757
  }).strict();
@@ -14701,6 +14761,10 @@ var accountResetCreditsSchema = external_exports.object({
14701
14761
  expiresAt: external_exports.array(external_exports.string().min(1)).min(1).max(32).optional()
14702
14762
  }).strict();
14703
14763
  var accountCreditsSnapshotSchema = external_exports.object({
14764
+ used: external_exports.number().finite().nonnegative().optional(),
14765
+ // Zero is a real empty cap, not an absent field.
14766
+ limit: external_exports.number().finite().nonnegative().optional(),
14767
+ unit: external_exports.string().min(1).max(32).optional(),
14704
14768
  /** Native label when the primary limit is scoped to a model or product group. */
14705
14769
  label: external_exports.string().min(1).optional(),
14706
14770
  usedPercent: usagePercentSchema,
@@ -14720,12 +14784,27 @@ var threadUsageInspectionSchema = external_exports.object({
14720
14784
  }).strict();
14721
14785
 
14722
14786
  // ../../shared-contracts/dist/harness-accounts.js
14723
- var harnessAccountSnapshotSchema = external_exports.object({
14787
+ var accountBalanceSnapshotSchema = external_exports.object({
14788
+ amount: external_exports.number().finite().nonnegative(),
14789
+ /** ISO 4217 code as reported by the Provider, for example `CNY`. */
14790
+ currency: external_exports.string().trim().min(1).max(8),
14791
+ /** Native label when the Harness exposes several Billing Sources. */
14792
+ label: external_exports.string().trim().min(1).max(128).optional()
14793
+ }).strict();
14794
+ var harnessAccountSnapshotObject = external_exports.object({
14724
14795
  email: external_exports.string().trim().min(1).max(320).optional(),
14725
14796
  label: external_exports.string().trim().min(1).max(256).optional(),
14726
14797
  plan: external_exports.string().trim().min(1).max(128).optional(),
14727
- credits: accountCreditsSnapshotSchema
14798
+ credits: accountCreditsSnapshotSchema.optional(),
14799
+ balance: accountBalanceSnapshotSchema.optional()
14728
14800
  }).strict();
14801
+ function requireReportedQuota(schema) {
14802
+ return schema.refine((value) => {
14803
+ const reported = value;
14804
+ return reported.credits !== void 0 || reported.balance !== void 0;
14805
+ }, { message: "Account must report either credits or a balance" });
14806
+ }
14807
+ var harnessAccountSnapshotSchema = requireReportedQuota(harnessAccountSnapshotObject);
14729
14808
  var harnessAccountIdentityShape = {
14730
14809
  harnessId: harnessIdSchema,
14731
14810
  harnessName: external_exports.string().trim().min(1).max(128)
@@ -14736,11 +14815,13 @@ var harnessAccountSourceListResultSchema = external_exports.object({ sources: ex
14736
14815
  var harnessAccountInspectParamsSchema = external_exports.object({ harnessId: harnessIdSchema, refresh: external_exports.boolean().optional() }).strict();
14737
14816
  var harnessAccountInspectResultSchema = external_exports.object({
14738
14817
  ...harnessAccountIdentityShape,
14739
- account: harnessAccountSnapshotSchema.nullable()
14818
+ account: harnessAccountSnapshotSchema.nullable(),
14819
+ /** Every Billing Source from one Harness; `account` remains the first for older clients. */
14820
+ accounts: external_exports.array(harnessAccountSnapshotSchema).max(8).optional()
14740
14821
  }).strict();
14741
14822
  var harnessAccountListParamsSchema = external_exports.object({ refresh: external_exports.boolean().optional() }).strict();
14742
14823
  var harnessAccountListResultSchema = external_exports.object({
14743
- accounts: external_exports.array(harnessAccountSnapshotSchema.extend(harnessAccountIdentityShape)).max(128)
14824
+ accounts: external_exports.array(requireReportedQuota(harnessAccountSnapshotObject.extend(harnessAccountIdentityShape))).max(128)
14744
14825
  }).strict();
14745
14826
 
14746
14827
  // ../../shared-contracts/dist/json-value.js
@@ -14878,6 +14959,8 @@ var harnessModelSchema = external_exports.object({
14878
14959
  ref: harnessModelRefSchema,
14879
14960
  label: nonBlankTextSchema2.max(HARNESS_MODEL_LABEL_MAX_LENGTH),
14880
14961
  resolvedModelLabel: harnessResolvedModelLabelSchema.optional(),
14962
+ /** Optional opaque selection for this same Model with priority processing enabled. */
14963
+ fastModel: harnessModelRefSchema.optional(),
14881
14964
  supportedThinkingOptionIds: external_exports.array(harnessThinkingOptionIdSchema).optional()
14882
14965
  }).strict();
14883
14966
  var harnessThinkingOptionsSchema = external_exports.array(harnessThinkingOptionSchema).superRefine((options, context) => {
@@ -14910,6 +14993,16 @@ var harnessModelCatalogSchema = external_exports.object({
14910
14993
  });
14911
14994
  }
14912
14995
  refs.add(model.ref.id);
14996
+ if (model.fastModel) {
14997
+ if (refs.has(model.fastModel.id) || catalog.models.some((entry) => entry.ref.id === model.fastModel?.id)) {
14998
+ context.addIssue({
14999
+ code: "custom",
15000
+ message: "Fast Model refs must be distinct and unique",
15001
+ path: ["models", index, "fastModel"]
15002
+ });
15003
+ }
15004
+ refs.add(model.fastModel.id);
15005
+ }
14913
15006
  const supportedThinkingIds = /* @__PURE__ */ new Set();
14914
15007
  for (const [optionIndex, optionId] of (model.supportedThinkingOptionIds ?? []).entries()) {
14915
15008
  if (supportedThinkingIds.has(optionId)) {
@@ -15029,11 +15122,13 @@ var threadThinkingSelectParamsSchema = external_exports.object({
15029
15122
  thinkingOptionId: harnessThinkingOptionIdSchema
15030
15123
  }).strict();
15031
15124
  var threadInspectionParamsSchema = external_exports.object({
15032
- threadId: hostThreadIdSchema
15125
+ threadId: hostThreadIdSchema,
15126
+ includeReferenceCapability: external_exports.boolean().optional()
15033
15127
  }).strict();
15034
15128
  var codexThreadInspectionSchema = external_exports.object({
15035
15129
  owner: external_exports.literal("codex"),
15036
- locked: external_exports.literal(true)
15130
+ locked: external_exports.literal(true),
15131
+ supportsThreadReferences: external_exports.literal(true).optional()
15037
15132
  }).strict();
15038
15133
  var externalThreadInspectionSchema = external_exports.object({
15039
15134
  owner: external_exports.literal("external"),
@@ -15159,6 +15254,22 @@ var harnessLaunchSettingsSchema = external_exports.object({
15159
15254
  restartRequired: external_exports.boolean()
15160
15255
  }).strict();
15161
15256
 
15257
+ // ../../shared-contracts/dist/harness-installation.js
15258
+ var harnessInstallationParamsSchema = external_exports.object({
15259
+ harnessId: harnessIdSchema,
15260
+ action: external_exports.enum(["check", "update", "install"])
15261
+ }).strict();
15262
+ var harnessInstallationStateSchema = external_exports.object({
15263
+ currentVersion: external_exports.string().min(1).max(128),
15264
+ latestVersion: external_exports.string().min(1).max(128),
15265
+ updateAvailable: external_exports.boolean(),
15266
+ canUpdate: external_exports.boolean(),
15267
+ // Adapter-owned diagnostic text; UI uses messageCode rather than displaying it verbatim.
15268
+ message: external_exports.string().max(2048).optional(),
15269
+ messageCode: external_exports.string().min(1).max(128).optional(),
15270
+ latestVersionKind: external_exports.enum(["unknown", "tracking-branch"]).optional()
15271
+ }).strict();
15272
+
15162
15273
  // ../../shared-contracts/dist/codex-accounts.js
15163
15274
  var accountIdSchema = external_exports.string().min(1).max(256).regex(/^[A-Za-z0-9._~-]+$/u);
15164
15275
  var nonBlankTextSchema3 = external_exports.string().trim().min(1);
@@ -15458,6 +15569,38 @@ var updateStatusResultSchema = external_exports.strictObject({
15458
15569
  status: updateStatusSchema.nullable()
15459
15570
  });
15460
15571
 
15572
+ // ../../shared-contracts/dist/remote-runtime.js
15573
+ var remoteUpdatePhaseSchema = external_exports.enum([
15574
+ "idle",
15575
+ "installing",
15576
+ "restarting",
15577
+ "succeeded",
15578
+ "failed"
15579
+ ]);
15580
+ var runtimeStatusSchema = external_exports.object({
15581
+ runningVersion: external_exports.string().nullable(),
15582
+ installedVersion: external_exports.string().nullable(),
15583
+ restartRequired: external_exports.boolean(),
15584
+ remote: external_exports.boolean(),
15585
+ updateSupported: external_exports.boolean(),
15586
+ update: external_exports.object({
15587
+ phase: remoteUpdatePhaseSchema,
15588
+ targetVersion: external_exports.string().nullable(),
15589
+ error: external_exports.string().nullable()
15590
+ })
15591
+ });
15592
+ var remoteUpdateParamsSchema = external_exports.object({
15593
+ version: external_exports.string().regex(/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u)
15594
+ }).strict();
15595
+ var remoteSshSetupParamsSchema = external_exports.object({
15596
+ hostname: external_exports.string().min(1).max(1024).refine((value) => !value.startsWith("-") && !/\s/u.test(value)),
15597
+ port: external_exports.number().int().min(1).max(65535).nullable(),
15598
+ identity: external_exports.string().max(4096).nullable(),
15599
+ action: external_exports.enum(["inspect", "install", "update", "repair"]),
15600
+ version: external_exports.string().regex(/^\d+\.\d+\.\d+$/u).nullable()
15601
+ }).strict();
15602
+ var remoteSshSetupResultSchema = external_exports.object({ state: external_exports.enum(["installed", "not-installed"]) }).strict();
15603
+
15461
15604
  // ../../shared-contracts/dist/index.js
15462
15605
  var workspaceContractVersionSchema = external_exports.literal(WORKSPACE_CONTRACT_VERSION);
15463
15606
 
@@ -15901,6 +16044,7 @@ function defaultHarnessBrokerDescriptorPath(environment = process.env, harnessId
15901
16044
  var cwdSchema = external_exports.string().min(1).max(16384);
15902
16045
  var brokerEnvironmentSchema = external_exports.object({
15903
16046
  CODEXHOST_CLI_PATH: external_exports.string().max(16384).optional(),
16047
+ CODEXHOST_CLI_NODE_PATH: external_exports.string().max(16384).optional(),
15904
16048
  CODEXHOST_RUNTIME_ENDPOINT: external_exports.string().max(16384).optional(),
15905
16049
  CODEXHOST_RUNTIME_TOKEN: external_exports.string().max(16384).optional(),
15906
16050
  CODEXHOST_THREAD_ID: external_exports.string().max(256).optional()
@@ -16055,6 +16199,7 @@ var eventKeys = /* @__PURE__ */ new Map([
16055
16199
  ["item.started", /* @__PURE__ */ new Set(["type", "turnId", "item"])],
16056
16200
  ["item.updated", /* @__PURE__ */ new Set(["type", "turnId", "itemId", "update"])],
16057
16201
  ["item.completed", /* @__PURE__ */ new Set(["type", "turnId", "snapshot"])],
16202
+ ["item.detached", /* @__PURE__ */ new Set(["type", "turnId", "itemId"])],
16058
16203
  ["interaction.closed", /* @__PURE__ */ new Set(["type", "interactionId", "turnId", "reason"])],
16059
16204
  ["turn.completed", /* @__PURE__ */ new Set(["type", "turnId", "nativeTurnRef", "outcome"])],
16060
16205
  ["session.faulted", /* @__PURE__ */ new Set(["type", "error"])]
@@ -16623,6 +16768,7 @@ var BrokeredHarnessAdapter = class {
16623
16768
  if (this.#forwardEnvironment && input.environment) {
16624
16769
  const allowed2 = [
16625
16770
  "CODEXHOST_CLI_PATH",
16771
+ "CODEXHOST_CLI_NODE_PATH",
16626
16772
  "CODEXHOST_RUNTIME_ENDPOINT",
16627
16773
  "CODEXHOST_RUNTIME_TOKEN",
16628
16774
  "CODEXHOST_THREAD_ID"
@@ -16680,7 +16826,7 @@ var BrokeredHarnessAdapter = class {
16680
16826
 
16681
16827
  // dist/claude-code-adapter.js
16682
16828
  import { randomUUID as randomUUID3 } from "node:crypto";
16683
- import path12 from "node:path";
16829
+ import path14 from "node:path";
16684
16830
 
16685
16831
  // ../../../node_modules/@anthropic-ai/claude-agent-sdk/sdk.mjs
16686
16832
  import { createRequire as DW } from "node:module";
@@ -42377,32 +42523,109 @@ import { opendir, realpath, stat } from "node:fs/promises";
42377
42523
  import os2 from "node:os";
42378
42524
  import path2 from "node:path";
42379
42525
  import { createInterface } from "node:readline";
42380
- var CLAUDE_SESSION_IMPORT_TITLE_MAX_LENGTH = 120;
42381
- var CLAUDE_INTERNAL_USER_TEXT = /^<(?:local-command-|command-)/u;
42382
- var ClaudeSessionChangedError = class extends Error {
42383
- constructor() {
42384
- super("Claude Code Session changed during discovery; refresh and retry");
42526
+
42527
+ // ../../harness-adapter/dist/session-import.js
42528
+ var SessionImportChangedError = class extends Error {
42529
+ constructor(message = "Native Session changed during discovery; refresh and retry") {
42530
+ super(message);
42531
+ this.name = "SessionImportChangedError";
42385
42532
  }
42386
42533
  };
42387
- function isRecord2(value) {
42388
- return typeof value === "object" && value !== null && !Array.isArray(value);
42389
- }
42390
- function missing(error52) {
42391
- return isRecord2(error52) && error52.code === "ENOENT";
42534
+ function isMissingFileError(error52) {
42535
+ return typeof error52 === "object" && error52 !== null && "code" in error52 && error52.code === "ENOENT";
42392
42536
  }
42393
- function sameFile(left, right) {
42394
- return left.size === right.size && left.mtimeMs === right.mtimeMs && left.ctimeMs === right.ctimeMs && left.ino === right.ino && left.dev === right.dev;
42537
+ function sameFileFingerprint(left, right) {
42538
+ return left === null || right === null ? left === right : left.dev === right.dev && left.ino === right.ino && left.size === right.size && left.mtimeMs === right.mtimeMs && left.ctimeMs === right.ctimeMs;
42395
42539
  }
42396
- function cleanText(value) {
42540
+ function sessionImportTitle(value, maxLength = HARNESS_SESSION_IMPORT_TITLE_MAX_LENGTH) {
42397
42541
  if (typeof value !== "string")
42398
42542
  return null;
42399
42543
  const normalized = value.replaceAll("\0", "").replaceAll(/\s+/gu, " ").trim();
42400
42544
  if (!normalized)
42401
42545
  return null;
42546
+ if (normalized.length <= maxLength)
42547
+ return normalized;
42402
42548
  const characters = [...normalized];
42403
- if (characters.length <= CLAUDE_SESSION_IMPORT_TITLE_MAX_LENGTH)
42549
+ if (characters.length <= maxLength)
42404
42550
  return normalized;
42405
- return `${characters.slice(0, CLAUDE_SESSION_IMPORT_TITLE_MAX_LENGTH - 1).join("").trimEnd()}…`;
42551
+ return `${characters.slice(0, maxLength - 1).join("").trimEnd()}…`;
42552
+ }
42553
+ function sessionImportCandidate(input) {
42554
+ const time3 = typeof input.updatedAt === "number" ? input.updatedAt : typeof input.updatedAt === "string" ? Date.parse(input.updatedAt) : Number.NaN;
42555
+ const parsed = harnessSessionImportCandidateSchema.safeParse({
42556
+ nativeSessionId: input.nativeSessionId,
42557
+ cwd: input.cwd,
42558
+ title: typeof input.title === "string" && input.title.trim().length > 0 ? input.title : null,
42559
+ updatedAt: Math.floor(time3),
42560
+ // Unknown must stay unknown; only an explicit boolean is a native statement.
42561
+ running: typeof input.running === "boolean" ? input.running : null
42562
+ });
42563
+ return parsed.success ? parsed.data : null;
42564
+ }
42565
+ var SessionImportScope = class {
42566
+ #abort = new AbortController();
42567
+ #options;
42568
+ #pending = /* @__PURE__ */ new Set();
42569
+ constructor(options) {
42570
+ this.#options = options;
42571
+ }
42572
+ #closed() {
42573
+ return {
42574
+ ok: false,
42575
+ error: { code: "invalidState", message: this.#options.closedMessage, retryable: false }
42576
+ };
42577
+ }
42578
+ read(operation) {
42579
+ const signal = this.#abort.signal;
42580
+ if (signal.aborted)
42581
+ return Promise.resolve(this.#closed());
42582
+ let started;
42583
+ try {
42584
+ started = operation(signal);
42585
+ } catch (error52) {
42586
+ started = Promise.reject(error52 instanceof Error ? error52 : new Error("Session read failed"));
42587
+ }
42588
+ const request = started.then((value) => signal.aborted ? this.#closed() : { ok: true, value }).catch(() => signal.aborted ? this.#closed() : {
42589
+ ok: false,
42590
+ error: {
42591
+ code: "unavailable",
42592
+ message: this.#options.unavailableMessage,
42593
+ retryable: true
42594
+ }
42595
+ }).finally(() => this.#pending.delete(request));
42596
+ this.#pending.add(request);
42597
+ return request;
42598
+ }
42599
+ /** `read` for `resolveCandidate`: a null source is the selected Session having disappeared. */
42600
+ async resolve(operation) {
42601
+ const result = await this.read(operation);
42602
+ if (!result.ok)
42603
+ return result;
42604
+ return result.value ? { ok: true, value: result.value } : {
42605
+ ok: false,
42606
+ error: {
42607
+ code: "sessionNotFound",
42608
+ message: this.#options.notFoundMessage,
42609
+ retryable: false
42610
+ }
42611
+ };
42612
+ }
42613
+ /** Idempotent. Resolves after every started read has settled. */
42614
+ async close() {
42615
+ this.#abort.abort();
42616
+ await Promise.allSettled(this.#pending);
42617
+ }
42618
+ };
42619
+
42620
+ // dist/claude-session-import.js
42621
+ var CLAUDE_SESSION_IMPORT_TITLE_MAX_LENGTH = 120;
42622
+ var CLAUDE_INTERNAL_USER_TEXT = /^<(?:local-command-|command-)/u;
42623
+ var CLAUDE_SESSION_CHANGED = "Claude Code Session changed during discovery; refresh and retry";
42624
+ function isRecord2(value) {
42625
+ return typeof value === "object" && value !== null && !Array.isArray(value);
42626
+ }
42627
+ function cleanText(value) {
42628
+ return sessionImportTitle(value, CLAUDE_SESSION_IMPORT_TITLE_MAX_LENGTH);
42406
42629
  }
42407
42630
  function userText(message) {
42408
42631
  if (!isRecord2(message) || message.role !== "user")
@@ -42418,7 +42641,7 @@ function claudeProjectsDirectory(environment) {
42418
42641
  async function sessionFiles(directory, signal) {
42419
42642
  signal.throwIfAborted();
42420
42643
  const projects = await opendir(directory).catch((error52) => {
42421
- if (missing(error52))
42644
+ if (isMissingFileError(error52))
42422
42645
  return null;
42423
42646
  throw error52;
42424
42647
  });
@@ -42430,7 +42653,7 @@ async function sessionFiles(directory, signal) {
42430
42653
  if (!project.isDirectory())
42431
42654
  continue;
42432
42655
  const entries = await opendir(path2.join(directory, project.name)).catch((error52) => {
42433
- if (missing(error52))
42656
+ if (isMissingFileError(error52))
42434
42657
  return null;
42435
42658
  throw error52;
42436
42659
  });
@@ -42497,24 +42720,23 @@ async function readCandidate(file2, signal) {
42497
42720
  if (!hasConversation || !cwd)
42498
42721
  return null;
42499
42722
  const after = await stat(file2);
42500
- if (!sameFile(before, after))
42501
- throw new ClaudeSessionChangedError();
42723
+ if (!sameFileFingerprint(before, after))
42724
+ throw new SessionImportChangedError(CLAUDE_SESSION_CHANGED);
42502
42725
  const resolvedCwd = await realpath(cwd);
42503
42726
  if (!(await stat(resolvedCwd)).isDirectory())
42504
42727
  return null;
42505
- const candidate = harnessSessionImportCandidateSchema.safeParse({
42728
+ const candidate = sessionImportCandidate({
42506
42729
  nativeSessionId,
42507
42730
  title: customTitle ?? generatedTitle ?? firstPrompt,
42508
- updatedAt: Math.floor(before.mtimeMs),
42509
- cwd: resolvedCwd,
42510
- running: null
42731
+ updatedAt: before.mtimeMs,
42732
+ cwd: resolvedCwd
42511
42733
  });
42512
42734
  const nativeRef = nativeSessionRefSchema.safeParse({
42513
42735
  harnessId: "claude-code",
42514
42736
  nativeSessionId,
42515
42737
  formatVersion: 1
42516
42738
  });
42517
- return candidate.success && nativeRef.success ? { candidate: candidate.data, nativeRef: nativeRef.data } : null;
42739
+ return candidate && nativeRef.success ? { candidate, nativeRef: nativeRef.data } : null;
42518
42740
  }
42519
42741
  var ClaudeSessionImportIndex = class {
42520
42742
  #directory;
@@ -42538,7 +42760,7 @@ var ClaudeSessionImportIndex = class {
42538
42760
  try {
42539
42761
  const fingerprint = await stat(file2);
42540
42762
  const cached2 = this.#cache.get(file2);
42541
- const source = cached2 && sameFile(cached2.fingerprint, fingerprint) ? cached2.source : await readCandidate(file2, signal);
42763
+ const source = cached2 && sameFileFingerprint(cached2.fingerprint, fingerprint) ? cached2.source : await readCandidate(file2, signal);
42542
42764
  if (!source)
42543
42765
  continue;
42544
42766
  if (!(await stat(source.candidate.cwd)).isDirectory())
@@ -42550,7 +42772,7 @@ var ClaudeSessionImportIndex = class {
42550
42772
  next.set(file2, { fingerprint, source });
42551
42773
  sources.push(source);
42552
42774
  } catch (error52) {
42553
- if (!missing(error52) && !(error52 instanceof ClaudeSessionChangedError))
42775
+ if (!isMissingFileError(error52) && !(error52 instanceof SessionImportChangedError))
42554
42776
  throw error52;
42555
42777
  }
42556
42778
  }
@@ -42575,7 +42797,7 @@ var ClaudeSessionImportIndex = class {
42575
42797
  const source = await readCandidate(selected, signal);
42576
42798
  return source?.candidate.nativeSessionId === nativeSessionId ? source : null;
42577
42799
  } catch (error52) {
42578
- if (missing(error52))
42800
+ if (isMissingFileError(error52))
42579
42801
  return null;
42580
42802
  throw error52;
42581
42803
  }
@@ -42583,7 +42805,7 @@ var ClaudeSessionImportIndex = class {
42583
42805
  };
42584
42806
 
42585
42807
  // dist/command.js
42586
- import path5 from "node:path";
42808
+ import path7 from "node:path";
42587
42809
 
42588
42810
  // ../../harness-discovery/dist/environment.js
42589
42811
  import fs from "node:fs";
@@ -42631,12 +42853,28 @@ function newestFirst(names) {
42631
42853
  return [...names].sort((left, right) => right.localeCompare(left, void 0, { numeric: true }));
42632
42854
  }
42633
42855
 
42634
- // ../../harness-discovery/dist/node-runtime.js
42856
+ // ../../harness-discovery/dist/invocation.js
42635
42857
  import path4 from "node:path";
42858
+ function commandInvocation(command, arguments_, environment, platform = process.platform) {
42859
+ const extension = path4.win32.extname(command).toLowerCase();
42860
+ if (platform !== "win32" || ![".cmd", ".bat"].includes(extension)) {
42861
+ return { command, arguments: [...arguments_], windowsVerbatimArguments: false };
42862
+ }
42863
+ const quote = (value) => `"${value.replaceAll("%", "%%").replaceAll('"', '""')}"`;
42864
+ const commandLine = [command, ...arguments_].map(quote).join(" ");
42865
+ return {
42866
+ command: environmentValue(environment, "ComSpec") ?? "cmd.exe",
42867
+ arguments: ["/d", "/v:off", "/s", "/c", `"${commandLine}"`],
42868
+ windowsVerbatimArguments: true
42869
+ };
42870
+ }
42871
+
42872
+ // ../../harness-discovery/dist/node-runtime.js
42873
+ import path5 from "node:path";
42636
42874
  function withNodeRuntimeOnPath(environment, runtimeExecutable = process.execPath, platform = process.platform) {
42637
42875
  const pathKey = Object.keys(environment).find((name) => name.toLowerCase() === "path") ?? "PATH";
42638
42876
  const delimiter = platform === "win32" ? ";" : ":";
42639
- const runtimeDirectory = path4.dirname(runtimeExecutable);
42877
+ const runtimeDirectory = path5.dirname(runtimeExecutable);
42640
42878
  const directories = (environment[pathKey] ?? "").split(delimiter).filter(Boolean);
42641
42879
  const equal = platform === "win32" ? (value) => value.toLowerCase() : (value) => value;
42642
42880
  if (!directories.some((directory) => equal(directory) === equal(runtimeDirectory))) {
@@ -42808,6 +43046,249 @@ function resolveHarnessExecutable(spec, input, dependencies = {}) {
42808
43046
  return void 0;
42809
43047
  }
42810
43048
 
43049
+ // ../../harness-discovery/dist/installation.js
43050
+ import { execFile } from "node:child_process";
43051
+ import { homedir } from "node:os";
43052
+ function runInstallationCommand(command, args, environment, timeout = 3e4) {
43053
+ const env = withNodeRuntimeOnPath(environment);
43054
+ const invocation = /\.[cm]?js$/i.test(command) ? commandInvocation(process.execPath, [command, ...args], env) : commandInvocation(command, args, env);
43055
+ return new Promise((resolve2, reject) => {
43056
+ const child = execFile(invocation.command, invocation.arguments, {
43057
+ env,
43058
+ cwd: env.HOME ?? env.USERPROFILE ?? homedir(),
43059
+ encoding: "utf8",
43060
+ timeout,
43061
+ killSignal: "SIGKILL",
43062
+ maxBuffer: 1024 * 1024,
43063
+ windowsHide: true,
43064
+ windowsVerbatimArguments: invocation.windowsVerbatimArguments
43065
+ }, (error52, stdout, stderr) => {
43066
+ if (error52)
43067
+ reject(new Error(error52.killed ? "Harness command timed out" : "Harness command failed; check the native installation and retry"));
43068
+ else
43069
+ resolve2((stdout || stderr).trim());
43070
+ });
43071
+ child.stdin?.end();
43072
+ });
43073
+ }
43074
+ function installationVersion(value) {
43075
+ if (typeof value !== "string" || !/^v?\d+(?:\.\d+){1,3}(?:-[\w.-]+)?(?:\+[\w.-]+)?$/.test(value.trim()))
43076
+ throw new Error("Harness returned an invalid version");
43077
+ return value.trim().replace(/^v/, "");
43078
+ }
43079
+ function versionFromOutput(output) {
43080
+ return installationVersion(output.match(/\b\d+(?:\.\d+){1,3}(?:-[\w.-]+)?(?:\+[\w.-]+)?\b/)?.[0]);
43081
+ }
43082
+ function newerInstallationVersion(current, latest) {
43083
+ const a = installationVersion(current).replace(/\+.*/, "");
43084
+ const b = installationVersion(latest).replace(/\+.*/, "");
43085
+ const coreA = a.replace(/-.*/, "").split(".").map(BigInt);
43086
+ const coreB = b.replace(/-.*/, "").split(".").map(BigInt);
43087
+ for (let i = 0; i < Math.max(coreA.length, coreB.length); i++) {
43088
+ if ((coreA[i] ?? 0n) !== (coreB[i] ?? 0n))
43089
+ return (coreB[i] ?? 0n) > (coreA[i] ?? 0n);
43090
+ }
43091
+ const preA = a.includes("-") ? a.slice(a.indexOf("-") + 1).split(".") : [];
43092
+ const preB = b.includes("-") ? b.slice(b.indexOf("-") + 1).split(".") : [];
43093
+ if (!preA.length || !preB.length)
43094
+ return !!preA.length && !preB.length;
43095
+ for (let i = 0; i < Math.max(preA.length, preB.length); i++) {
43096
+ const x2 = preA[i];
43097
+ const y = preB[i];
43098
+ if (x2 === y)
43099
+ continue;
43100
+ if (x2 === void 0 || y === void 0)
43101
+ return x2 === void 0;
43102
+ const numericX = /^\d+$/.test(x2);
43103
+ const numericY = /^\d+$/.test(y);
43104
+ if (numericX && numericY) {
43105
+ if (BigInt(x2) === BigInt(y))
43106
+ continue;
43107
+ return BigInt(y) > BigInt(x2);
43108
+ }
43109
+ if (numericX !== numericY)
43110
+ return numericX;
43111
+ return y > x2;
43112
+ }
43113
+ return false;
43114
+ }
43115
+ function createInstallationManager(options) {
43116
+ let checking;
43117
+ let updating;
43118
+ const check2 = () => checking ??= options.check().finally(() => {
43119
+ checking = void 0;
43120
+ });
43121
+ return (action) => {
43122
+ if (updating)
43123
+ return updating;
43124
+ if (action === "check")
43125
+ return check2();
43126
+ updating = (async () => {
43127
+ const before = await check2();
43128
+ if (!before.updateAvailable)
43129
+ return before;
43130
+ if (!before.canUpdate)
43131
+ throw new Error(before.message ?? "This installation cannot be updated automatically");
43132
+ await options.update(before);
43133
+ const after = await check2();
43134
+ if (after.currentVersion === before.currentVersion)
43135
+ throw new Error("The Harness version did not change; check the native updater and retry");
43136
+ return after;
43137
+ })().finally(() => {
43138
+ updating = void 0;
43139
+ });
43140
+ return updating;
43141
+ };
43142
+ }
43143
+ async function fetchInstallationText(url2) {
43144
+ const request = async () => {
43145
+ const response = await fetch(url2, { signal: AbortSignal.timeout(15e3) });
43146
+ if (!response.ok)
43147
+ throw new Error("Could not check the latest Harness version");
43148
+ return response.text();
43149
+ };
43150
+ try {
43151
+ return await request();
43152
+ } catch (error52) {
43153
+ if (error52 instanceof DOMException && (error52.name === "AbortError" || error52.name === "TimeoutError"))
43154
+ throw error52;
43155
+ return request();
43156
+ }
43157
+ }
43158
+
43159
+ // ../../harness-discovery/dist/npm-installation.js
43160
+ import { readFile as readFile2, realpath as realpath2 } from "node:fs/promises";
43161
+ import path6 from "node:path";
43162
+ function referencesNpmBin(shim, name, bin) {
43163
+ if (bin.includes(".."))
43164
+ return false;
43165
+ const target = `node_modules/${name}/${bin.replace(/^\.\//, "")}`.toLowerCase();
43166
+ const text = shim.replaceAll("\\", "/").toLowerCase();
43167
+ return text.includes(`%dp0%/${target}"`) || text.includes(`%~dp0/${target}"`);
43168
+ }
43169
+ async function npmInstallation(command, packages, environment) {
43170
+ let selected = await realpath2(command);
43171
+ if (process.platform === "win32" && /\.(cmd|bat)$/i.test(selected)) {
43172
+ const shim = (await readFile2(selected, "utf8")).replaceAll("\\", "/");
43173
+ const root = path6.dirname(selected);
43174
+ for (const name of packages) {
43175
+ const directory2 = path6.join(root, "node_modules", ...name.split("/"));
43176
+ const metadata = await readFile2(path6.join(directory2, "package.json"), "utf8").then((text) => JSON.parse(text)).catch(() => null);
43177
+ const bins = typeof metadata?.bin === "string" ? [metadata.bin] : Object.values(metadata?.bin ?? {});
43178
+ const bin = bins.find((entry) => referencesNpmBin(shim, name, entry));
43179
+ if (bin) {
43180
+ selected = await realpath2(path6.join(directory2, bin));
43181
+ break;
43182
+ }
43183
+ }
43184
+ }
43185
+ let directory = path6.dirname(selected);
43186
+ for (let depth = 0; depth < 8; depth++) {
43187
+ const metadata = await readFile2(path6.join(directory, "package.json"), "utf8").then((text) => JSON.parse(text)).catch(() => null);
43188
+ if (metadata?.name && packages.includes(metadata.name)) {
43189
+ const name = metadata.name;
43190
+ const currentVersion = installationVersion(metadata.version);
43191
+ const segments = name.split("/");
43192
+ let modules = directory;
43193
+ for (let index = 0; index < segments.length; index++)
43194
+ modules = path6.dirname(modules);
43195
+ const prefix = process.platform === "win32" ? path6.dirname(modules) : path6.dirname(path6.dirname(modules));
43196
+ const globalRoot = process.platform === "win32" ? path6.join(prefix, "node_modules") : path6.join(prefix, "lib", "node_modules");
43197
+ const env = withNodeRuntimeOnPath(environment);
43198
+ const npm = resolveHarnessExecutable({ id: "npm", command: "npm", installRoots: { posix: [], windows: [] } }, { environment: env });
43199
+ let globalInstall = modules === globalRoot;
43200
+ if (process.platform === "win32") {
43201
+ const project = (await Promise.all(["package.json", "package-lock.json", "npm-shrinkwrap.json"].map((file2) => readFile2(path6.join(prefix, file2), "utf8").then(() => true, (error52) => error52.code !== "ENOENT")))).some(Boolean);
43202
+ const bins = typeof metadata.bin === "string" ? { [name.split("/").at(-1) ?? name]: metadata.bin } : metadata.bin ?? {};
43203
+ const launchers = await Promise.all(Object.entries(bins).map(async ([bin, entry]) => {
43204
+ if (path6.basename(bin) !== bin || entry.includes(".."))
43205
+ return false;
43206
+ const target = await realpath2(path6.join(directory, entry)).catch(() => "");
43207
+ if (target.toLowerCase() !== selected.toLowerCase())
43208
+ return false;
43209
+ const shim = await readFile2(path6.join(prefix, `${bin}.cmd`), "utf8").catch(() => "");
43210
+ return referencesNpmBin(shim, name, entry);
43211
+ }));
43212
+ globalInstall = globalInstall && !project && launchers.some(Boolean);
43213
+ }
43214
+ const canUpdate = globalInstall && !!npm;
43215
+ return {
43216
+ prefix,
43217
+ currentVersion,
43218
+ canUpdate,
43219
+ latest: async () => {
43220
+ const data = JSON.parse(await fetchInstallationText(`https://registry.npmjs.org/${encodeURIComponent(name)}/latest`));
43221
+ return installationVersion(data.version);
43222
+ },
43223
+ update: async (version2) => {
43224
+ if (!canUpdate || !npm)
43225
+ throw new Error("Use the original package manager to update this installation");
43226
+ await runInstallationCommand(npm.executable, ["install", "--global", "--prefix", prefix, `${name}@${installationVersion(version2)}`], env, 3e5);
43227
+ }
43228
+ };
43229
+ }
43230
+ const parent = path6.dirname(directory);
43231
+ if (parent === directory)
43232
+ break;
43233
+ directory = parent;
43234
+ }
43235
+ return null;
43236
+ }
43237
+
43238
+ // ../../harness-discovery/dist/installer.js
43239
+ import { mkdtemp, rm as rm2, writeFile } from "node:fs/promises";
43240
+ import { tmpdir } from "node:os";
43241
+ import { join as join2 } from "node:path";
43242
+ function createHarnessInstaller(environment, source) {
43243
+ return async () => {
43244
+ if (!["darwin", "linux", "win32"].includes(process.platform))
43245
+ throw new Error("Unsupported installation platform");
43246
+ const env = withNodeRuntimeOnPath(environment);
43247
+ if ("npm" in source) {
43248
+ const npm = resolveHarnessExecutable({
43249
+ id: "npm",
43250
+ command: "npm",
43251
+ installRoots: {
43252
+ posix: [
43253
+ "~/.npm-global/bin",
43254
+ "~/.local/bin",
43255
+ VERSION_MANAGER_ROOTS,
43256
+ "/opt/homebrew/bin",
43257
+ "/usr/local/bin",
43258
+ "/usr/bin"
43259
+ ],
43260
+ windows: [
43261
+ "${APPDATA}/npm",
43262
+ VERSION_MANAGER_ROOTS,
43263
+ "${ProgramFiles}/nodejs",
43264
+ "${LOCALAPPDATA}/Programs/nodejs"
43265
+ ]
43266
+ }
43267
+ }, { environment: env });
43268
+ if (!npm)
43269
+ throw new Error("Install Node.js and npm first");
43270
+ await runInstallationCommand(npm.executable, ["install", "--global", source.npm], {
43271
+ ...env,
43272
+ ...source.allowScripts ? { npm_config_allow_scripts: source.allowScripts } : {}
43273
+ }, 6e5);
43274
+ return;
43275
+ }
43276
+ const windows = process.platform === "win32";
43277
+ const url2 = windows ? source.windows : source.posix;
43278
+ if (new URL(url2).protocol !== "https:")
43279
+ throw new Error("Installer requires HTTPS");
43280
+ const script = await fetchInstallationText(url2);
43281
+ const directory = await mkdtemp(join2(tmpdir(), "codexhost-installer-"));
43282
+ try {
43283
+ const file2 = join2(directory, windows ? "install.ps1" : "install.sh");
43284
+ await writeFile(file2, script, { mode: 384 });
43285
+ await runInstallationCommand(windows ? "powershell.exe" : source.shell ?? "bash", windows ? ["-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-File", file2] : [file2], env, 6e5);
43286
+ } finally {
43287
+ await rm2(directory, { recursive: true, force: true });
43288
+ }
43289
+ };
43290
+ }
43291
+
42811
43292
  // dist/command.js
42812
43293
  var ClaudeCodeExecutableError = class extends Error {
42813
43294
  code = "CLAUDE_NOT_FOUND";
@@ -42854,14 +43335,14 @@ function resolveClaudeCodeExecutable(input = {}, dependencies = {}) {
42854
43335
  }, dependencies);
42855
43336
  if (!resolution)
42856
43337
  throw new ClaudeCodeExecutableError("Claude Code is not installed");
42857
- return targetPath(platform).isAbsolute(resolution.executable) ? resolution.executable : path5.resolve(resolution.executable);
43338
+ return targetPath(platform).isAbsolute(resolution.executable) ? resolution.executable : path7.resolve(resolution.executable);
42858
43339
  }
42859
43340
 
42860
43341
  // dist/pending-session.js
42861
43342
  import { randomUUID as randomUUID2 } from "node:crypto";
42862
- import { mkdir, open, readFile as readFile2, rename, rm as rm2, stat as stat2, unlink } from "node:fs/promises";
43343
+ import { mkdir, open, readFile as readFile3, rename, rm as rm3, stat as stat2, unlink } from "node:fs/promises";
42863
43344
  import os4 from "node:os";
42864
- import path6 from "node:path";
43345
+ import path8 from "node:path";
42865
43346
  var reservationSchema = external_exports.strictObject({
42866
43347
  version: external_exports.literal(1),
42867
43348
  sessionId: external_exports.uuid(),
@@ -42874,13 +43355,13 @@ function isPendingClaudeSession(ref) {
42874
43355
  var ClaudePendingSessions = class {
42875
43356
  #directory;
42876
43357
  constructor(environment) {
42877
- this.#directory = path6.join(path6.resolve(environment.CLAUDE_CONFIG_DIR ?? path6.join(os4.homedir(), ".claude")), "codexhost", "pending-sessions");
43358
+ this.#directory = path8.join(path8.resolve(environment.CLAUDE_CONFIG_DIR ?? path8.join(os4.homedir(), ".claude")), "codexhost", "pending-sessions");
42878
43359
  }
42879
43360
  #path(ref, cwd) {
42880
- if (ref.harnessId !== "claude-code" || !external_exports.uuid().safeParse(ref.nativeSessionId).success || !external_exports.strictObject({ pendingSession: external_exports.literal(1) }).safeParse(ref.locator).success || !path6.isAbsolute(cwd)) {
43361
+ if (ref.harnessId !== "claude-code" || !external_exports.uuid().safeParse(ref.nativeSessionId).success || !external_exports.strictObject({ pendingSession: external_exports.literal(1) }).safeParse(ref.locator).success || !path8.isAbsolute(cwd)) {
42881
43362
  throw new Error("Claude Code pending Session identity is invalid");
42882
43363
  }
42883
- return path6.join(this.#directory, ref.nativeSessionId);
43364
+ return path8.join(this.#directory, ref.nativeSessionId);
42884
43365
  }
42885
43366
  async create(cwd, configuration) {
42886
43367
  const ref = nativeSessionRefSchema.parse({
@@ -42899,7 +43380,7 @@ var ClaudePendingSessions = class {
42899
43380
  await mkdir(this.#directory, { recursive: true, mode: 448 });
42900
43381
  await mkdir(directory, { mode: 448 });
42901
43382
  try {
42902
- const file2 = await open(path6.join(directory, "session.json"), "wx", 384);
43383
+ const file2 = await open(path8.join(directory, "session.json"), "wx", 384);
42903
43384
  try {
42904
43385
  await file2.writeFile(JSON.stringify(reservation));
42905
43386
  await file2.sync();
@@ -42907,7 +43388,7 @@ var ClaudePendingSessions = class {
42907
43388
  await file2.close();
42908
43389
  }
42909
43390
  } catch (error52) {
42910
- await rm2(directory, { recursive: true, force: true });
43391
+ await rm3(directory, { recursive: true, force: true });
42911
43392
  throw error52;
42912
43393
  }
42913
43394
  await this.#sync(directory);
@@ -42916,13 +43397,13 @@ var ClaudePendingSessions = class {
42916
43397
  }
42917
43398
  async read(ref, cwd) {
42918
43399
  const directory = this.#path(ref, cwd);
42919
- const reservation = reservationSchema.parse(JSON.parse(await readFile2(path6.join(directory, "session.json"), "utf8")));
43400
+ const reservation = reservationSchema.parse(JSON.parse(await readFile3(path8.join(directory, "session.json"), "utf8")));
42920
43401
  if (reservation.sessionId !== ref.nativeSessionId || reservation.cwd !== cwd) {
42921
43402
  throw new Error("Claude Code pending Session does not belong to this working directory");
42922
43403
  }
42923
43404
  let started = false;
42924
43405
  try {
42925
- const claim = await stat2(path6.join(directory, "started"));
43406
+ const claim = await stat2(path8.join(directory, "started"));
42926
43407
  if (!claim.isFile())
42927
43408
  throw new Error("Claude Code pending Session claim is invalid");
42928
43409
  started = true;
@@ -42935,7 +43416,7 @@ var ClaudePendingSessions = class {
42935
43416
  async saveConfiguration(ref, cwd, configuration) {
42936
43417
  await this.read(ref, cwd);
42937
43418
  const directory = this.#path(ref, cwd);
42938
- const temporary = path6.join(directory, `${randomUUID2()}.tmp`);
43419
+ const temporary = path8.join(directory, `${randomUUID2()}.tmp`);
42939
43420
  try {
42940
43421
  const file2 = await open(temporary, "wx", 384);
42941
43422
  try {
@@ -42949,10 +43430,10 @@ var ClaudePendingSessions = class {
42949
43430
  } finally {
42950
43431
  await file2.close();
42951
43432
  }
42952
- await rename(temporary, path6.join(directory, "session.json"));
43433
+ await rename(temporary, path8.join(directory, "session.json"));
42953
43434
  await this.#sync(directory);
42954
43435
  } finally {
42955
- await rm2(temporary, { force: true });
43436
+ await rm3(temporary, { force: true });
42956
43437
  }
42957
43438
  }
42958
43439
  async #sync(directory) {
@@ -42967,7 +43448,7 @@ var ClaudePendingSessions = class {
42967
43448
  }
42968
43449
  async claim(ref, cwd) {
42969
43450
  await this.read(ref, cwd);
42970
- const claim = await open(path6.join(this.#path(ref, cwd), "started"), "wx", 384);
43451
+ const claim = await open(path8.join(this.#path(ref, cwd), "started"), "wx", 384);
42971
43452
  try {
42972
43453
  await claim.sync();
42973
43454
  } finally {
@@ -42977,249 +43458,1009 @@ var ClaudePendingSessions = class {
42977
43458
  }
42978
43459
  /** Only the claim owner may release, after proven close and before submitting any native input. */
42979
43460
  async release(ref, cwd) {
42980
- await unlink(path6.join(this.#path(ref, cwd), "started"));
43461
+ await unlink(path8.join(this.#path(ref, cwd), "started"));
42981
43462
  await this.#sync(this.#path(ref, cwd));
42982
43463
  }
42983
43464
  async discard(ref, cwd) {
42984
- await rm2(this.#path(ref, cwd), { recursive: true, force: true });
43465
+ await rm3(this.#path(ref, cwd), { recursive: true, force: true });
42985
43466
  }
42986
43467
  };
42987
43468
 
42988
43469
  // dist/claude-fork.js
42989
- import path7 from "node:path";
43470
+ import path10 from "node:path";
42990
43471
  import { isDeepStrictEqual } from "node:util";
42991
43472
 
42992
- // dist/item-identity.js
42993
- function claudeTranscriptItemId(nativeTurnKey, kind, ordinal) {
42994
- return hostItemIdSchema.parse(`claude-item-v2-${nativeTurnKey}-${kind}-${ordinal}`);
42995
- }
42996
-
42997
- // dist/claude-history.js
42998
- var claudeCodeHarnessId = harnessIdSchema.parse("claude-code");
43473
+ // dist/file-change.js
43474
+ import path9 from "node:path";
43475
+ var hunkSchema = external_exports.object({
43476
+ oldStart: external_exports.number().int().nonnegative(),
43477
+ oldLines: external_exports.number().int().nonnegative(),
43478
+ newStart: external_exports.number().int().nonnegative(),
43479
+ newLines: external_exports.number().int().nonnegative(),
43480
+ lines: external_exports.array(external_exports.string())
43481
+ }).strict();
42999
43482
  function isRecord3(value) {
43000
43483
  return typeof value === "object" && value !== null && !Array.isArray(value);
43001
43484
  }
43002
- function textParts(value) {
43003
- if (typeof value === "string")
43004
- return value.length > 0 ? [value] : [];
43005
- if (!Array.isArray(value))
43006
- return [];
43007
- return value.flatMap((part) => isRecord3(part) && part.type === "text" && typeof part.text === "string" ? [part.text] : []);
43485
+ function validNativePath(value) {
43486
+ return typeof value === "string" && value.trim().length > 0 && !value.includes("\0") && !value.includes("\n") && !value.includes("\r");
43008
43487
  }
43009
- function thinkingParts(value) {
43010
- if (!Array.isArray(value))
43011
- return [];
43012
- return value.flatMap((part) => isRecord3(part) && part.type === "thinking" && typeof part.thinking === "string" ? [part.thinking] : []);
43488
+ function countLines(lines, prefixes) {
43489
+ return lines.filter((line) => line.length > 0 && prefixes.has(line[0])).length;
43013
43490
  }
43014
- var localCommandRecordPattern = /^\s*<(local-command-(?:stdout|caveat))>[\s\S]*<\/\1>\s*$/u;
43015
- var taskNotificationRecordPattern = /^\s*<task-notification>[\s\S]*<\/task-notification>\s*$/u;
43016
- var commandEnvelopePattern = /^\s*(?:<(command-(?:message|name|args))>[\s\S]*?<\/\1>\s*)+$/u;
43017
- var controlCommandNamePattern = /<command-name>\s*\/(?:model|compact)\s*<\/command-name>/u;
43018
- var recapCommandNamePattern = /<command-name>\s*\/recap\s*<\/command-name>/u;
43019
- var initCommandNamePattern = /<command-name>\s*\/init\s*<\/command-name>/u;
43020
- var localCommandStdoutPattern = /^\s*<local-command-stdout>([\s\S]*)<\/local-command-stdout>\s*$/u;
43021
- function isLocalCommandRecord(text) {
43022
- return localCommandRecordPattern.test(text);
43491
+ function validHunk(value) {
43492
+ const parsed = hunkSchema.safeParse(value);
43493
+ if (!parsed.success)
43494
+ return null;
43495
+ const hunk = parsed.data;
43496
+ if (hunk.lines.some((line) => line.length === 0 || ![" ", "+", "-", "\\"].includes(line[0]))) {
43497
+ return null;
43498
+ }
43499
+ if (countLines(hunk.lines, /* @__PURE__ */ new Set([" ", "-"])) !== hunk.oldLines)
43500
+ return null;
43501
+ if (countLines(hunk.lines, /* @__PURE__ */ new Set([" ", "+"])) !== hunk.newLines)
43502
+ return null;
43503
+ return hunk;
43023
43504
  }
43024
- function isTaskNotificationRecord(text) {
43025
- return taskNotificationRecordPattern.test(text);
43505
+ function parseClaudeNativeFileChange(toolName, value) {
43506
+ if (toolName !== "Edit" && toolName !== "Write" || !isRecord3(value))
43507
+ return null;
43508
+ if (!validNativePath(value.filePath) || !Array.isArray(value.structuredPatch))
43509
+ return null;
43510
+ const hunks = value.structuredPatch.map(validHunk);
43511
+ if (hunks.length === 0 || hunks.some((hunk) => hunk === null))
43512
+ return null;
43513
+ if (toolName === "Write" && value.type !== "create" && value.type !== "update")
43514
+ return null;
43515
+ return {
43516
+ path: value.filePath,
43517
+ kind: toolName === "Write" && value.type === "create" ? "add" : "update",
43518
+ hunks
43519
+ };
43026
43520
  }
43027
- function isControlCommandEnvelope(text) {
43028
- return commandEnvelopePattern.test(text) && controlCommandNamePattern.test(text);
43521
+ function displayPath(nativePath, cwd) {
43522
+ const resolvedCwd = path9.resolve(cwd);
43523
+ const resolvedPath = path9.isAbsolute(nativePath) ? path9.resolve(nativePath) : path9.resolve(cwd, nativePath);
43524
+ const relative = path9.relative(resolvedCwd, resolvedPath);
43525
+ const selected = relative.length > 0 && relative !== ".." && !relative.startsWith(`..${path9.sep}`) ? relative : resolvedPath;
43526
+ const normalized = selected.replaceAll("\\", "/");
43527
+ return validNativePath(normalized) && normalized !== "." ? normalized : null;
43029
43528
  }
43030
- function isNamedCommandEnvelope(text, namePattern) {
43031
- return commandEnvelopePattern.test(text) && namePattern.test(text);
43529
+ function projectClaudeFileChange(value, cwd) {
43530
+ const normalizedPath = displayPath(value.path, cwd);
43531
+ if (!normalizedPath)
43532
+ return null;
43533
+ const body = value.hunks.flatMap((hunk) => [
43534
+ `@@ -${hunk.oldStart},${hunk.oldLines} +${hunk.newStart},${hunk.newLines} @@`,
43535
+ ...hunk.lines
43536
+ ]);
43537
+ const absoluteDisplayPath = path9.posix.isAbsolute(normalizedPath);
43538
+ const oldHeader = value.kind === "add" ? "/dev/null" : absoluteDisplayPath ? normalizedPath : `a/${normalizedPath}`;
43539
+ const newHeader = absoluteDisplayPath ? normalizedPath : `b/${normalizedPath}`;
43540
+ const unifiedDiff = [`--- ${oldHeader}`, `+++ ${newHeader}`, ...body, ""].join("\n");
43541
+ return { path: normalizedPath, kind: value.kind, unifiedDiff };
43032
43542
  }
43033
- function displayedUserText(text) {
43034
- if (isNamedCommandEnvelope(text, initCommandNamePattern))
43035
- return "/init";
43036
- if (isNamedCommandEnvelope(text, recapCommandNamePattern))
43037
- return "/recap";
43038
- return text;
43543
+
43544
+ // dist/native-message.js
43545
+ var ABORTED_TERMINALS = /* @__PURE__ */ new Set(["aborted_streaming", "aborted_tools"]);
43546
+ var AUTHENTICATION_ERRORS = /* @__PURE__ */ new Set(["authentication_failed", "oauth_org_not_allowed"]);
43547
+ var CLAUDE_SUBAGENT_TOOLS = /* @__PURE__ */ new Set(["Agent", "Task", "SendMessage"]);
43548
+ var BACKGROUND_OUTPUT_FILE_PATTERN = /Output is being written to: (.+?\.output)\./u;
43549
+ var SUBAGENT_DESCRIPTION_LIMIT = 500;
43550
+ var SUBAGENT_SUMMARY_LIMIT = 2e3;
43551
+ function isRecord4(value) {
43552
+ return typeof value === "object" && value !== null && !Array.isArray(value);
43039
43553
  }
43040
- function localCommandStdoutText(text) {
43041
- const match = localCommandStdoutPattern.exec(text);
43042
- if (!match)
43554
+ function nativeUuid(message) {
43555
+ return typeof message.uuid === "string" && message.uuid.length > 0 ? message.uuid : null;
43556
+ }
43557
+ function parentToolUseId(message) {
43558
+ return typeof message.parent_tool_use_id === "string" && message.parent_tool_use_id.length > 0 ? message.parent_tool_use_id : null;
43559
+ }
43560
+ function assistantNativeMessageId(message) {
43561
+ if (!isRecord4(message.message))
43043
43562
  return null;
43044
- return match[1] ?? "";
43563
+ return typeof message.message.id === "string" && message.message.id.length > 0 ? message.message.id : null;
43045
43564
  }
43046
- function isTaskNotificationOrigin(value) {
43047
- return isRecord3(value.origin) && value.origin.kind === "task-notification";
43565
+ function assistantContent(message) {
43566
+ if (message.type !== "assistant" || !isRecord4(message.message))
43567
+ return null;
43568
+ return Array.isArray(message.message.content) ? message.message.content : null;
43048
43569
  }
43049
- function visibleUserTextParts(message) {
43050
- if (message.type !== "user" || message.syntheticUser)
43051
- return [];
43052
- const parts = textParts(message.message.content);
43053
- if (parts.some(isControlCommandEnvelope))
43054
- return [];
43055
- return parts.filter((part) => !isLocalCommandRecord(part) && !isTaskNotificationRecord(part));
43570
+ function assistantText(message) {
43571
+ const content = assistantContent(message);
43572
+ if (!content)
43573
+ return null;
43574
+ return content.flatMap((block) => isRecord4(block) && block.type === "text" && typeof block.text === "string" ? [block.text] : []).join("");
43056
43575
  }
43057
- function isInterruptionRecord(value, promptId) {
43058
- if (value.type !== "user" || promptId === null || value.promptId !== promptId || value.promptSource !== void 0 || !isRecord3(value.message))
43059
- return false;
43060
- const content = value.message.content;
43061
- if (!Array.isArray(content) || content.length !== 1)
43062
- return false;
43063
- const part = content[0];
43064
- return isRecord3(part) && part.type === "text" && (part.text === "[Request interrupted by user]" || part.text === "[Request interrupted by user for tool use]");
43576
+ function assistantError(message) {
43577
+ return isRecord4(message) && message.type === "assistant" && typeof message.error === "string" ? message.error : null;
43065
43578
  }
43066
- function conversationMessages(values, sessionId) {
43067
- const messages = [];
43068
- const ids = /* @__PURE__ */ new Set();
43069
- let promptId = null;
43070
- for (const value of values) {
43071
- if (!isRecord3(value))
43072
- throw new Error("Claude history contains a malformed message");
43073
- if (value.type === "system")
43074
- continue;
43075
- if (value.type !== "user" && value.type !== "assistant" || typeof value.uuid !== "string" || value.uuid.length === 0 || value.session_id !== sessionId || !isRecord3(value.message) || value.message.role !== value.type) {
43076
- throw new Error("Claude history contains an invalid message identity");
43077
- }
43078
- if (ids.has(value.uuid))
43079
- throw new Error("Claude history contains duplicate message IDs");
43080
- ids.add(value.uuid);
43081
- const interrupted = isInterruptionRecord(value, promptId);
43082
- const message = {
43083
- type: value.type,
43084
- uuid: value.uuid,
43085
- message: value.message,
43086
- interrupted,
43087
- syntheticUser: value.type === "user" && (interrupted || value.isSynthetic === true || value.isMeta === true || isTaskNotificationOrigin(value) || value.toolUseResult !== void 0 && value.toolUseResult !== null)
43088
- };
43089
- messages.push(message);
43090
- if (isHumanUser(message)) {
43091
- promptId = typeof value.promptId === "string" && value.promptId.length > 0 ? value.promptId : null;
43579
+ function boundedString(value, limit) {
43580
+ if (typeof value !== "string")
43581
+ return void 0;
43582
+ const trimmed = value.trim();
43583
+ if (trimmed.length === 0)
43584
+ return void 0;
43585
+ return trimmed.slice(0, limit);
43586
+ }
43587
+ function subagentDescription(argumentsValue, toolName) {
43588
+ if (!isRecord4(argumentsValue))
43589
+ return `${toolName} delegation`;
43590
+ return boundedString(argumentsValue.description, SUBAGENT_DESCRIPTION_LIMIT) ?? boundedString(argumentsValue.summary, SUBAGENT_DESCRIPTION_LIMIT) ?? boundedString(argumentsValue.name, SUBAGENT_DESCRIPTION_LIMIT) ?? `${toolName} delegation`;
43591
+ }
43592
+ function subagentPrompt(argumentsValue) {
43593
+ if (!isRecord4(argumentsValue))
43594
+ return void 0;
43595
+ return boundedString(argumentsValue.prompt ?? argumentsValue.message, SUBAGENT_SUMMARY_LIMIT);
43596
+ }
43597
+ function subagentRole(argumentsValue) {
43598
+ if (!isRecord4(argumentsValue))
43599
+ return void 0;
43600
+ return boundedString(argumentsValue.subagent_type ?? argumentsValue.agent_type, SUBAGENT_DESCRIPTION_LIMIT);
43601
+ }
43602
+ function subagentBackground(argumentsValue) {
43603
+ return isRecord4(argumentsValue) && argumentsValue.run_in_background === true;
43604
+ }
43605
+ function targetedSubagentId(argumentsValue) {
43606
+ if (!isRecord4(argumentsValue))
43607
+ return void 0;
43608
+ return boundedString(argumentsValue.to ?? argumentsValue.recipient ?? argumentsValue.agentId, SUBAGENT_DESCRIPTION_LIMIT);
43609
+ }
43610
+ function includesAuthenticationFailure(errors) {
43611
+ return errors.some((error52) => AUTHENTICATION_ERRORS.has(error52));
43612
+ }
43613
+ function failure(kind) {
43614
+ return { status: "failed", kind };
43615
+ }
43616
+ function safeNonNegativeInteger(value) {
43617
+ return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
43618
+ }
43619
+ function finiteNonNegativeNumber(value) {
43620
+ return typeof value === "number" && Number.isFinite(value) && value >= 0;
43621
+ }
43622
+ function parseResultModelUsage(value) {
43623
+ if (!isRecord4(value))
43624
+ return void 0;
43625
+ const usage = [];
43626
+ for (const entry of Object.values(value)) {
43627
+ if (!isRecord4(entry) || !safeNonNegativeInteger(entry.inputTokens) || !safeNonNegativeInteger(entry.outputTokens)) {
43628
+ return void 0;
43092
43629
  }
43630
+ usage.push({ inputTokens: entry.inputTokens, outputTokens: entry.outputTokens });
43093
43631
  }
43094
- return messages;
43632
+ return usage;
43095
43633
  }
43096
- function isHumanUser(message) {
43097
- return visibleUserTextParts(message).length > 0;
43634
+ function parseLastRequestUsage(value, attribution = {}) {
43635
+ if (!isRecord4(value))
43636
+ return void 0;
43637
+ const inputTokens = value.input_tokens;
43638
+ const outputTokens = value.output_tokens;
43639
+ const cacheCreationInputTokens = value.cache_creation_input_tokens;
43640
+ const cacheReadInputTokens = value.cache_read_input_tokens;
43641
+ if (!safeNonNegativeInteger(inputTokens) || !safeNonNegativeInteger(outputTokens) || !safeNonNegativeInteger(cacheCreationInputTokens) || !safeNonNegativeInteger(cacheReadInputTokens)) {
43642
+ return void 0;
43643
+ }
43644
+ const requestId = boundedString(attribution.requestId, 500);
43645
+ const model = boundedString(attribution.model, 500);
43646
+ const provider = boundedString(attribution.provider, 100);
43647
+ return {
43648
+ ...requestId ? { requestId } : {},
43649
+ ...model ? { model } : {},
43650
+ ...provider ? { provider } : {},
43651
+ inputTokens,
43652
+ outputTokens,
43653
+ cacheCreationInputTokens,
43654
+ cacheReadInputTokens
43655
+ };
43098
43656
  }
43099
- function turnOutcome(messages) {
43100
- if (messages.some(({ interrupted }) => interrupted))
43101
- return { status: "cancelled", reason: "Cancelled by user" };
43102
- const assistants = messages.filter(({ type }) => type === "assistant");
43103
- const failed = assistants.some(({ message }) => typeof message.error === "string");
43104
- if (failed) {
43105
- return {
43106
- status: "failed",
43107
- error: {
43108
- code: "nativeFailure",
43109
- message: "Claude Assistant failed",
43110
- retryable: false
43111
- }
43112
- };
43657
+ function assistantRequestUsage(message, provider) {
43658
+ if (!isRecord4(message.message))
43659
+ return void 0;
43660
+ return parseLastRequestUsage(message.message.usage, {
43661
+ requestId: message.message.id ?? message.request_id,
43662
+ model: message.message.model,
43663
+ provider: message.provider ?? message.message.provider ?? provider
43664
+ });
43665
+ }
43666
+ function parseResultUsageEvent(message) {
43667
+ const totalCostUsd = finiteNonNegativeNumber(message.total_cost_usd) ? message.total_cost_usd : void 0;
43668
+ const modelUsage = parseResultModelUsage(message.modelUsage);
43669
+ const lastRequestUsage = parseLastRequestUsage(message.usage);
43670
+ if (totalCostUsd === void 0 && modelUsage === void 0 && lastRequestUsage === void 0) {
43671
+ return null;
43113
43672
  }
43114
- const final = assistants.at(-1);
43115
- if (!final)
43116
- return { status: "unknown", reason: "Claude history has no Assistant terminal" };
43117
43673
  return {
43118
- status: "unknown",
43119
- reason: "Claude history does not include complete Result terminal evidence"
43674
+ type: "usage.result",
43675
+ ...totalCostUsd !== void 0 ? { totalCostUsd } : {},
43676
+ ...modelUsage !== void 0 ? { modelUsage } : {},
43677
+ ...lastRequestUsage ? { lastRequestUsage } : {}
43120
43678
  };
43121
43679
  }
43122
- function itemOutcome(outcome) {
43123
- if (outcome.status === "failed")
43124
- return { status: "failed", error: outcome.error };
43125
- if (outcome.status === "cancelled") {
43126
- return {
43127
- status: "cancelled",
43128
- ...outcome.reason ? { reason: outcome.reason } : {}
43129
- };
43680
+ function parsePlanLimitWindow(value) {
43681
+ if (!isRecord4(value))
43682
+ return void 0;
43683
+ const utilization = value.utilization;
43684
+ if (typeof utilization !== "number" || !Number.isFinite(utilization) || utilization < 0) {
43685
+ return void 0;
43130
43686
  }
43131
- return { status: "succeeded" };
43687
+ const utilizationPercent = Math.min(100, Math.max(0, Math.round(utilization * 1e4) / 100));
43688
+ const resetsAt = value.resetsAt;
43689
+ const resetsAtUnix = safeNonNegativeInteger(resetsAt) ? resetsAt : void 0;
43690
+ return { utilizationPercent, ...resetsAtUnix !== void 0 ? { resetsAtUnix } : {} };
43132
43691
  }
43133
- function mapClaudeSnapshot(values, sessionId) {
43134
- const messages = conversationMessages(values, sessionId);
43135
- const turns = [];
43136
- for (let index = 0; index < messages.length; ) {
43137
- const user = messages[index];
43138
- if (!user || !isHumanUser(user)) {
43139
- index += 1;
43140
- continue;
43141
- }
43142
- let end = index + 1;
43143
- while (end < messages.length && !isHumanUser(messages[end]))
43144
- end += 1;
43145
- const turnMessages = messages.slice(index, end);
43146
- const outcome = turnOutcome(turnMessages);
43147
- const results = toolResultBlocks(turnMessages);
43148
- const checkpointMessage = turnMessages.findLast(({ type, interrupted }) => type === "assistant" || interrupted);
43149
- let agentMessageOrdinal = 0;
43150
- let reasoningOrdinal = 0;
43151
- turns.push({
43152
- nativeTurnRef: nativeTurnRefSchema.parse({
43153
- harnessId: claudeCodeHarnessId,
43154
- nativeSessionId: sessionId,
43155
- nativeTurnKey: user.uuid,
43156
- formatVersion: 1
43157
- }),
43158
- ...checkpointMessage ? {
43159
- checkpoint: nativeCheckpointRefSchema.parse({
43160
- harnessId: claudeCodeHarnessId,
43161
- nativeSessionId: sessionId,
43162
- checkpointId: checkpointMessage.uuid,
43163
- formatVersion: 1
43164
- })
43165
- } : {},
43166
- input: visibleUserTextParts(user).map((text) => ({
43167
- type: "text",
43168
- text: displayedUserText(text)
43169
- })),
43170
- items: turnMessages.flatMap((message) => {
43171
- if (message.type === "user") {
43172
- const recapOutput = visibleUserTextParts(user).some((text2) => isNamedCommandEnvelope(text2, recapCommandNamePattern)) ? textParts(message.message.content).map(localCommandStdoutText).find((text2) => text2 !== null && text2.length > 0) : void 0;
43173
- if (!recapOutput)
43174
- return [];
43175
- return [
43176
- {
43177
- item: {
43178
- type: "agentMessage",
43179
- itemId: claudeTranscriptItemId(user.uuid, "agentMessage", agentMessageOrdinal += 1),
43180
- text: recapOutput
43181
- },
43182
- outcome: itemOutcome(outcome)
43183
- }
43184
- ];
43185
- }
43186
- if (message.type !== "assistant")
43187
- return [];
43188
- const content = message.message.content;
43189
- const text = textParts(content).join("");
43190
- const reasoning = thinkingParts(content).join("");
43191
- if (!Array.isArray(content)) {
43192
- return text.length > 0 ? [
43193
- {
43194
- item: {
43195
- type: "agentMessage",
43196
- itemId: claudeTranscriptItemId(user.uuid, "agentMessage", agentMessageOrdinal += 1),
43197
- text
43198
- },
43199
- outcome: itemOutcome(outcome)
43200
- }
43201
- ] : [];
43202
- }
43203
- const items = [];
43204
- let projectedReasoning = false;
43205
- let projectedText = false;
43206
- for (const [blockIndex, block] of content.entries()) {
43207
- if (!isRecord3(block))
43208
- continue;
43209
- if (block.type === "thinking" && !projectedReasoning && reasoning.length > 0) {
43210
- items.push({
43211
- item: {
43212
- type: "reasoning",
43213
- itemId: claudeTranscriptItemId(user.uuid, "reasoning", reasoningOrdinal += 1),
43214
- text: reasoning
43215
- },
43216
- outcome: itemOutcome(outcome)
43217
- });
43218
- projectedReasoning = true;
43219
- continue;
43220
- }
43221
- if (block.type === "text" && !projectedText && text.length > 0) {
43222
- items.push({
43692
+ function parseClaudePlanLimitEvent(message) {
43693
+ if (!isRecord4(message) || message.type !== "rate_limit_event")
43694
+ return null;
43695
+ const info = message.rate_limit_info;
43696
+ if (!isRecord4(info))
43697
+ return null;
43698
+ const windows = isRecord4(info.unifiedWindows) ? info.unifiedWindows : void 0;
43699
+ let fiveHour = parsePlanLimitWindow(windows?.five_hour);
43700
+ let sevenDay = parsePlanLimitWindow(windows?.seven_day);
43701
+ if (!fiveHour && !sevenDay) {
43702
+ const flatWindow = parsePlanLimitWindow(info);
43703
+ if (flatWindow && info.rateLimitType === "five_hour")
43704
+ fiveHour = flatWindow;
43705
+ else if (flatWindow && info.rateLimitType === "seven_day")
43706
+ sevenDay = flatWindow;
43707
+ }
43708
+ if (!fiveHour && !sevenDay)
43709
+ return null;
43710
+ return {
43711
+ ...fiveHour ? { fiveHour } : {},
43712
+ ...sevenDay ? { sevenDay } : {}
43713
+ };
43714
+ }
43715
+ function nativeSubagentId(nativeResult, outputText) {
43716
+ if (isRecord4(nativeResult)) {
43717
+ const structured = boundedString(nativeResult.agentId ?? nativeResult.agent_id ?? nativeResult.task_id, SUBAGENT_DESCRIPTION_LIMIT);
43718
+ if (structured)
43719
+ return structured;
43720
+ }
43721
+ return boundedString(/agentId:\s*([A-Za-z0-9_-]+)/u.exec(outputText ?? "")?.[1], SUBAGENT_DESCRIPTION_LIMIT);
43722
+ }
43723
+ function subagentContinuesInBackground(nativeResult, outputText) {
43724
+ if (isRecord4(nativeResult)) {
43725
+ if (nativeResult.isAsync === true || nativeResult.is_async === true)
43726
+ return true;
43727
+ if (nativeResult.status === "async_launched")
43728
+ return true;
43729
+ }
43730
+ return outputText?.includes("The agent is working in the background.") ?? false;
43731
+ }
43732
+ function resultText(content, nativeResult) {
43733
+ let text = "";
43734
+ if (typeof content === "string") {
43735
+ text = content;
43736
+ } else if (Array.isArray(content)) {
43737
+ text = content.flatMap((block) => isRecord4(block) && block.type === "text" && typeof block.text === "string" ? [block.text] : []).join("");
43738
+ }
43739
+ if (text.length > 0)
43740
+ return text;
43741
+ if (!isRecord4(nativeResult))
43742
+ return void 0;
43743
+ const stdout = typeof nativeResult.stdout === "string" ? nativeResult.stdout : "";
43744
+ const stderr = typeof nativeResult.stderr === "string" ? nativeResult.stderr : "";
43745
+ const combined = stdout + stderr;
43746
+ return combined.length > 0 ? combined : void 0;
43747
+ }
43748
+ function userMessageText(content) {
43749
+ if (typeof content === "string")
43750
+ return content;
43751
+ if (!Array.isArray(content))
43752
+ return null;
43753
+ const text = content.flatMap((block) => isRecord4(block) && block.type === "text" && typeof block.text === "string" ? [block.text] : []).join("");
43754
+ return text.length > 0 ? text : null;
43755
+ }
43756
+ function parseClaudeTaskNotification(message) {
43757
+ if (!isRecord4(message) || message.type !== "user" || !isRecord4(message.message))
43758
+ return null;
43759
+ if (isRecord4(message.origin) && message.origin.kind !== "task-notification")
43760
+ return null;
43761
+ const content = userMessageText(message.message.content);
43762
+ if (!content || !content.includes("<task-notification>"))
43763
+ return null;
43764
+ const taskId = content.match(/<task-id>([^<]+)<\/task-id>/u)?.[1]?.trim();
43765
+ if (!taskId)
43766
+ return null;
43767
+ const xmlStatus = content.match(/<status>([^<]+)<\/status>/u)?.[1]?.trim();
43768
+ const status = taskStatus(xmlStatus ?? "completed");
43769
+ if (status !== "completed" && status !== "failed" && status !== "interrupted")
43770
+ return null;
43771
+ const summary = content.match(/<summary>([\s\S]*?)<\/summary>/u)?.[1]?.trim();
43772
+ const callId = content.match(/<tool-use-id>([^<]+)<\/tool-use-id>/u)?.[1]?.trim();
43773
+ const outputFile = content.match(/<output-file>([^<]+)<\/output-file>/u)?.[1]?.trim();
43774
+ return {
43775
+ type: "subagent.settled",
43776
+ nativeSubagentId: taskId,
43777
+ status,
43778
+ ...callId ? { callId } : {},
43779
+ ...summary ? { resultSummary: summary.slice(0, SUBAGENT_SUMMARY_LIMIT) } : {},
43780
+ ...outputFile ? { outputFile } : {}
43781
+ };
43782
+ }
43783
+ function taskStatus(value) {
43784
+ switch (value) {
43785
+ case "pending":
43786
+ return "pending";
43787
+ case "running":
43788
+ return "running";
43789
+ case "completed":
43790
+ return "completed";
43791
+ case "failed":
43792
+ return "failed";
43793
+ case "killed":
43794
+ case "stopped":
43795
+ return "interrupted";
43796
+ default:
43797
+ return null;
43798
+ }
43799
+ }
43800
+ var ClaudeNativeTurnAccumulator = class {
43801
+ #provider;
43802
+ #activeRootStreamMessageId = null;
43803
+ #assistantErrors = [];
43804
+ #cancelRequested = false;
43805
+ #compactionState = "idle";
43806
+ #completed = false;
43807
+ #completedToolIds = /* @__PURE__ */ new Set();
43808
+ #messageOrdinal = 0;
43809
+ #messages = /* @__PURE__ */ new Map();
43810
+ #protocolConflict = false;
43811
+ #textConflict = false;
43812
+ #tools = /* @__PURE__ */ new Map();
43813
+ constructor(options = {}) {
43814
+ this.#provider = options.provider;
43815
+ }
43816
+ requestCancel() {
43817
+ this.#cancelRequested = true;
43818
+ }
43819
+ consume(message) {
43820
+ if (this.#completed || !isRecord4(message))
43821
+ return { events: [] };
43822
+ const events = [];
43823
+ this.#consumeSegmentLevel(message, events);
43824
+ this.#consumeTaskLifecycle(message, events);
43825
+ const parentCallId = parentToolUseId(message);
43826
+ const nested = parentCallId !== null;
43827
+ if (parentCallId && this.#tools.get(parentCallId)?.subagent === true && (message.type === "assistant" || message.type === "user")) {
43828
+ events.push({ type: "subagent.transcript.changed", callId: parentCallId });
43829
+ }
43830
+ if (!nested) {
43831
+ this.#consumeCompaction(message, events);
43832
+ this.#consumeLocalCommandOutput(message, events);
43833
+ }
43834
+ if (message.type === "stream_event" && isRecord4(message.event)) {
43835
+ if (!nested)
43836
+ this.#consumeStreamEvent(message, events);
43837
+ } else if (message.type === "tool_progress") {
43838
+ this.#consumeToolProgress(message, events);
43839
+ }
43840
+ if (!nested) {
43841
+ const error52 = assistantError(message);
43842
+ if (error52 !== null)
43843
+ this.#assistantErrors.push(error52);
43844
+ }
43845
+ if (message.type === "assistant") {
43846
+ if (!nested)
43847
+ this.#consumeAssistantMessage(message, events);
43848
+ } else if (message.type === "user") {
43849
+ this.#consumeTaskNotification(message, events);
43850
+ this.#consumeToolResults(message, events, nested);
43851
+ }
43852
+ if (message.type !== "result")
43853
+ return { events };
43854
+ const usageEvent = parseResultUsageEvent(message);
43855
+ if (usageEvent)
43856
+ events.push(usageEvent);
43857
+ this.#completed = true;
43858
+ const terminalReason = typeof message.terminal_reason === "string" ? message.terminal_reason : "missing";
43859
+ const nativeSuccess = message.subtype === "success" && message.is_error === false && (terminalReason === "completed" || terminalReason === "missing") && this.#assistantErrors.length === 0;
43860
+ if (nativeSuccess && this.#tools.size > 0)
43861
+ this.#protocolConflict = true;
43862
+ let terminal;
43863
+ if (this.#protocolConflict) {
43864
+ terminal = failure("protocol");
43865
+ } else if (this.#textConflict) {
43866
+ terminal = failure("textConflict");
43867
+ } else if (includesAuthenticationFailure(this.#assistantErrors)) {
43868
+ terminal = failure("authentication");
43869
+ } else if (this.#cancelRequested && ABORTED_TERMINALS.has(terminalReason)) {
43870
+ terminal = { status: "cancelled", reason: terminalReason };
43871
+ } else if (this.#cancelRequested) {
43872
+ terminal = failure("cancellationUnproven");
43873
+ } else if (nativeSuccess) {
43874
+ terminal = { status: "succeeded" };
43875
+ } else {
43876
+ terminal = failure("native");
43877
+ }
43878
+ return { events, terminal };
43879
+ }
43880
+ #consumeCompaction(message, events) {
43881
+ if (message.type !== "system")
43882
+ return;
43883
+ if (message.subtype === "status") {
43884
+ if (message.status === "compacting" && this.#compactionState !== "active") {
43885
+ this.#compactionState = "active";
43886
+ events.push({ type: "compaction.started" });
43887
+ }
43888
+ if (message.compact_result === "success" || message.compact_result === "failed") {
43889
+ if (this.#compactionState === "settled")
43890
+ return;
43891
+ if (this.#compactionState === "idle")
43892
+ events.push({ type: "compaction.started" });
43893
+ this.#compactionState = "settled";
43894
+ events.push({
43895
+ type: "compaction.completed",
43896
+ outcome: message.compact_result === "success" ? "succeeded" : "failed"
43897
+ });
43898
+ }
43899
+ return;
43900
+ }
43901
+ if (message.subtype !== "compact_boundary" || this.#compactionState === "settled")
43902
+ return;
43903
+ if (this.#compactionState === "idle")
43904
+ events.push({ type: "compaction.started" });
43905
+ this.#compactionState = "settled";
43906
+ events.push({ type: "compaction.completed", outcome: "succeeded" });
43907
+ }
43908
+ #consumeLocalCommandOutput(message, events) {
43909
+ if (message.type !== "system" || message.subtype !== "local_command_output")
43910
+ return;
43911
+ if (typeof message.content !== "string" || message.content.length === 0)
43912
+ return;
43913
+ const checkpointId = nativeUuid(message);
43914
+ const messageId = checkpointId ?? this.#nextMessageId();
43915
+ const state = this.#messageState(messageId);
43916
+ if (state.completed)
43917
+ return;
43918
+ state.text += message.content;
43919
+ events.push({ type: "text.delta", messageId, delta: message.content });
43920
+ state.completed = true;
43921
+ events.push({
43922
+ type: "message.completed",
43923
+ messageId,
43924
+ ...checkpointId ? { checkpointId } : {}
43925
+ });
43926
+ }
43927
+ /**
43928
+ * Claude opens one native Segment per Root execution and reports its live
43929
+ * background tasks as a level whose membership replaces the previous set.
43930
+ */
43931
+ #consumeSegmentLevel(message, events) {
43932
+ if (message.type !== "system")
43933
+ return;
43934
+ if (message.subtype === "init") {
43935
+ events.push({ type: "segment.started" });
43936
+ return;
43937
+ }
43938
+ if (message.subtype !== "background_tasks_changed" || !Array.isArray(message.tasks))
43939
+ return;
43940
+ const nativeSubagentIds = message.tasks.flatMap((task) => {
43941
+ if (!isRecord4(task))
43942
+ return [];
43943
+ const taskId = boundedString(task.task_id, SUBAGENT_DESCRIPTION_LIMIT);
43944
+ return taskId ? [taskId] : [];
43945
+ });
43946
+ events.push({ type: "subagents.live", nativeSubagentIds });
43947
+ }
43948
+ #consumeTaskLifecycle(message, events) {
43949
+ if (message.type !== "system")
43950
+ return;
43951
+ if (message.subtype === "task_notification") {
43952
+ const agentId = boundedString(message.task_id, SUBAGENT_DESCRIPTION_LIMIT);
43953
+ const status = taskStatus(message.status);
43954
+ if (!agentId || status !== "completed" && status !== "failed" && status !== "interrupted") {
43955
+ return;
43956
+ }
43957
+ const resultSummary = boundedString(message.summary, SUBAGENT_SUMMARY_LIMIT);
43958
+ const callId2 = boundedString(message.tool_use_id, SUBAGENT_DESCRIPTION_LIMIT);
43959
+ const outputFile = typeof message.output_file === "string" && message.output_file.length > 0 ? message.output_file : void 0;
43960
+ events.push({
43961
+ type: "subagent.settled",
43962
+ nativeSubagentId: agentId,
43963
+ status,
43964
+ ...callId2 ? { callId: callId2 } : {},
43965
+ ...resultSummary ? { resultSummary } : {},
43966
+ ...outputFile ? { outputFile } : {}
43967
+ });
43968
+ return;
43969
+ }
43970
+ const callId = typeof message.tool_use_id === "string" ? message.tool_use_id : null;
43971
+ if (!callId || !this.#tools.get(callId)?.subagent)
43972
+ return;
43973
+ if (message.subtype === "task_started") {
43974
+ const description = boundedString(message.description, SUBAGENT_DESCRIPTION_LIMIT);
43975
+ const role = boundedString(message.subagent_type, SUBAGENT_DESCRIPTION_LIMIT);
43976
+ const agentId = boundedString(message.task_id, SUBAGENT_DESCRIPTION_LIMIT);
43977
+ events.push({
43978
+ type: "subagent.updated",
43979
+ callId,
43980
+ status: "running",
43981
+ ...description ? { description } : {},
43982
+ ...role ? { role } : {},
43983
+ ...agentId ? { nativeSubagentId: agentId } : {}
43984
+ });
43985
+ return;
43986
+ }
43987
+ if (message.subtype === "task_progress") {
43988
+ const description = boundedString(message.description, SUBAGENT_DESCRIPTION_LIMIT);
43989
+ const role = boundedString(message.subagent_type, SUBAGENT_DESCRIPTION_LIMIT);
43990
+ const resultSummary = boundedString(message.summary, SUBAGENT_SUMMARY_LIMIT);
43991
+ const agentId = boundedString(message.task_id, SUBAGENT_DESCRIPTION_LIMIT);
43992
+ events.push({
43993
+ type: "subagent.updated",
43994
+ callId,
43995
+ status: "running",
43996
+ ...description ? { description } : {},
43997
+ ...role ? { role } : {},
43998
+ ...agentId ? { nativeSubagentId: agentId } : {},
43999
+ ...resultSummary ? { resultSummary } : {}
44000
+ });
44001
+ return;
44002
+ }
44003
+ if (message.subtype === "task_updated" && isRecord4(message.patch)) {
44004
+ const status = taskStatus(message.patch.status);
44005
+ if (!status)
44006
+ return;
44007
+ const description = boundedString(message.patch.description, SUBAGENT_DESCRIPTION_LIMIT);
44008
+ const resultSummary = boundedString(message.patch.error, SUBAGENT_SUMMARY_LIMIT);
44009
+ const agentId = boundedString(message.task_id, SUBAGENT_DESCRIPTION_LIMIT);
44010
+ events.push({
44011
+ type: "subagent.updated",
44012
+ callId,
44013
+ status,
44014
+ ...description ? { description } : {},
44015
+ ...agentId ? { nativeSubagentId: agentId } : {},
44016
+ ...resultSummary ? { resultSummary } : {}
44017
+ });
44018
+ }
44019
+ }
44020
+ #consumeStreamEvent(message, events) {
44021
+ const event = message.event;
44022
+ if (!isRecord4(event))
44023
+ return;
44024
+ if (event.type === "message_start" && isRecord4(event.message) && typeof event.message.id === "string" && event.message.id.length > 0) {
44025
+ this.#activeRootStreamMessageId = event.message.id;
44026
+ this.#messageState(event.message.id);
44027
+ return;
44028
+ }
44029
+ if (event.type !== "content_block_delta" || !isRecord4(event.delta))
44030
+ return;
44031
+ const messageId = this.#activeRootStreamMessageId ?? nativeUuid(message) ?? this.#nextMessageId();
44032
+ if (!this.#activeRootStreamMessageId)
44033
+ this.#activeRootStreamMessageId = messageId;
44034
+ const state = this.#messageState(messageId);
44035
+ if (state.completed) {
44036
+ if (event.delta.type === "text_delta")
44037
+ this.#textConflict = true;
44038
+ return;
44039
+ }
44040
+ if (event.delta.type === "text_delta" && typeof event.delta.text === "string") {
44041
+ if (event.delta.text.length === 0)
44042
+ return;
44043
+ state.text += event.delta.text;
44044
+ events.push({ type: "text.delta", messageId, delta: event.delta.text });
44045
+ return;
44046
+ }
44047
+ if (event.delta.type === "thinking_delta" && typeof event.delta.thinking === "string") {
44048
+ if (event.delta.thinking.length === 0)
44049
+ return;
44050
+ state.reasoning += event.delta.thinking;
44051
+ events.push({ type: "reasoning.delta", messageId, delta: event.delta.thinking });
44052
+ }
44053
+ }
44054
+ #consumeAssistantMessage(message, events) {
44055
+ const checkpointId = nativeUuid(message);
44056
+ const nativeMessageId = assistantNativeMessageId(message);
44057
+ const messageId = this.#activeRootStreamMessageId ?? nativeMessageId ?? checkpointId ?? this.#nextMessageId();
44058
+ const state = this.#messageState(messageId);
44059
+ if (state.completed) {
44060
+ this.#consumeToolUseBlocks(message, events, true);
44061
+ const usage = assistantRequestUsage(message, this.#provider);
44062
+ if (usage && !state.usagePublished) {
44063
+ state.usagePublished = true;
44064
+ events.push({
44065
+ type: "message.completed",
44066
+ messageId,
44067
+ ...checkpointId ? { checkpointId } : {},
44068
+ lastRequestUsage: usage
44069
+ });
44070
+ }
44071
+ return;
44072
+ }
44073
+ if (state.reasoning.length > 0) {
44074
+ events.push({ type: "reasoning.completed", messageId });
44075
+ }
44076
+ const completeText = assistantText(message);
44077
+ if (completeText !== null && completeText.length > 0) {
44078
+ if (completeText.startsWith(state.text)) {
44079
+ const suffix = completeText.slice(state.text.length);
44080
+ if (suffix.length > 0) {
44081
+ state.text += suffix;
44082
+ events.push({ type: "text.delta", messageId, delta: suffix });
44083
+ }
44084
+ } else if (completeText !== state.text) {
44085
+ this.#textConflict = true;
44086
+ }
44087
+ }
44088
+ this.#consumeToolUseBlocks(message, events, false);
44089
+ if (!this.#protocolConflict && !this.#textConflict) {
44090
+ const usage = assistantRequestUsage(message, this.#provider);
44091
+ state.usagePublished = usage !== void 0;
44092
+ events.push({
44093
+ type: "message.completed",
44094
+ messageId,
44095
+ ...checkpointId ? { checkpointId } : {},
44096
+ ...usage ? { lastRequestUsage: usage } : {}
44097
+ });
44098
+ }
44099
+ state.completed = true;
44100
+ if (this.#activeRootStreamMessageId === messageId)
44101
+ this.#activeRootStreamMessageId = null;
44102
+ }
44103
+ #consumeToolUseBlocks(message, events, ignoreKnownIds) {
44104
+ for (const block of assistantContent(message) ?? []) {
44105
+ if (!isRecord4(block) || block.type !== "tool_use")
44106
+ continue;
44107
+ const argumentsResult = jsonValueSchema.safeParse(block.input);
44108
+ if (typeof block.id !== "string" || block.id.length === 0 || typeof block.name !== "string" || block.name.length === 0 || !argumentsResult.success) {
44109
+ this.#protocolConflict = true;
44110
+ continue;
44111
+ }
44112
+ if (this.#tools.has(block.id) || this.#completedToolIds.has(block.id)) {
44113
+ if (!ignoreKnownIds)
44114
+ this.#protocolConflict = true;
44115
+ continue;
44116
+ }
44117
+ const subagent = CLAUDE_SUBAGENT_TOOLS.has(block.name);
44118
+ this.#tools.set(block.id, { name: block.name, subagent });
44119
+ if (subagent) {
44120
+ const prompt = subagentPrompt(argumentsResult.data);
44121
+ const role = subagentRole(argumentsResult.data);
44122
+ const agentId = targetedSubagentId(argumentsResult.data);
44123
+ events.push({
44124
+ type: "subagent.started",
44125
+ callId: block.id,
44126
+ operation: block.name === "SendMessage" ? "send" : "spawn",
44127
+ description: subagentDescription(argumentsResult.data, block.name),
44128
+ ...prompt ? { prompt } : {},
44129
+ ...role ? { role } : {},
44130
+ background: block.name === "SendMessage" || subagentBackground(argumentsResult.data),
44131
+ ...agentId ? { nativeSubagentId: agentId } : {}
44132
+ });
44133
+ } else {
44134
+ events.push({
44135
+ type: "tool.started",
44136
+ callId: block.id,
44137
+ toolName: block.name,
44138
+ arguments: argumentsResult.data
44139
+ });
44140
+ }
44141
+ }
44142
+ }
44143
+ #consumeToolProgress(message, events) {
44144
+ const callId = message.tool_use_id;
44145
+ const elapsedSeconds = message.elapsed_time_seconds;
44146
+ if (typeof callId !== "string" || this.#tools.get(callId)?.subagent !== false || typeof elapsedSeconds !== "number" || !Number.isFinite(elapsedSeconds) || elapsedSeconds < 0) {
44147
+ return;
44148
+ }
44149
+ events.push({ type: "tool.progress", callId, elapsedMs: Math.round(elapsedSeconds * 1e3) });
44150
+ }
44151
+ #consumeTaskNotification(message, events) {
44152
+ const settled = parseClaudeTaskNotification(message);
44153
+ if (settled)
44154
+ events.push(settled);
44155
+ }
44156
+ #consumeToolResults(message, events, ignoreUnknown) {
44157
+ if (!isRecord4(message.message) || !Array.isArray(message.message.content))
44158
+ return;
44159
+ const resultBlocks = message.message.content.filter((block) => isRecord4(block) && block.type === "tool_result");
44160
+ if (resultBlocks.length === 0)
44161
+ return;
44162
+ if (resultBlocks.length > 1 && message.tool_use_result !== void 0) {
44163
+ this.#protocolConflict = true;
44164
+ }
44165
+ for (const block of resultBlocks) {
44166
+ const callId = block.tool_use_id;
44167
+ if (typeof callId !== "string" || callId.length === 0) {
44168
+ this.#protocolConflict = true;
44169
+ continue;
44170
+ }
44171
+ const tool = this.#tools.get(callId);
44172
+ if (!tool || this.#completedToolIds.has(callId)) {
44173
+ if (!ignoreUnknown)
44174
+ this.#protocolConflict = true;
44175
+ continue;
44176
+ }
44177
+ if (block.is_error !== void 0 && typeof block.is_error !== "boolean") {
44178
+ this.#protocolConflict = true;
44179
+ continue;
44180
+ }
44181
+ this.#tools.delete(callId);
44182
+ this.#completedToolIds.add(callId);
44183
+ const isError = block.is_error === true;
44184
+ const nativeResult = resultBlocks.length === 1 ? message.tool_use_result ?? message.toolUseResult : void 0;
44185
+ const outputText = resultText(block.content, nativeResult);
44186
+ const structuredResult = tool.name === "TaskCreate" || tool.name === "TaskUpdate" || tool.name === "TaskList" ? jsonValueSchema.safeParse(nativeResult) : null;
44187
+ if (tool.subagent) {
44188
+ const resultSummary = boundedString(outputText, SUBAGENT_SUMMARY_LIMIT);
44189
+ const agentId = nativeSubagentId(nativeResult, outputText);
44190
+ events.push({
44191
+ type: "subagent.completed",
44192
+ callId,
44193
+ isError,
44194
+ ...subagentContinuesInBackground(nativeResult, outputText) ? { continuesInBackground: true } : {},
44195
+ ...agentId ? { nativeSubagentId: agentId } : {},
44196
+ ...resultSummary ? { resultSummary } : {}
44197
+ });
44198
+ continue;
44199
+ }
44200
+ const fileChange = isError ? null : parseClaudeNativeFileChange(tool.name, nativeResult);
44201
+ const backgroundTaskId = tool.name === "Bash" && !isError && isRecord4(nativeResult) && typeof nativeResult.backgroundTaskId === "string" && nativeResult.backgroundTaskId.length > 0 ? nativeResult.backgroundTaskId : void 0;
44202
+ const outputFile = backgroundTaskId !== void 0 ? BACKGROUND_OUTPUT_FILE_PATTERN.exec(outputText ?? "")?.[1] : void 0;
44203
+ const backgroundOutputFile = typeof outputFile === "string" && outputFile.length > 0 ? outputFile : void 0;
44204
+ events.push({
44205
+ type: "tool.completed",
44206
+ callId,
44207
+ toolName: tool.name,
44208
+ ...outputText ? { outputText } : {},
44209
+ ...structuredResult?.success ? { structuredResult: structuredResult.data } : {},
44210
+ isError,
44211
+ ...fileChange ? { fileChange } : {},
44212
+ ...backgroundTaskId ? { backgroundTaskId } : {},
44213
+ ...backgroundOutputFile ? { backgroundOutputFile } : {}
44214
+ });
44215
+ }
44216
+ }
44217
+ #messageState(messageId) {
44218
+ const existing = this.#messages.get(messageId);
44219
+ if (existing)
44220
+ return existing;
44221
+ const created = { completed: false, reasoning: "", text: "", usagePublished: false };
44222
+ this.#messages.set(messageId, created);
44223
+ return created;
44224
+ }
44225
+ #nextMessageId() {
44226
+ this.#messageOrdinal += 1;
44227
+ return `claude-assistant-${this.#messageOrdinal}`;
44228
+ }
44229
+ };
44230
+
44231
+ // dist/item-identity.js
44232
+ function claudeTranscriptItemId(nativeTurnKey, kind, ordinal) {
44233
+ return hostItemIdSchema.parse(`claude-item-v2-${nativeTurnKey}-${kind}-${ordinal}`);
44234
+ }
44235
+
44236
+ // dist/claude-history.js
44237
+ var claudeCodeHarnessId = harnessIdSchema.parse("claude-code");
44238
+ function isRecord5(value) {
44239
+ return typeof value === "object" && value !== null && !Array.isArray(value);
44240
+ }
44241
+ function textParts(value) {
44242
+ if (typeof value === "string")
44243
+ return value.length > 0 ? [value] : [];
44244
+ if (!Array.isArray(value))
44245
+ return [];
44246
+ return value.flatMap((part) => isRecord5(part) && part.type === "text" && typeof part.text === "string" ? [part.text] : []);
44247
+ }
44248
+ function thinkingParts(value) {
44249
+ if (!Array.isArray(value))
44250
+ return [];
44251
+ return value.flatMap((part) => isRecord5(part) && part.type === "thinking" && typeof part.thinking === "string" ? [part.thinking] : []);
44252
+ }
44253
+ var localCommandRecordPattern = /^\s*<(local-command-(?:stdout|caveat))>[\s\S]*<\/\1>\s*$/u;
44254
+ var taskNotificationRecordPattern = /^\s*<task-notification>[\s\S]*<\/task-notification>\s*$/u;
44255
+ var commandEnvelopePattern = /^\s*(?:<(command-(?:message|name|args))>[\s\S]*?<\/\1>\s*)+$/u;
44256
+ var controlCommandNamePattern = /<command-name>\s*\/(?:model|compact)\s*<\/command-name>/u;
44257
+ var recapCommandNamePattern = /<command-name>\s*\/recap\s*<\/command-name>/u;
44258
+ var initCommandNamePattern = /<command-name>\s*\/init\s*<\/command-name>/u;
44259
+ var localCommandStdoutPattern = /^\s*<local-command-stdout>([\s\S]*)<\/local-command-stdout>\s*$/u;
44260
+ function isLocalCommandRecord(text) {
44261
+ return localCommandRecordPattern.test(text);
44262
+ }
44263
+ function isTaskNotificationRecord(text) {
44264
+ return taskNotificationRecordPattern.test(text);
44265
+ }
44266
+ function isControlCommandEnvelope(text) {
44267
+ return commandEnvelopePattern.test(text) && controlCommandNamePattern.test(text);
44268
+ }
44269
+ function isNamedCommandEnvelope(text, namePattern) {
44270
+ return commandEnvelopePattern.test(text) && namePattern.test(text);
44271
+ }
44272
+ function displayedUserText(text) {
44273
+ if (isNamedCommandEnvelope(text, initCommandNamePattern))
44274
+ return "/init";
44275
+ if (isNamedCommandEnvelope(text, recapCommandNamePattern))
44276
+ return "/recap";
44277
+ return text;
44278
+ }
44279
+ function localCommandStdoutText(text) {
44280
+ const match = localCommandStdoutPattern.exec(text);
44281
+ if (!match)
44282
+ return null;
44283
+ return match[1] ?? "";
44284
+ }
44285
+ function isTaskNotificationOrigin(value) {
44286
+ return isRecord5(value.origin) && value.origin.kind === "task-notification";
44287
+ }
44288
+ function visibleUserTextParts(message) {
44289
+ if (message.type !== "user" || message.syntheticUser)
44290
+ return [];
44291
+ const parts = textParts(message.message.content);
44292
+ if (parts.some(isControlCommandEnvelope))
44293
+ return [];
44294
+ return parts.filter((part) => !isLocalCommandRecord(part) && !isTaskNotificationRecord(part));
44295
+ }
44296
+ function isInterruptionRecord(value, promptId) {
44297
+ if (value.type !== "user" || promptId === null || value.promptId !== promptId || value.promptSource !== void 0 || !isRecord5(value.message))
44298
+ return false;
44299
+ const content = value.message.content;
44300
+ if (!Array.isArray(content) || content.length !== 1)
44301
+ return false;
44302
+ const part = content[0];
44303
+ return isRecord5(part) && part.type === "text" && (part.text === "[Request interrupted by user]" || part.text === "[Request interrupted by user for tool use]");
44304
+ }
44305
+ function conversationMessages(values, sessionId) {
44306
+ const messages = [];
44307
+ const ids = /* @__PURE__ */ new Set();
44308
+ let promptId = null;
44309
+ for (const value of values) {
44310
+ if (!isRecord5(value))
44311
+ throw new Error("Claude history contains a malformed message");
44312
+ if (value.type === "system")
44313
+ continue;
44314
+ if (value.type !== "user" && value.type !== "assistant" || typeof value.uuid !== "string" || value.uuid.length === 0 || value.session_id !== sessionId || !isRecord5(value.message) || value.message.role !== value.type) {
44315
+ throw new Error("Claude history contains an invalid message identity");
44316
+ }
44317
+ if (ids.has(value.uuid))
44318
+ throw new Error("Claude history contains duplicate message IDs");
44319
+ ids.add(value.uuid);
44320
+ const interrupted = isInterruptionRecord(value, promptId);
44321
+ const message = {
44322
+ type: value.type,
44323
+ uuid: value.uuid,
44324
+ message: value.message,
44325
+ nested: typeof value.parent_tool_use_id === "string" && value.parent_tool_use_id.length > 0,
44326
+ interrupted,
44327
+ syntheticUser: value.type === "user" && (interrupted || value.isSynthetic === true || value.isMeta === true || isTaskNotificationOrigin(value) || value.toolUseResult !== void 0 && value.toolUseResult !== null)
44328
+ };
44329
+ messages.push(message);
44330
+ if (isHumanUser(message)) {
44331
+ promptId = typeof value.promptId === "string" && value.promptId.length > 0 ? value.promptId : null;
44332
+ }
44333
+ }
44334
+ return messages;
44335
+ }
44336
+ function isHumanUser(message) {
44337
+ return visibleUserTextParts(message).length > 0;
44338
+ }
44339
+ function turnOutcome(messages) {
44340
+ if (messages.some(({ interrupted }) => interrupted))
44341
+ return { status: "cancelled", reason: "Cancelled by user" };
44342
+ const assistants = messages.filter(({ type }) => type === "assistant");
44343
+ const failed = assistants.some(({ message }) => typeof message.error === "string");
44344
+ if (failed) {
44345
+ return {
44346
+ status: "failed",
44347
+ error: {
44348
+ code: "nativeFailure",
44349
+ message: "Claude Assistant failed",
44350
+ retryable: false
44351
+ }
44352
+ };
44353
+ }
44354
+ const final = assistants.at(-1);
44355
+ if (!final)
44356
+ return { status: "unknown", reason: "Claude history has no Assistant terminal" };
44357
+ return {
44358
+ status: "unknown",
44359
+ reason: "Claude history does not include complete Result terminal evidence"
44360
+ };
44361
+ }
44362
+ function itemOutcome(outcome) {
44363
+ if (outcome.status === "failed")
44364
+ return { status: "failed", error: outcome.error };
44365
+ if (outcome.status === "cancelled") {
44366
+ return {
44367
+ status: "cancelled",
44368
+ ...outcome.reason ? { reason: outcome.reason } : {}
44369
+ };
44370
+ }
44371
+ return { status: "succeeded" };
44372
+ }
44373
+ function mapClaudeSnapshot(values, sessionId) {
44374
+ const messages = conversationMessages(values, sessionId);
44375
+ const turns = [];
44376
+ for (let index = 0; index < messages.length; ) {
44377
+ const user = messages[index];
44378
+ if (!user || !isHumanUser(user)) {
44379
+ index += 1;
44380
+ continue;
44381
+ }
44382
+ let end = index + 1;
44383
+ while (end < messages.length && !isHumanUser(messages[end]))
44384
+ end += 1;
44385
+ const turnMessages = messages.slice(index, end);
44386
+ const outcome = turnOutcome(turnMessages);
44387
+ const results = toolResultBlocks(turnMessages);
44388
+ const checkpointMessage = turnMessages.findLast(({ type, interrupted }) => type === "assistant" || interrupted);
44389
+ let agentMessageOrdinal = 0;
44390
+ let reasoningOrdinal = 0;
44391
+ let toolOrdinal = 0;
44392
+ turns.push({
44393
+ nativeTurnRef: nativeTurnRefSchema.parse({
44394
+ harnessId: claudeCodeHarnessId,
44395
+ nativeSessionId: sessionId,
44396
+ nativeTurnKey: user.uuid,
44397
+ formatVersion: 1
44398
+ }),
44399
+ ...checkpointMessage ? {
44400
+ checkpoint: nativeCheckpointRefSchema.parse({
44401
+ harnessId: claudeCodeHarnessId,
44402
+ nativeSessionId: sessionId,
44403
+ checkpointId: checkpointMessage.uuid,
44404
+ formatVersion: 1
44405
+ })
44406
+ } : {},
44407
+ input: visibleUserTextParts(user).map((text) => ({
44408
+ type: "text",
44409
+ text: displayedUserText(text)
44410
+ })),
44411
+ items: turnMessages.flatMap((message) => {
44412
+ if (message.type === "user") {
44413
+ const recapOutput = visibleUserTextParts(user).some((text2) => isNamedCommandEnvelope(text2, recapCommandNamePattern)) ? textParts(message.message.content).map(localCommandStdoutText).find((text2) => text2 !== null && text2.length > 0) : void 0;
44414
+ if (!recapOutput)
44415
+ return [];
44416
+ return [
44417
+ {
44418
+ item: {
44419
+ type: "agentMessage",
44420
+ itemId: claudeTranscriptItemId(user.uuid, "agentMessage", agentMessageOrdinal += 1),
44421
+ text: recapOutput
44422
+ },
44423
+ outcome: itemOutcome(outcome)
44424
+ }
44425
+ ];
44426
+ }
44427
+ if (message.type !== "assistant")
44428
+ return [];
44429
+ const content = message.message.content;
44430
+ const text = textParts(content).join("");
44431
+ const reasoning = thinkingParts(content).join("");
44432
+ if (!Array.isArray(content)) {
44433
+ return text.length > 0 ? [
44434
+ {
44435
+ item: {
44436
+ type: "agentMessage",
44437
+ itemId: claudeTranscriptItemId(user.uuid, "agentMessage", agentMessageOrdinal += 1),
44438
+ text
44439
+ },
44440
+ outcome: itemOutcome(outcome)
44441
+ }
44442
+ ] : [];
44443
+ }
44444
+ const items = [];
44445
+ let projectedReasoning = false;
44446
+ let projectedText = false;
44447
+ for (const [blockIndex, block] of content.entries()) {
44448
+ if (!isRecord5(block))
44449
+ continue;
44450
+ if (block.type === "thinking" && !projectedReasoning && reasoning.length > 0) {
44451
+ items.push({
44452
+ item: {
44453
+ type: "reasoning",
44454
+ itemId: claudeTranscriptItemId(user.uuid, "reasoning", reasoningOrdinal += 1),
44455
+ text: reasoning
44456
+ },
44457
+ outcome: itemOutcome(outcome)
44458
+ });
44459
+ projectedReasoning = true;
44460
+ continue;
44461
+ }
44462
+ if (block.type === "text" && !projectedText && text.length > 0) {
44463
+ items.push({
43223
44464
  item: {
43224
44465
  type: "agentMessage",
43225
44466
  itemId: claudeTranscriptItemId(user.uuid, "agentMessage", agentMessageOrdinal += 1),
@@ -43233,6 +44474,7 @@ function mapClaudeSnapshot(values, sessionId) {
43233
44474
  if (block.type !== "tool_use" || typeof block.id !== "string" || typeof block.name !== "string") {
43234
44475
  continue;
43235
44476
  }
44477
+ const toolItem = !message.nested && !CLAUDE_SUBAGENT_TOOLS.has(block.name) ? toolOrdinal += 1 : null;
43236
44478
  const result = results.get(block.id);
43237
44479
  if (!result)
43238
44480
  continue;
@@ -43246,8 +44488,8 @@ function mapClaudeSnapshot(values, sessionId) {
43246
44488
  retryable: false
43247
44489
  }
43248
44490
  } : { status: "succeeded" };
43249
- const itemId = hostItemIdSchema.parse(`claude-item-v1-${message.uuid}-tool-${blockIndex}`);
43250
- if (block.name === "Bash" && isRecord3(block.input) && typeof block.input.command === "string") {
44491
+ const itemId = toolItem !== null ? claudeTranscriptItemId(user.uuid, "tool", toolItem) : hostItemIdSchema.parse(`claude-item-v1-${message.uuid}-tool-${blockIndex}`);
44492
+ if (block.name === "Bash" && isRecord5(block.input) && typeof block.input.command === "string") {
43251
44493
  items.push({
43252
44494
  item: {
43253
44495
  type: "commandExecution",
@@ -43285,7 +44527,7 @@ function toolResultBlocks(messages) {
43285
44527
  if (message.type !== "user" || !Array.isArray(message.message.content))
43286
44528
  continue;
43287
44529
  for (const block of message.message.content) {
43288
- if (isRecord3(block) && block.type === "tool_result" && typeof block.tool_use_id === "string") {
44530
+ if (isRecord5(block) && block.type === "tool_result" && typeof block.tool_use_id === "string") {
43289
44531
  results.set(block.tool_use_id, block);
43290
44532
  }
43291
44533
  }
@@ -43300,7 +44542,7 @@ function toolResultOutput(block) {
43300
44542
  }
43301
44543
  function resultSubagentId(value, block) {
43302
44544
  const nativeResult = value.tool_use_result;
43303
- if (isRecord3(nativeResult)) {
44545
+ if (isRecord5(nativeResult)) {
43304
44546
  const structured = nativeResult.agentId ?? nativeResult.agent_id ?? nativeResult.task_id;
43305
44547
  if (typeof structured === "string" && structured.length > 0)
43306
44548
  return structured;
@@ -43308,16 +44550,16 @@ function resultSubagentId(value, block) {
43308
44550
  const match = /agentId:\s*([A-Za-z0-9_-]+)/u.exec(textParts(block.content).join(""));
43309
44551
  return match?.[1];
43310
44552
  }
43311
- function subagentPrompt(values, nativeSubagentId2) {
44553
+ function subagentPrompt2(values, nativeSubagentId2) {
43312
44554
  const toolUses = /* @__PURE__ */ new Map();
43313
44555
  for (const value of values) {
43314
- if (!isRecord3(value) || !isRecord3(value.message) || !Array.isArray(value.message.content)) {
44556
+ if (!isRecord5(value) || !isRecord5(value.message) || !Array.isArray(value.message.content)) {
43315
44557
  continue;
43316
44558
  }
43317
44559
  for (const block of value.message.content) {
43318
- if (!isRecord3(block))
44560
+ if (!isRecord5(block))
43319
44561
  continue;
43320
- if (block.type === "tool_use" && typeof block.id === "string" && (block.name === "Agent" || block.name === "Task") && isRecord3(block.input) && typeof block.input.prompt === "string" && block.input.prompt.length > 0) {
44562
+ if (block.type === "tool_use" && typeof block.id === "string" && (block.name === "Agent" || block.name === "Task") && isRecord5(block.input) && typeof block.input.prompt === "string" && block.input.prompt.length > 0) {
43321
44563
  toolUses.set(block.id, block.input.prompt);
43322
44564
  continue;
43323
44565
  }
@@ -43331,7 +44573,7 @@ function subagentPrompt(values, nativeSubagentId2) {
43331
44573
  return void 0;
43332
44574
  }
43333
44575
  function mapClaudeSubagentSnapshot(values, parentSessionId, nativeSubagentId2, parentValues = []) {
43334
- const messages = conversationMessages(values.map((value) => isRecord3(value) ? { ...value, session_id: parentSessionId } : value), parentSessionId);
44576
+ const messages = conversationMessages(values.map((value) => isRecord5(value) ? { ...value, session_id: parentSessionId } : value), parentSessionId);
43335
44577
  const turns = [];
43336
44578
  for (let index = 0; index < messages.length; ) {
43337
44579
  const first = messages[index];
@@ -43358,7 +44600,7 @@ function mapClaudeSubagentSnapshot(values, parentSessionId, nativeSubagentId2, p
43358
44600
  const content = Array.isArray(message.message.content) ? message.message.content : [{ type: "text", text: message.message.content }];
43359
44601
  for (let blockIndex = 0; blockIndex < content.length; blockIndex += 1) {
43360
44602
  const block = content[blockIndex];
43361
- if (!isRecord3(block))
44603
+ if (!isRecord5(block))
43362
44604
  continue;
43363
44605
  const itemId = hostItemIdSchema.parse(`claude-subagent-item-v2-${nativeSubagentId2}-${message.uuid}-${blockIndex}`);
43364
44606
  if (block.type === "thinking" && typeof block.thinking === "string") {
@@ -43395,7 +44637,7 @@ function mapClaudeSubagentSnapshot(values, parentSessionId, nativeSubagentId2, p
43395
44637
  retryable: false
43396
44638
  }
43397
44639
  } : { status: "succeeded" };
43398
- if (block.name === "Bash" && isRecord3(block.input) && typeof block.input.command === "string") {
44640
+ if (block.name === "Bash" && isRecord5(block.input) && typeof block.input.command === "string") {
43399
44641
  items.push({
43400
44642
  item: {
43401
44643
  type: "commandExecution",
@@ -43437,7 +44679,7 @@ function mapClaudeSubagentSnapshot(values, parentSessionId, nativeSubagentId2, p
43437
44679
  formatVersion: 1
43438
44680
  })
43439
44681
  } : {},
43440
- input: user ? visibleUserTextParts(user).map((text) => ({ type: "text", text })) : turns.length === 0 ? [subagentPrompt(parentValues, nativeSubagentId2)].filter((text) => text !== void 0).map((text) => ({ type: "text", text })) : [],
44682
+ input: user ? visibleUserTextParts(user).map((text) => ({ type: "text", text })) : turns.length === 0 ? [subagentPrompt2(parentValues, nativeSubagentId2)].filter((text) => text !== void 0).map((text) => ({ type: "text", text })) : [],
43441
44683
  items,
43442
44684
  outcome
43443
44685
  });
@@ -43525,7 +44767,7 @@ async function forkClaudeSession(input) {
43525
44767
  error: error51("protocolError", "Claude Code Session working directory is unavailable", false)
43526
44768
  };
43527
44769
  }
43528
- if (path7.resolve(sourceInfo.cwd) !== input.cwd) {
44770
+ if (path10.resolve(sourceInfo.cwd) !== input.cwd) {
43529
44771
  return {
43530
44772
  ok: false,
43531
44773
  error: error51("unsupported", "Claude Code cannot Fork across working directories", false)
@@ -43626,13 +44868,13 @@ async function forkClaudeSession(input) {
43626
44868
 
43627
44869
  // dist/claude-transcript.js
43628
44870
  import os5 from "node:os";
43629
- import path8 from "node:path";
43630
- import { readFile as readFile3, readdir, stat as stat3 } from "node:fs/promises";
44871
+ import path11 from "node:path";
44872
+ import { readFile as readFile4, readdir, stat as stat3 } from "node:fs/promises";
43631
44873
  function projectDirectoryName(cwd) {
43632
44874
  return cwd.replace(/[^A-Za-z0-9]/gu, "-");
43633
44875
  }
43634
44876
  function configDirectory(environment) {
43635
- return environment.CLAUDE_CONFIG_DIR ? path8.resolve(environment.CLAUDE_CONFIG_DIR) : path8.join(os5.homedir(), ".claude");
44877
+ return environment.CLAUDE_CONFIG_DIR ? path11.resolve(environment.CLAUDE_CONFIG_DIR) : path11.join(os5.homedir(), ".claude");
43636
44878
  }
43637
44879
  async function existingFile(file2) {
43638
44880
  try {
@@ -43642,9 +44884,9 @@ async function existingFile(file2) {
43642
44884
  }
43643
44885
  }
43644
44886
  async function findTranscript(input) {
43645
- const projectsDirectory = path8.join(configDirectory(input.environment), "projects");
44887
+ const projectsDirectory = path11.join(configDirectory(input.environment), "projects");
43646
44888
  const name = `${input.sessionId}.jsonl`;
43647
- const expected = path8.join(projectsDirectory, projectDirectoryName(input.cwd), name);
44889
+ const expected = path11.join(projectsDirectory, projectDirectoryName(input.cwd), name);
43648
44890
  if (await existingFile(expected))
43649
44891
  return expected;
43650
44892
  let projects;
@@ -43654,20 +44896,20 @@ async function findTranscript(input) {
43654
44896
  return null;
43655
44897
  }
43656
44898
  for (const project of projects) {
43657
- const candidate = path8.join(projectsDirectory, project, name);
44899
+ const candidate = path11.join(projectsDirectory, project, name);
43658
44900
  if (await existingFile(candidate))
43659
44901
  return candidate;
43660
44902
  }
43661
44903
  return null;
43662
44904
  }
43663
- function isRecord4(value) {
44905
+ function isRecord6(value) {
43664
44906
  return typeof value === "object" && value !== null && !Array.isArray(value);
43665
44907
  }
43666
44908
  async function readClaudeTranscript(input) {
43667
44909
  const transcript = await findTranscript(input);
43668
44910
  if (!transcript)
43669
44911
  return null;
43670
- const contents = await readFile3(transcript, "utf8");
44912
+ const contents = await readFile4(transcript, "utf8");
43671
44913
  const messages = [];
43672
44914
  for (const line of contents.split("\n")) {
43673
44915
  if (line.trim().length === 0)
@@ -43678,7 +44920,7 @@ async function readClaudeTranscript(input) {
43678
44920
  } catch {
43679
44921
  continue;
43680
44922
  }
43681
- if (!isRecord4(entry) || entry.type !== "user" && entry.type !== "assistant" || typeof entry.uuid !== "string" || !isRecord4(entry.message)) {
44923
+ if (!isRecord6(entry) || entry.type !== "user" && entry.type !== "assistant" || typeof entry.uuid !== "string" || !isRecord6(entry.message)) {
43682
44924
  continue;
43683
44925
  }
43684
44926
  messages.push({ ...entry, session_id: input.sessionId });
@@ -43688,9 +44930,9 @@ async function readClaudeTranscript(input) {
43688
44930
 
43689
44931
  // dist/model-catalog.js
43690
44932
  import { Buffer as Buffer2 } from "node:buffer";
43691
- import { readFile as readFile4 } from "node:fs/promises";
44933
+ import { readFile as readFile5 } from "node:fs/promises";
43692
44934
  import os6 from "node:os";
43693
- import path9 from "node:path";
44935
+ import path12 from "node:path";
43694
44936
 
43695
44937
  // dist/thinking-options.js
43696
44938
  var option = (id, label) => ({
@@ -43769,1118 +45011,385 @@ function decodeClaudeModelRef(ref) {
43769
45011
  if (encodeClaudeModelRef(value).id !== parsed.id) {
43770
45012
  throw new Error("Claude Code Model Ref is not canonical");
43771
45013
  }
43772
- return value === "default" ? void 0 : value;
43773
- }
43774
- function resolveClaudeConfigDirectory(environment = process.env) {
43775
- return path9.resolve(environment.CLAUDE_CONFIG_DIR ?? path9.join(os6.homedir(), ".claude"));
43776
- }
43777
- function parseModelPickerOptions(value) {
43778
- if (!Array.isArray(value))
43779
- return [];
43780
- const options = [];
43781
- const seen = /* @__PURE__ */ new Set();
43782
- for (const entry of value) {
43783
- const parsed = modelPickerOptionSchema.safeParse(entry);
43784
- if (!parsed.success)
43785
- continue;
43786
- if (seen.has(parsed.data.model))
43787
- continue;
43788
- seen.add(parsed.data.model);
43789
- options.push({
43790
- model: parsed.data.model,
43791
- ...parsed.data.label ? { label: parsed.data.label } : {},
43792
- ...parsed.data.description ? { description: parsed.data.description } : {},
43793
- ...parsed.data.behavesAs ? { behavesAs: parsed.data.behavesAs } : {}
43794
- });
43795
- }
43796
- return options;
43797
- }
43798
- function parseClaudeModelPickerSettings(value) {
43799
- if (value === void 0 || value === null)
43800
- return void 0;
43801
- const parsed = modelPickerSettingsSchema.safeParse(value);
43802
- if (!parsed.success)
43803
- return void 0;
43804
- if (parsed.data.options === void 0 && parsed.data.replaceBuiltInOptions === void 0) {
43805
- return void 0;
43806
- }
43807
- const options = parseModelPickerOptions(parsed.data.options);
43808
- if (Array.isArray(parsed.data.options) && parsed.data.options.length > 0 && options.length === 0) {
43809
- return void 0;
43810
- }
43811
- return {
43812
- options,
43813
- replaceBuiltInOptions: parsed.data.replaceBuiltInOptions === true
43814
- };
43815
- }
43816
- async function readClaudeUserModelPicker(environment = process.env) {
43817
- const settingsPath = path9.join(resolveClaudeConfigDirectory(environment), "settings.json");
43818
- let raw;
43819
- try {
43820
- raw = await readFile4(settingsPath, "utf8");
43821
- } catch {
43822
- return void 0;
43823
- }
43824
- let document2;
43825
- try {
43826
- document2 = JSON.parse(raw);
43827
- } catch {
43828
- return void 0;
43829
- }
43830
- if (document2 === null || typeof document2 !== "object" || Array.isArray(document2)) {
43831
- return void 0;
43832
- }
43833
- return parseClaudeModelPickerSettings(document2.modelPicker);
43834
- }
43835
- function optionToModelInfo(option2) {
43836
- return {
43837
- value: option2.model,
43838
- displayName: option2.label ?? option2.model,
43839
- ...option2.description ? { description: option2.description } : {},
43840
- ...option2.behavesAs ? { resolvedModel: option2.behavesAs } : {}
43841
- };
43842
- }
43843
- function readModelValue(row) {
43844
- if (row === null || typeof row !== "object" || Array.isArray(row))
43845
- return void 0;
43846
- const value = row.value;
43847
- return typeof value === "string" && value.trim().length > 0 ? value.trim() : void 0;
43848
- }
43849
- function mergeOptionOntoSdkRow(sdkRow, option2) {
43850
- const base = sdkRow !== null && typeof sdkRow === "object" && !Array.isArray(sdkRow) ? { ...sdkRow } : {};
43851
- const overlay = optionToModelInfo(option2);
43852
- return { ...base, ...overlay };
43853
- }
43854
- function mergeClaudeModelPickerOptions(sdkModels, modelPicker) {
43855
- if (!modelPicker)
43856
- return sdkModels;
43857
- const sdkRows = Array.isArray(sdkModels) ? [...sdkModels] : [];
43858
- const sdkByValue = /* @__PURE__ */ new Map();
43859
- for (const row of sdkRows) {
43860
- const value = readModelValue(row);
43861
- if (value && !sdkByValue.has(value))
43862
- sdkByValue.set(value, row);
43863
- }
43864
- if (modelPicker.replaceBuiltInOptions) {
43865
- const defaultSdk = sdkByValue.get("default");
43866
- const merged2 = [
43867
- defaultSdk !== void 0 ? defaultSdk : { value: "default", displayName: "Default" }
43868
- ];
43869
- const included2 = /* @__PURE__ */ new Set(["default"]);
43870
- for (const option2 of modelPicker.options) {
43871
- if (included2.has(option2.model)) {
43872
- if (option2.model === "default") {
43873
- merged2[0] = mergeOptionOntoSdkRow(merged2[0], option2);
43874
- }
43875
- continue;
43876
- }
43877
- merged2.push(mergeOptionOntoSdkRow(sdkByValue.get(option2.model), option2));
43878
- included2.add(option2.model);
43879
- }
43880
- return merged2;
43881
- }
43882
- const merged = [...sdkRows];
43883
- const included = new Set(sdkRows.flatMap((row) => {
43884
- const value = readModelValue(row);
43885
- return value ? [value] : [];
43886
- }));
43887
- for (const option2 of modelPicker.options) {
43888
- if (included.has(option2.model))
43889
- continue;
43890
- merged.push(mergeOptionOntoSdkRow(void 0, option2));
43891
- included.add(option2.model);
43892
- }
43893
- return merged;
43894
- }
43895
- function uniqueDisplayLabels(rows) {
43896
- const groups = /* @__PURE__ */ new Map();
43897
- for (const row of rows) {
43898
- const group = groups.get(row.displayName) ?? [];
43899
- group.push(row);
43900
- groups.set(row.displayName, group);
43901
- }
43902
- const labels = /* @__PURE__ */ new Map();
43903
- for (const [displayName, group] of groups) {
43904
- const sorted = [...group].sort((left, right) => left.value.localeCompare(right.value));
43905
- for (const [index, row] of sorted.entries()) {
43906
- if (sorted.length === 1) {
43907
- labels.set(row.value, displayName);
43908
- continue;
43909
- }
43910
- const nativeSuffix = ` (${row.value})`;
43911
- const suffix = displayName.length + nativeSuffix.length <= HARNESS_MODEL_LABEL_MAX_LENGTH ? nativeSuffix : ` (alias ${index + 1})`;
43912
- labels.set(row.value, `${displayName.slice(0, HARNESS_MODEL_LABEL_MAX_LENGTH - suffix.length)}${suffix}`);
43913
- }
43914
- }
43915
- return labels;
43916
- }
43917
- function normalizeRows(value) {
43918
- if (!Array.isArray(value))
43919
- throw new Error("Claude Code Model catalog is not an array");
43920
- const byValue = /* @__PURE__ */ new Map();
43921
- for (const nativeRow of value) {
43922
- const row = modelInfoSchema.parse(nativeRow);
43923
- const existing = byValue.get(row.value);
43924
- if (existing && JSON.stringify(existing) !== JSON.stringify(row)) {
43925
- throw new Error("Claude Code Model catalog contains conflicting selectable values");
43926
- }
43927
- if (!existing)
43928
- byValue.set(row.value, row);
43929
- }
43930
- if (byValue.size === 0)
43931
- throw new Error("Claude Code Model catalog is empty");
43932
- if (!byValue.has("default")) {
43933
- byValue.set("default", { value: "default", displayName: "Default" });
43934
- }
43935
- return [...byValue.values()];
43936
- }
43937
- function normalizeClaudeModelCatalog(snapshot) {
43938
- if (!snapshot.canSelectModel)
43939
- throw new Error("Claude Code Model selection is unavailable");
43940
- const rows = normalizeRows(snapshot.models);
43941
- const labels = uniqueDisplayLabels(rows);
43942
- const models = rows.map((row) => {
43943
- return {
43944
- ref: encodeClaudeModelRef(row.value),
43945
- label: labels.get(row.value) ?? row.displayName,
43946
- ...row.resolvedModel ? { resolvedModelLabel: row.resolvedModel } : {},
43947
- supportedThinkingOptionIds: [...CLAUDE_THINKING_OPTION_IDS]
43948
- };
43949
- });
43950
- models.sort((left, right) => {
43951
- if (left.ref.id === CLAUDE_DEFAULT_MODEL_REF.id)
43952
- return -1;
43953
- if (right.ref.id === CLAUDE_DEFAULT_MODEL_REF.id)
43954
- return 1;
43955
- return left.label.localeCompare(right.label) || left.ref.id.localeCompare(right.ref.id);
43956
- });
43957
- const catalog = harnessModelCatalogSchema.parse({
43958
- models,
43959
- defaultModel: CLAUDE_DEFAULT_MODEL_REF,
43960
- thinkingOptions: [...CLAUDE_THINKING_OPTIONS],
43961
- defaultThinkingOptionId: CLAUDE_DEFAULT_THINKING_OPTION_ID
43962
- });
43963
- return { catalog, defaultModel: CLAUDE_DEFAULT_MODEL_REF };
43964
- }
43965
-
43966
- // dist/permission-modes.js
43967
- var nativePermissionModes = /* @__PURE__ */ new Set([
43968
- "plan",
43969
- "default",
43970
- "acceptEdits",
43971
- "auto",
43972
- "bypassPermissions"
43973
- ]);
43974
- var CLAUDE_DEFAULT_PERMISSION_MODE_ID = harnessPermissionModeIdSchema.parse("default");
43975
- var claudePermissionModes = [
43976
- {
43977
- id: "plan",
43978
- label: "Plan mode",
43979
- description: "Explore and prepare a plan; approval exits planning and resumes the previous permission mode."
43980
- },
43981
- {
43982
- id: "default",
43983
- label: "Default",
43984
- description: "Ask before edits and other protected actions."
43985
- },
43986
- {
43987
- id: "acceptEdits",
43988
- label: "Accept edits",
43989
- description: "Allow file edits and ask for other protected actions."
43990
- },
43991
- {
43992
- id: "auto",
43993
- label: "Auto mode",
43994
- description: "Let Claude classify permission requests."
43995
- },
43996
- {
43997
- id: "bypassPermissions",
43998
- label: "Bypass permissions",
43999
- description: "Skip Claude Code permission checks.",
44000
- dangerous: true
44001
- }
44002
- ];
44003
- function createPermissionModeCatalog(includeAuto) {
44004
- return harnessPermissionModeCatalogSchema.parse({
44005
- modes: includeAuto ? claudePermissionModes : claudePermissionModes.filter(({ id }) => id !== "auto"),
44006
- defaultModeId: CLAUDE_DEFAULT_PERMISSION_MODE_ID
44007
- });
44008
- }
44009
- var CLAUDE_PERMISSION_MODE_CATALOG = createPermissionModeCatalog(true);
44010
- var CLAUDE_PERMISSION_MODE_CATALOG_WITHOUT_AUTO = createPermissionModeCatalog(false);
44011
- var autoModeModelInfoSchema = external_exports.object({ supportsAutoMode: external_exports.literal(true) });
44012
- function claudePermissionModeCatalogForModels(models) {
44013
- const supportsAutoMode = Array.isArray(models) && models.some((model) => autoModeModelInfoSchema.safeParse(model).success);
44014
- return supportsAutoMode ? CLAUDE_PERMISSION_MODE_CATALOG : CLAUDE_PERMISSION_MODE_CATALOG_WITHOUT_AUTO;
44015
- }
44016
- function decodeClaudePermissionModeId(permissionModeId) {
44017
- const parsed = harnessPermissionModeIdSchema.parse(permissionModeId);
44018
- if (!nativePermissionModes.has(parsed)) {
44019
- throw new Error("Claude Code Permission Mode belongs to another Adapter");
44020
- }
44021
- return parsed;
44022
- }
44023
- function encodeClaudePermissionModeId(permissionMode) {
44024
- if (!nativePermissionModes.has(permissionMode)) {
44025
- throw new Error("Claude Code returned an unsupported Permission Mode");
44026
- }
44027
- return harnessPermissionModeIdSchema.parse(permissionMode);
44028
- }
44029
- function isClaudePermissionMode(value) {
44030
- return typeof value === "string" && nativePermissionModes.has(value);
44031
- }
44032
-
44033
- // dist/sdk-transport.js
44034
- import { spawn } from "node:child_process";
44035
-
44036
- // dist/slash-commands.js
44037
- var DYNAMIC_ID_PREFIX = "claude.slash.";
44038
- var CLAUDE_EXCLUDED_COMMANDS = [
44039
- "advisor",
44040
- "agents",
44041
- "design-consent",
44042
- "design-revoke",
44043
- "doctor",
44044
- "extra-usage",
44045
- "import",
44046
- "team-onboarding",
44047
- "ultrareview",
44048
- "usage-credits",
44049
- "workflow-launch-exec"
44050
- ];
44051
- function parseClaudeSlashCommands(value) {
44052
- if (!Array.isArray(value))
44053
- return [];
44054
- return value.flatMap((entry) => {
44055
- if (typeof entry !== "object" || entry === null)
44056
- return [];
44057
- const record2 = entry;
44058
- const name = typeof record2.name === "string" ? record2.name.trim().replace(/^\//u, "") : "";
44059
- if (!name)
44060
- return [];
44061
- return [
44062
- {
44063
- name,
44064
- description: typeof record2.description === "string" ? record2.description : "",
44065
- argumentHint: typeof record2.argumentHint === "string" ? record2.argumentHint : ""
44066
- }
44067
- ];
44068
- });
44069
- }
44070
- function claudeLiveCommandCatalog(builtIns, snapshot) {
44071
- return mergeLiveHarnessCommands(builtIns, DYNAMIC_ID_PREFIX, snapshot?.commands.map((command) => ({
44072
- name: command.name,
44073
- description: command.description,
44074
- kind: snapshot.skillNames.has(command.name) ? "skill" : "command"
44075
- })) ?? null, { names: CLAUDE_EXCLUDED_COMMANDS });
44076
- }
44077
- function claudeDynamicCommandPrompt(catalog, commandId, argumentText) {
44078
- return liveHarnessCommandPrompt(catalog, DYNAMIC_ID_PREFIX, commandId, argumentText);
44079
- }
44080
-
44081
- // dist/account-usage.js
44082
- function projectClaudeAccountUsage(usage, account) {
44083
- if (!usage.rate_limits_available || !usage.rate_limits)
44084
- return null;
44085
- const limits = usage.rate_limits;
44086
- const windows = [];
44087
- const add = (product, periodType, value) => {
44088
- if (!value || typeof value.utilization !== "number" || !Number.isFinite(value.utilization) || value.utilization < 0 || value.utilization > 100)
44089
- return;
44090
- windows.push({
44091
- product,
44092
- periodType,
44093
- usagePercent: value.utilization,
44094
- ...value.resets_at && Number.isFinite(Date.parse(value.resets_at)) ? { resetsAt: value.resets_at } : {}
44095
- });
44096
- };
44097
- add("5-hour window", "five_hour", limits.five_hour);
44098
- add("7-day window", "seven_day", limits.seven_day);
44099
- add("OAuth apps · 7-day", "seven_day", limits.seven_day_oauth_apps);
44100
- add("Opus · 7-day", "seven_day", limits.seven_day_opus);
44101
- add("Sonnet · 7-day", "seven_day", limits.seven_day_sonnet);
44102
- for (const window2 of limits.model_scoped ?? [])
44103
- add(`${window2.display_name} · 7-day`, "seven_day", window2);
44104
- const [primary, ...others] = windows;
44105
- if (!primary)
44106
- return null;
44107
- const genericPrimary = primary.product === "5-hour window" || primary.product === "7-day window";
44108
- return {
44109
- ...account.email ? { email: account.email } : {},
44110
- ...usage.subscription_type ? { plan: usage.subscription_type } : {},
44111
- credits: {
44112
- usedPercent: primary.usagePercent,
44113
- periodType: primary.periodType,
44114
- ...!genericPrimary ? { label: primary.product } : {},
44115
- ...primary.resetsAt ? { resetsAt: primary.resetsAt } : {},
44116
- ...others.length ? {
44117
- productUsage: others.map(({ product, usagePercent, resetsAt }) => ({
44118
- product,
44119
- usagePercent,
44120
- ...resetsAt ? { resetsAt } : {}
44121
- }))
44122
- } : {}
44123
- }
44124
- };
44125
- }
44126
-
44127
- // dist/file-change.js
44128
- import path10 from "node:path";
44129
- var hunkSchema = external_exports.object({
44130
- oldStart: external_exports.number().int().nonnegative(),
44131
- oldLines: external_exports.number().int().nonnegative(),
44132
- newStart: external_exports.number().int().nonnegative(),
44133
- newLines: external_exports.number().int().nonnegative(),
44134
- lines: external_exports.array(external_exports.string())
44135
- }).strict();
44136
- function isRecord5(value) {
44137
- return typeof value === "object" && value !== null && !Array.isArray(value);
44138
- }
44139
- function validNativePath(value) {
44140
- return typeof value === "string" && value.trim().length > 0 && !value.includes("\0") && !value.includes("\n") && !value.includes("\r");
44141
- }
44142
- function countLines(lines, prefixes) {
44143
- return lines.filter((line) => line.length > 0 && prefixes.has(line[0])).length;
44144
- }
44145
- function validHunk(value) {
44146
- const parsed = hunkSchema.safeParse(value);
44147
- if (!parsed.success)
44148
- return null;
44149
- const hunk = parsed.data;
44150
- if (hunk.lines.some((line) => line.length === 0 || ![" ", "+", "-", "\\"].includes(line[0]))) {
44151
- return null;
44152
- }
44153
- if (countLines(hunk.lines, /* @__PURE__ */ new Set([" ", "-"])) !== hunk.oldLines)
44154
- return null;
44155
- if (countLines(hunk.lines, /* @__PURE__ */ new Set([" ", "+"])) !== hunk.newLines)
44156
- return null;
44157
- return hunk;
44158
- }
44159
- function parseClaudeNativeFileChange(toolName, value) {
44160
- if (toolName !== "Edit" && toolName !== "Write" || !isRecord5(value))
44161
- return null;
44162
- if (!validNativePath(value.filePath) || !Array.isArray(value.structuredPatch))
44163
- return null;
44164
- const hunks = value.structuredPatch.map(validHunk);
44165
- if (hunks.length === 0 || hunks.some((hunk) => hunk === null))
44166
- return null;
44167
- if (toolName === "Write" && value.type !== "create" && value.type !== "update")
44168
- return null;
44169
- return {
44170
- path: value.filePath,
44171
- kind: toolName === "Write" && value.type === "create" ? "add" : "update",
44172
- hunks
44173
- };
44174
- }
44175
- function displayPath(nativePath, cwd) {
44176
- const resolvedCwd = path10.resolve(cwd);
44177
- const resolvedPath = path10.isAbsolute(nativePath) ? path10.resolve(nativePath) : path10.resolve(cwd, nativePath);
44178
- const relative = path10.relative(resolvedCwd, resolvedPath);
44179
- const selected = relative.length > 0 && relative !== ".." && !relative.startsWith(`..${path10.sep}`) ? relative : resolvedPath;
44180
- const normalized = selected.replaceAll("\\", "/");
44181
- return validNativePath(normalized) && normalized !== "." ? normalized : null;
44182
- }
44183
- function projectClaudeFileChange(value, cwd) {
44184
- const normalizedPath = displayPath(value.path, cwd);
44185
- if (!normalizedPath)
44186
- return null;
44187
- const body = value.hunks.flatMap((hunk) => [
44188
- `@@ -${hunk.oldStart},${hunk.oldLines} +${hunk.newStart},${hunk.newLines} @@`,
44189
- ...hunk.lines
44190
- ]);
44191
- const absoluteDisplayPath = path10.posix.isAbsolute(normalizedPath);
44192
- const oldHeader = value.kind === "add" ? "/dev/null" : absoluteDisplayPath ? normalizedPath : `a/${normalizedPath}`;
44193
- const newHeader = absoluteDisplayPath ? normalizedPath : `b/${normalizedPath}`;
44194
- const unifiedDiff = [`--- ${oldHeader}`, `+++ ${newHeader}`, ...body, ""].join("\n");
44195
- return { path: normalizedPath, kind: value.kind, unifiedDiff };
44196
- }
44197
-
44198
- // dist/native-message.js
44199
- var ABORTED_TERMINALS = /* @__PURE__ */ new Set(["aborted_streaming", "aborted_tools"]);
44200
- var AUTHENTICATION_ERRORS = /* @__PURE__ */ new Set(["authentication_failed", "oauth_org_not_allowed"]);
44201
- var SUBAGENT_TOOLS = /* @__PURE__ */ new Set(["Agent", "Task", "SendMessage"]);
44202
- var SUBAGENT_DESCRIPTION_LIMIT = 500;
44203
- var SUBAGENT_SUMMARY_LIMIT = 2e3;
44204
- function isRecord6(value) {
44205
- return typeof value === "object" && value !== null && !Array.isArray(value);
44206
- }
44207
- function nativeUuid(message) {
44208
- return typeof message.uuid === "string" && message.uuid.length > 0 ? message.uuid : null;
44209
- }
44210
- function parentToolUseId(message) {
44211
- return typeof message.parent_tool_use_id === "string" && message.parent_tool_use_id.length > 0 ? message.parent_tool_use_id : null;
44212
- }
44213
- function assistantNativeMessageId(message) {
44214
- if (!isRecord6(message.message))
44215
- return null;
44216
- return typeof message.message.id === "string" && message.message.id.length > 0 ? message.message.id : null;
44217
- }
44218
- function assistantContent(message) {
44219
- if (message.type !== "assistant" || !isRecord6(message.message))
44220
- return null;
44221
- return Array.isArray(message.message.content) ? message.message.content : null;
44222
- }
44223
- function assistantText(message) {
44224
- const content = assistantContent(message);
44225
- if (!content)
44226
- return null;
44227
- return content.flatMap((block) => isRecord6(block) && block.type === "text" && typeof block.text === "string" ? [block.text] : []).join("");
44228
- }
44229
- function assistantError(message) {
44230
- return isRecord6(message) && message.type === "assistant" && typeof message.error === "string" ? message.error : null;
44231
- }
44232
- function boundedString(value, limit) {
44233
- if (typeof value !== "string")
44234
- return void 0;
44235
- const trimmed = value.trim();
44236
- if (trimmed.length === 0)
44237
- return void 0;
44238
- return trimmed.slice(0, limit);
44239
- }
44240
- function subagentDescription(argumentsValue, toolName) {
44241
- if (!isRecord6(argumentsValue))
44242
- return `${toolName} delegation`;
44243
- return boundedString(argumentsValue.description, SUBAGENT_DESCRIPTION_LIMIT) ?? boundedString(argumentsValue.summary, SUBAGENT_DESCRIPTION_LIMIT) ?? boundedString(argumentsValue.name, SUBAGENT_DESCRIPTION_LIMIT) ?? `${toolName} delegation`;
44244
- }
44245
- function subagentPrompt2(argumentsValue) {
44246
- if (!isRecord6(argumentsValue))
44247
- return void 0;
44248
- return boundedString(argumentsValue.prompt ?? argumentsValue.message, SUBAGENT_SUMMARY_LIMIT);
44249
- }
44250
- function subagentRole(argumentsValue) {
44251
- if (!isRecord6(argumentsValue))
44252
- return void 0;
44253
- return boundedString(argumentsValue.subagent_type ?? argumentsValue.agent_type, SUBAGENT_DESCRIPTION_LIMIT);
44254
- }
44255
- function subagentBackground(argumentsValue) {
44256
- return isRecord6(argumentsValue) && argumentsValue.run_in_background === true;
44257
- }
44258
- function targetedSubagentId(argumentsValue) {
44259
- if (!isRecord6(argumentsValue))
44260
- return void 0;
44261
- return boundedString(argumentsValue.to ?? argumentsValue.recipient ?? argumentsValue.agentId, SUBAGENT_DESCRIPTION_LIMIT);
44262
- }
44263
- function includesAuthenticationFailure(message, errors) {
44264
- if (errors.some((error52) => AUTHENTICATION_ERRORS.has(error52)))
44265
- return true;
44266
- const text = [message.result, ...Array.isArray(message.errors) ? message.errors : []].filter((value) => typeof value === "string").join(" ").toLowerCase();
44267
- return text.includes("not logged in") || text.includes("invalid api key") || text.includes("oauth");
44268
- }
44269
- function failure(kind) {
44270
- return { status: "failed", kind };
44271
- }
44272
- function safeNonNegativeInteger(value) {
44273
- return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
45014
+ return value === "default" ? void 0 : value;
44274
45015
  }
44275
- function finiteNonNegativeNumber(value) {
44276
- return typeof value === "number" && Number.isFinite(value) && value >= 0;
45016
+ function resolveClaudeConfigDirectory(environment = process.env) {
45017
+ return path12.resolve(environment.CLAUDE_CONFIG_DIR ?? path12.join(os6.homedir(), ".claude"));
44277
45018
  }
44278
- function parseResultModelUsage(value) {
44279
- if (!isRecord6(value))
44280
- return void 0;
44281
- const usage = [];
44282
- for (const entry of Object.values(value)) {
44283
- if (!isRecord6(entry) || !safeNonNegativeInteger(entry.inputTokens) || !safeNonNegativeInteger(entry.outputTokens)) {
44284
- return void 0;
44285
- }
44286
- usage.push({ inputTokens: entry.inputTokens, outputTokens: entry.outputTokens });
45019
+ function parseModelPickerOptions(value) {
45020
+ if (!Array.isArray(value))
45021
+ return [];
45022
+ const options = [];
45023
+ const seen = /* @__PURE__ */ new Set();
45024
+ for (const entry of value) {
45025
+ const parsed = modelPickerOptionSchema.safeParse(entry);
45026
+ if (!parsed.success)
45027
+ continue;
45028
+ if (seen.has(parsed.data.model))
45029
+ continue;
45030
+ seen.add(parsed.data.model);
45031
+ options.push({
45032
+ model: parsed.data.model,
45033
+ ...parsed.data.label ? { label: parsed.data.label } : {},
45034
+ ...parsed.data.description ? { description: parsed.data.description } : {},
45035
+ ...parsed.data.behavesAs ? { behavesAs: parsed.data.behavesAs } : {}
45036
+ });
44287
45037
  }
44288
- return usage;
45038
+ return options;
44289
45039
  }
44290
- function parseLastRequestUsage(value, attribution = {}) {
44291
- if (!isRecord6(value))
45040
+ function parseClaudeModelPickerSettings(value) {
45041
+ if (value === void 0 || value === null)
44292
45042
  return void 0;
44293
- const inputTokens = value.input_tokens;
44294
- const outputTokens = value.output_tokens;
44295
- const cacheCreationInputTokens = value.cache_creation_input_tokens;
44296
- const cacheReadInputTokens = value.cache_read_input_tokens;
44297
- if (!safeNonNegativeInteger(inputTokens) || !safeNonNegativeInteger(outputTokens) || !safeNonNegativeInteger(cacheCreationInputTokens) || !safeNonNegativeInteger(cacheReadInputTokens)) {
45043
+ const parsed = modelPickerSettingsSchema.safeParse(value);
45044
+ if (!parsed.success)
45045
+ return void 0;
45046
+ if (parsed.data.options === void 0 && parsed.data.replaceBuiltInOptions === void 0) {
44298
45047
  return void 0;
44299
45048
  }
44300
- const requestId = boundedString(attribution.requestId, 500);
44301
- const model = boundedString(attribution.model, 500);
44302
- const provider = boundedString(attribution.provider, 100);
44303
- return {
44304
- ...requestId ? { requestId } : {},
44305
- ...model ? { model } : {},
44306
- ...provider ? { provider } : {},
44307
- inputTokens,
44308
- outputTokens,
44309
- cacheCreationInputTokens,
44310
- cacheReadInputTokens
44311
- };
44312
- }
44313
- function assistantRequestUsage(message, provider) {
44314
- if (!isRecord6(message.message))
45049
+ const options = parseModelPickerOptions(parsed.data.options);
45050
+ if (Array.isArray(parsed.data.options) && parsed.data.options.length > 0 && options.length === 0) {
44315
45051
  return void 0;
44316
- return parseLastRequestUsage(message.message.usage, {
44317
- requestId: message.message.id ?? message.request_id,
44318
- model: message.message.model,
44319
- provider: message.provider ?? message.message.provider ?? provider
44320
- });
44321
- }
44322
- function parseResultUsageEvent(message) {
44323
- const totalCostUsd = finiteNonNegativeNumber(message.total_cost_usd) ? message.total_cost_usd : void 0;
44324
- const modelUsage = parseResultModelUsage(message.modelUsage);
44325
- const lastRequestUsage = parseLastRequestUsage(message.usage);
44326
- if (totalCostUsd === void 0 && modelUsage === void 0 && lastRequestUsage === void 0) {
44327
- return null;
44328
45052
  }
44329
45053
  return {
44330
- type: "usage.result",
44331
- ...totalCostUsd !== void 0 ? { totalCostUsd } : {},
44332
- ...modelUsage !== void 0 ? { modelUsage } : {},
44333
- ...lastRequestUsage ? { lastRequestUsage } : {}
45054
+ options,
45055
+ replaceBuiltInOptions: parsed.data.replaceBuiltInOptions === true
44334
45056
  };
44335
45057
  }
44336
- function parsePlanLimitWindow(value) {
44337
- if (!isRecord6(value))
45058
+ async function readClaudeUserModelPicker(environment = process.env) {
45059
+ const settingsPath = path12.join(resolveClaudeConfigDirectory(environment), "settings.json");
45060
+ let raw;
45061
+ try {
45062
+ raw = await readFile5(settingsPath, "utf8");
45063
+ } catch {
44338
45064
  return void 0;
44339
- const utilization = value.utilization;
44340
- if (typeof utilization !== "number" || !Number.isFinite(utilization) || utilization < 0) {
45065
+ }
45066
+ let document2;
45067
+ try {
45068
+ document2 = JSON.parse(raw);
45069
+ } catch {
44341
45070
  return void 0;
44342
45071
  }
44343
- const utilizationPercent = Math.min(100, Math.max(0, Math.round(utilization * 1e4) / 100));
44344
- const resetsAt = value.resetsAt;
44345
- const resetsAtUnix = safeNonNegativeInteger(resetsAt) ? resetsAt : void 0;
44346
- return { utilizationPercent, ...resetsAtUnix !== void 0 ? { resetsAtUnix } : {} };
44347
- }
44348
- function parseClaudePlanLimitEvent(message) {
44349
- if (!isRecord6(message) || message.type !== "rate_limit_event")
44350
- return null;
44351
- const info = message.rate_limit_info;
44352
- if (!isRecord6(info))
44353
- return null;
44354
- const windows = isRecord6(info.unifiedWindows) ? info.unifiedWindows : void 0;
44355
- let fiveHour = parsePlanLimitWindow(windows?.five_hour);
44356
- let sevenDay = parsePlanLimitWindow(windows?.seven_day);
44357
- if (!fiveHour && !sevenDay) {
44358
- const flatWindow = parsePlanLimitWindow(info);
44359
- if (flatWindow && info.rateLimitType === "five_hour")
44360
- fiveHour = flatWindow;
44361
- else if (flatWindow && info.rateLimitType === "seven_day")
44362
- sevenDay = flatWindow;
45072
+ if (document2 === null || typeof document2 !== "object" || Array.isArray(document2)) {
45073
+ return void 0;
44363
45074
  }
44364
- if (!fiveHour && !sevenDay)
44365
- return null;
45075
+ return parseClaudeModelPickerSettings(document2.modelPicker);
45076
+ }
45077
+ function optionToModelInfo(option2) {
44366
45078
  return {
44367
- ...fiveHour ? { fiveHour } : {},
44368
- ...sevenDay ? { sevenDay } : {}
45079
+ value: option2.model,
45080
+ displayName: option2.label ?? option2.model,
45081
+ ...option2.description ? { description: option2.description } : {},
45082
+ ...option2.behavesAs ? { resolvedModel: option2.behavesAs } : {}
44369
45083
  };
44370
45084
  }
44371
- function nativeSubagentId(nativeResult, outputText) {
44372
- if (isRecord6(nativeResult)) {
44373
- const structured = boundedString(nativeResult.agentId ?? nativeResult.agent_id ?? nativeResult.task_id, SUBAGENT_DESCRIPTION_LIMIT);
44374
- if (structured)
44375
- return structured;
44376
- }
44377
- return boundedString(/agentId:\s*([A-Za-z0-9_-]+)/u.exec(outputText ?? "")?.[1], SUBAGENT_DESCRIPTION_LIMIT);
44378
- }
44379
- function subagentContinuesInBackground(nativeResult, outputText) {
44380
- if (isRecord6(nativeResult)) {
44381
- if (nativeResult.isAsync === true || nativeResult.is_async === true)
44382
- return true;
44383
- if (nativeResult.status === "async_launched")
44384
- return true;
44385
- }
44386
- return outputText?.includes("The agent is working in the background.") ?? false;
44387
- }
44388
- function resultText(content, nativeResult) {
44389
- let text = "";
44390
- if (typeof content === "string") {
44391
- text = content;
44392
- } else if (Array.isArray(content)) {
44393
- text = content.flatMap((block) => isRecord6(block) && block.type === "text" && typeof block.text === "string" ? [block.text] : []).join("");
44394
- }
44395
- if (text.length > 0)
44396
- return text;
44397
- if (!isRecord6(nativeResult))
45085
+ function readModelValue(row) {
45086
+ if (row === null || typeof row !== "object" || Array.isArray(row))
44398
45087
  return void 0;
44399
- const stdout = typeof nativeResult.stdout === "string" ? nativeResult.stdout : "";
44400
- const stderr = typeof nativeResult.stderr === "string" ? nativeResult.stderr : "";
44401
- const combined = stdout + stderr;
44402
- return combined.length > 0 ? combined : void 0;
44403
- }
44404
- function userMessageText(content) {
44405
- if (typeof content === "string")
44406
- return content;
44407
- if (!Array.isArray(content))
44408
- return null;
44409
- const text = content.flatMap((block) => isRecord6(block) && block.type === "text" && typeof block.text === "string" ? [block.text] : []).join("");
44410
- return text.length > 0 ? text : null;
44411
- }
44412
- function parseClaudeTaskNotification(message) {
44413
- if (!isRecord6(message) || message.type !== "user" || !isRecord6(message.message))
44414
- return null;
44415
- if (isRecord6(message.origin) && message.origin.kind !== "task-notification")
44416
- return null;
44417
- const content = userMessageText(message.message.content);
44418
- if (!content || !content.includes("<task-notification>"))
44419
- return null;
44420
- const taskId = content.match(/<task-id>([^<]+)<\/task-id>/u)?.[1]?.trim();
44421
- if (!taskId)
44422
- return null;
44423
- const xmlStatus = content.match(/<status>([^<]+)<\/status>/u)?.[1]?.trim();
44424
- const status = taskStatus(xmlStatus ?? "completed");
44425
- if (status !== "completed" && status !== "failed" && status !== "interrupted")
44426
- return null;
44427
- const summary = content.match(/<summary>([\s\S]*?)<\/summary>/u)?.[1]?.trim();
44428
- const callId = content.match(/<tool-use-id>([^<]+)<\/tool-use-id>/u)?.[1]?.trim();
44429
- return {
44430
- type: "subagent.settled",
44431
- nativeSubagentId: taskId,
44432
- status,
44433
- ...callId ? { callId } : {},
44434
- ...summary ? { resultSummary: summary.slice(0, SUBAGENT_SUMMARY_LIMIT) } : {}
44435
- };
45088
+ const value = row.value;
45089
+ return typeof value === "string" && value.trim().length > 0 ? value.trim() : void 0;
44436
45090
  }
44437
- function taskStatus(value) {
44438
- switch (value) {
44439
- case "pending":
44440
- return "pending";
44441
- case "running":
44442
- return "running";
44443
- case "completed":
44444
- return "completed";
44445
- case "failed":
44446
- return "failed";
44447
- case "killed":
44448
- case "stopped":
44449
- return "interrupted";
44450
- default:
44451
- return null;
44452
- }
45091
+ function mergeOptionOntoSdkRow(sdkRow, option2) {
45092
+ const base = sdkRow !== null && typeof sdkRow === "object" && !Array.isArray(sdkRow) ? { ...sdkRow } : {};
45093
+ const overlay = optionToModelInfo(option2);
45094
+ return { ...base, ...overlay };
44453
45095
  }
44454
- var ClaudeNativeTurnAccumulator = class {
44455
- #provider;
44456
- #activeRootStreamMessageId = null;
44457
- #assistantErrors = [];
44458
- #cancelRequested = false;
44459
- #compactionState = "idle";
44460
- #completed = false;
44461
- #completedToolIds = /* @__PURE__ */ new Set();
44462
- #messageOrdinal = 0;
44463
- #messages = /* @__PURE__ */ new Map();
44464
- #protocolConflict = false;
44465
- #textConflict = false;
44466
- #tools = /* @__PURE__ */ new Map();
44467
- constructor(options = {}) {
44468
- this.#provider = options.provider;
44469
- }
44470
- requestCancel() {
44471
- this.#cancelRequested = true;
44472
- }
44473
- consume(message) {
44474
- if (this.#completed || !isRecord6(message))
44475
- return { events: [] };
44476
- const events = [];
44477
- this.#consumeSegmentLevel(message, events);
44478
- this.#consumeTaskLifecycle(message, events);
44479
- const parentCallId = parentToolUseId(message);
44480
- const nested = parentCallId !== null;
44481
- if (parentCallId && this.#tools.get(parentCallId)?.subagent === true && (message.type === "assistant" || message.type === "user")) {
44482
- events.push({ type: "subagent.transcript.changed", callId: parentCallId });
44483
- }
44484
- if (!nested) {
44485
- this.#consumeCompaction(message, events);
44486
- this.#consumeLocalCommandOutput(message, events);
44487
- }
44488
- if (message.type === "stream_event" && isRecord6(message.event)) {
44489
- if (!nested)
44490
- this.#consumeStreamEvent(message, events);
44491
- } else if (message.type === "tool_progress") {
44492
- this.#consumeToolProgress(message, events);
44493
- }
44494
- if (!nested) {
44495
- const error52 = assistantError(message);
44496
- if (error52 !== null)
44497
- this.#assistantErrors.push(error52);
44498
- }
44499
- if (message.type === "assistant") {
44500
- if (!nested)
44501
- this.#consumeAssistantMessage(message, events);
44502
- } else if (message.type === "user") {
44503
- this.#consumeTaskNotification(message, events);
44504
- this.#consumeToolResults(message, events, nested);
44505
- }
44506
- if (message.type !== "result")
44507
- return { events };
44508
- const usageEvent = parseResultUsageEvent(message);
44509
- if (usageEvent)
44510
- events.push(usageEvent);
44511
- this.#completed = true;
44512
- const terminalReason = typeof message.terminal_reason === "string" ? message.terminal_reason : "missing";
44513
- const nativeSuccess = message.subtype === "success" && message.is_error === false && (terminalReason === "completed" || terminalReason === "missing") && this.#assistantErrors.length === 0;
44514
- if (nativeSuccess && this.#tools.size > 0)
44515
- this.#protocolConflict = true;
44516
- let terminal;
44517
- if (this.#protocolConflict) {
44518
- terminal = failure("protocol");
44519
- } else if (this.#textConflict) {
44520
- terminal = failure("textConflict");
44521
- } else if (includesAuthenticationFailure(message, this.#assistantErrors)) {
44522
- terminal = failure("authentication");
44523
- } else if (this.#cancelRequested && ABORTED_TERMINALS.has(terminalReason)) {
44524
- terminal = { status: "cancelled", reason: terminalReason };
44525
- } else if (this.#cancelRequested) {
44526
- terminal = failure("cancellationUnproven");
44527
- } else if (nativeSuccess) {
44528
- terminal = { status: "succeeded" };
44529
- } else {
44530
- terminal = failure("native");
44531
- }
44532
- return { events, terminal };
44533
- }
44534
- #consumeCompaction(message, events) {
44535
- if (message.type !== "system")
44536
- return;
44537
- if (message.subtype === "status") {
44538
- if (message.status === "compacting" && this.#compactionState !== "active") {
44539
- this.#compactionState = "active";
44540
- events.push({ type: "compaction.started" });
44541
- }
44542
- if (message.compact_result === "success" || message.compact_result === "failed") {
44543
- if (this.#compactionState === "settled")
44544
- return;
44545
- if (this.#compactionState === "idle")
44546
- events.push({ type: "compaction.started" });
44547
- this.#compactionState = "settled";
44548
- events.push({
44549
- type: "compaction.completed",
44550
- outcome: message.compact_result === "success" ? "succeeded" : "failed"
44551
- });
44552
- }
44553
- return;
44554
- }
44555
- if (message.subtype !== "compact_boundary" || this.#compactionState === "settled")
44556
- return;
44557
- if (this.#compactionState === "idle")
44558
- events.push({ type: "compaction.started" });
44559
- this.#compactionState = "settled";
44560
- events.push({ type: "compaction.completed", outcome: "succeeded" });
44561
- }
44562
- #consumeLocalCommandOutput(message, events) {
44563
- if (message.type !== "system" || message.subtype !== "local_command_output")
44564
- return;
44565
- if (typeof message.content !== "string" || message.content.length === 0)
44566
- return;
44567
- const checkpointId = nativeUuid(message);
44568
- const messageId = checkpointId ?? this.#nextMessageId();
44569
- const state = this.#messageState(messageId);
44570
- if (state.completed)
44571
- return;
44572
- state.text += message.content;
44573
- events.push({ type: "text.delta", messageId, delta: message.content });
44574
- state.completed = true;
44575
- events.push({
44576
- type: "message.completed",
44577
- messageId,
44578
- ...checkpointId ? { checkpointId } : {}
44579
- });
44580
- }
44581
- /**
44582
- * Claude opens one native Segment per Root execution and reports its live
44583
- * background tasks as a level whose membership replaces the previous set.
44584
- */
44585
- #consumeSegmentLevel(message, events) {
44586
- if (message.type !== "system")
44587
- return;
44588
- if (message.subtype === "init") {
44589
- events.push({ type: "segment.started" });
44590
- return;
44591
- }
44592
- if (message.subtype !== "background_tasks_changed" || !Array.isArray(message.tasks))
44593
- return;
44594
- const nativeSubagentIds = message.tasks.flatMap((task) => {
44595
- if (!isRecord6(task))
44596
- return [];
44597
- const taskId = boundedString(task.task_id, SUBAGENT_DESCRIPTION_LIMIT);
44598
- return taskId ? [taskId] : [];
44599
- });
44600
- events.push({ type: "subagents.live", nativeSubagentIds });
44601
- }
44602
- #consumeTaskLifecycle(message, events) {
44603
- if (message.type !== "system")
44604
- return;
44605
- if (message.subtype === "task_notification") {
44606
- const agentId = boundedString(message.task_id, SUBAGENT_DESCRIPTION_LIMIT);
44607
- const status = taskStatus(message.status);
44608
- if (!agentId || status !== "completed" && status !== "failed" && status !== "interrupted") {
44609
- return;
44610
- }
44611
- const resultSummary = boundedString(message.summary, SUBAGENT_SUMMARY_LIMIT);
44612
- const callId2 = boundedString(message.tool_use_id, SUBAGENT_DESCRIPTION_LIMIT);
44613
- events.push({
44614
- type: "subagent.settled",
44615
- nativeSubagentId: agentId,
44616
- status,
44617
- ...callId2 ? { callId: callId2 } : {},
44618
- ...resultSummary ? { resultSummary } : {}
44619
- });
44620
- return;
44621
- }
44622
- const callId = typeof message.tool_use_id === "string" ? message.tool_use_id : null;
44623
- if (!callId || !this.#tools.get(callId)?.subagent)
44624
- return;
44625
- if (message.subtype === "task_started") {
44626
- const description = boundedString(message.description, SUBAGENT_DESCRIPTION_LIMIT);
44627
- const role = boundedString(message.subagent_type, SUBAGENT_DESCRIPTION_LIMIT);
44628
- const agentId = boundedString(message.task_id, SUBAGENT_DESCRIPTION_LIMIT);
44629
- events.push({
44630
- type: "subagent.updated",
44631
- callId,
44632
- status: "running",
44633
- ...description ? { description } : {},
44634
- ...role ? { role } : {},
44635
- ...agentId ? { nativeSubagentId: agentId } : {}
44636
- });
44637
- return;
44638
- }
44639
- if (message.subtype === "task_progress") {
44640
- const description = boundedString(message.description, SUBAGENT_DESCRIPTION_LIMIT);
44641
- const role = boundedString(message.subagent_type, SUBAGENT_DESCRIPTION_LIMIT);
44642
- const resultSummary = boundedString(message.summary, SUBAGENT_SUMMARY_LIMIT);
44643
- const agentId = boundedString(message.task_id, SUBAGENT_DESCRIPTION_LIMIT);
44644
- events.push({
44645
- type: "subagent.updated",
44646
- callId,
44647
- status: "running",
44648
- ...description ? { description } : {},
44649
- ...role ? { role } : {},
44650
- ...agentId ? { nativeSubagentId: agentId } : {},
44651
- ...resultSummary ? { resultSummary } : {}
44652
- });
44653
- return;
44654
- }
44655
- if (message.subtype === "task_updated" && isRecord6(message.patch)) {
44656
- const status = taskStatus(message.patch.status);
44657
- if (!status)
44658
- return;
44659
- const description = boundedString(message.patch.description, SUBAGENT_DESCRIPTION_LIMIT);
44660
- const resultSummary = boundedString(message.patch.error, SUBAGENT_SUMMARY_LIMIT);
44661
- const agentId = boundedString(message.task_id, SUBAGENT_DESCRIPTION_LIMIT);
44662
- events.push({
44663
- type: "subagent.updated",
44664
- callId,
44665
- status,
44666
- ...description ? { description } : {},
44667
- ...agentId ? { nativeSubagentId: agentId } : {},
44668
- ...resultSummary ? { resultSummary } : {}
44669
- });
44670
- }
44671
- }
44672
- #consumeStreamEvent(message, events) {
44673
- const event = message.event;
44674
- if (!isRecord6(event))
44675
- return;
44676
- if (event.type === "message_start" && isRecord6(event.message) && typeof event.message.id === "string" && event.message.id.length > 0) {
44677
- this.#activeRootStreamMessageId = event.message.id;
44678
- this.#messageState(event.message.id);
44679
- return;
44680
- }
44681
- if (event.type !== "content_block_delta" || !isRecord6(event.delta))
44682
- return;
44683
- const messageId = this.#activeRootStreamMessageId ?? nativeUuid(message) ?? this.#nextMessageId();
44684
- if (!this.#activeRootStreamMessageId)
44685
- this.#activeRootStreamMessageId = messageId;
44686
- const state = this.#messageState(messageId);
44687
- if (state.completed) {
44688
- if (event.delta.type === "text_delta")
44689
- this.#textConflict = true;
44690
- return;
44691
- }
44692
- if (event.delta.type === "text_delta" && typeof event.delta.text === "string") {
44693
- if (event.delta.text.length === 0)
44694
- return;
44695
- state.text += event.delta.text;
44696
- events.push({ type: "text.delta", messageId, delta: event.delta.text });
44697
- return;
44698
- }
44699
- if (event.delta.type === "thinking_delta" && typeof event.delta.thinking === "string") {
44700
- if (event.delta.thinking.length === 0)
44701
- return;
44702
- state.reasoning += event.delta.thinking;
44703
- events.push({ type: "reasoning.delta", messageId, delta: event.delta.thinking });
44704
- }
44705
- }
44706
- #consumeAssistantMessage(message, events) {
44707
- const checkpointId = nativeUuid(message);
44708
- const nativeMessageId = assistantNativeMessageId(message);
44709
- const messageId = this.#activeRootStreamMessageId ?? nativeMessageId ?? checkpointId ?? this.#nextMessageId();
44710
- const state = this.#messageState(messageId);
44711
- if (state.completed) {
44712
- this.#consumeToolUseBlocks(message, events, true);
44713
- const usage = assistantRequestUsage(message, this.#provider);
44714
- if (usage && !state.usagePublished) {
44715
- state.usagePublished = true;
44716
- events.push({
44717
- type: "message.completed",
44718
- messageId,
44719
- ...checkpointId ? { checkpointId } : {},
44720
- lastRequestUsage: usage
44721
- });
44722
- }
44723
- return;
44724
- }
44725
- if (state.reasoning.length > 0) {
44726
- events.push({ type: "reasoning.completed", messageId });
44727
- }
44728
- const completeText = assistantText(message);
44729
- if (completeText !== null && completeText.length > 0) {
44730
- if (completeText.startsWith(state.text)) {
44731
- const suffix = completeText.slice(state.text.length);
44732
- if (suffix.length > 0) {
44733
- state.text += suffix;
44734
- events.push({ type: "text.delta", messageId, delta: suffix });
44735
- }
44736
- } else if (completeText !== state.text) {
44737
- this.#textConflict = true;
44738
- }
44739
- }
44740
- this.#consumeToolUseBlocks(message, events, false);
44741
- if (!this.#protocolConflict && !this.#textConflict) {
44742
- const usage = assistantRequestUsage(message, this.#provider);
44743
- state.usagePublished = usage !== void 0;
44744
- events.push({
44745
- type: "message.completed",
44746
- messageId,
44747
- ...checkpointId ? { checkpointId } : {},
44748
- ...usage ? { lastRequestUsage: usage } : {}
44749
- });
44750
- }
44751
- state.completed = true;
44752
- if (this.#activeRootStreamMessageId === messageId)
44753
- this.#activeRootStreamMessageId = null;
44754
- }
44755
- #consumeToolUseBlocks(message, events, ignoreKnownIds) {
44756
- for (const block of assistantContent(message) ?? []) {
44757
- if (!isRecord6(block) || block.type !== "tool_use")
44758
- continue;
44759
- const argumentsResult = jsonValueSchema.safeParse(block.input);
44760
- if (typeof block.id !== "string" || block.id.length === 0 || typeof block.name !== "string" || block.name.length === 0 || !argumentsResult.success) {
44761
- this.#protocolConflict = true;
44762
- continue;
44763
- }
44764
- if (this.#tools.has(block.id) || this.#completedToolIds.has(block.id)) {
44765
- if (!ignoreKnownIds)
44766
- this.#protocolConflict = true;
45096
+ function mergeClaudeModelPickerOptions(sdkModels, modelPicker) {
45097
+ if (!modelPicker)
45098
+ return sdkModels;
45099
+ const sdkRows = Array.isArray(sdkModels) ? [...sdkModels] : [];
45100
+ const sdkByValue = /* @__PURE__ */ new Map();
45101
+ for (const row of sdkRows) {
45102
+ const value = readModelValue(row);
45103
+ if (value && !sdkByValue.has(value))
45104
+ sdkByValue.set(value, row);
45105
+ }
45106
+ if (modelPicker.replaceBuiltInOptions) {
45107
+ const defaultSdk = sdkByValue.get("default");
45108
+ const merged2 = [
45109
+ defaultSdk !== void 0 ? defaultSdk : { value: "default", displayName: "Default" }
45110
+ ];
45111
+ const included2 = /* @__PURE__ */ new Set(["default"]);
45112
+ for (const option2 of modelPicker.options) {
45113
+ if (included2.has(option2.model)) {
45114
+ if (option2.model === "default") {
45115
+ merged2[0] = mergeOptionOntoSdkRow(merged2[0], option2);
45116
+ }
44767
45117
  continue;
44768
45118
  }
44769
- const subagent = SUBAGENT_TOOLS.has(block.name);
44770
- this.#tools.set(block.id, { name: block.name, subagent });
44771
- if (subagent) {
44772
- const prompt = subagentPrompt2(argumentsResult.data);
44773
- const role = subagentRole(argumentsResult.data);
44774
- const agentId = targetedSubagentId(argumentsResult.data);
44775
- events.push({
44776
- type: "subagent.started",
44777
- callId: block.id,
44778
- operation: block.name === "SendMessage" ? "send" : "spawn",
44779
- description: subagentDescription(argumentsResult.data, block.name),
44780
- ...prompt ? { prompt } : {},
44781
- ...role ? { role } : {},
44782
- background: block.name === "SendMessage" || subagentBackground(argumentsResult.data),
44783
- ...agentId ? { nativeSubagentId: agentId } : {}
44784
- });
44785
- } else {
44786
- events.push({
44787
- type: "tool.started",
44788
- callId: block.id,
44789
- toolName: block.name,
44790
- arguments: argumentsResult.data
44791
- });
44792
- }
45119
+ merged2.push(mergeOptionOntoSdkRow(sdkByValue.get(option2.model), option2));
45120
+ included2.add(option2.model);
44793
45121
  }
45122
+ return merged2;
44794
45123
  }
44795
- #consumeToolProgress(message, events) {
44796
- const callId = message.tool_use_id;
44797
- const elapsedSeconds = message.elapsed_time_seconds;
44798
- if (typeof callId !== "string" || this.#tools.get(callId)?.subagent !== false || typeof elapsedSeconds !== "number" || !Number.isFinite(elapsedSeconds) || elapsedSeconds < 0) {
44799
- return;
44800
- }
44801
- events.push({ type: "tool.progress", callId, elapsedMs: Math.round(elapsedSeconds * 1e3) });
45124
+ const merged = [...sdkRows];
45125
+ const included = new Set(sdkRows.flatMap((row) => {
45126
+ const value = readModelValue(row);
45127
+ return value ? [value] : [];
45128
+ }));
45129
+ for (const option2 of modelPicker.options) {
45130
+ if (included.has(option2.model))
45131
+ continue;
45132
+ merged.push(mergeOptionOntoSdkRow(void 0, option2));
45133
+ included.add(option2.model);
44802
45134
  }
44803
- #consumeTaskNotification(message, events) {
44804
- const settled = parseClaudeTaskNotification(message);
44805
- if (settled)
44806
- events.push(settled);
45135
+ return merged;
45136
+ }
45137
+ function uniqueDisplayLabels(rows) {
45138
+ const groups = /* @__PURE__ */ new Map();
45139
+ for (const row of rows) {
45140
+ const group = groups.get(row.displayName) ?? [];
45141
+ group.push(row);
45142
+ groups.set(row.displayName, group);
44807
45143
  }
44808
- #consumeToolResults(message, events, ignoreUnknown) {
44809
- if (!isRecord6(message.message) || !Array.isArray(message.message.content))
44810
- return;
44811
- const resultBlocks = message.message.content.filter((block) => isRecord6(block) && block.type === "tool_result");
44812
- if (resultBlocks.length === 0)
44813
- return;
44814
- if (resultBlocks.length > 1 && message.tool_use_result !== void 0) {
44815
- this.#protocolConflict = true;
44816
- }
44817
- for (const block of resultBlocks) {
44818
- const callId = block.tool_use_id;
44819
- if (typeof callId !== "string" || callId.length === 0) {
44820
- this.#protocolConflict = true;
44821
- continue;
44822
- }
44823
- const tool = this.#tools.get(callId);
44824
- if (!tool || this.#completedToolIds.has(callId)) {
44825
- if (!ignoreUnknown)
44826
- this.#protocolConflict = true;
44827
- continue;
44828
- }
44829
- if (block.is_error !== void 0 && typeof block.is_error !== "boolean") {
44830
- this.#protocolConflict = true;
44831
- continue;
44832
- }
44833
- this.#tools.delete(callId);
44834
- this.#completedToolIds.add(callId);
44835
- const isError = block.is_error === true;
44836
- const nativeResult = resultBlocks.length === 1 ? message.tool_use_result ?? message.toolUseResult : void 0;
44837
- const outputText = resultText(block.content, nativeResult);
44838
- const structuredResult = tool.name === "TaskCreate" || tool.name === "TaskUpdate" || tool.name === "TaskList" ? jsonValueSchema.safeParse(nativeResult) : null;
44839
- if (tool.subagent) {
44840
- const resultSummary = boundedString(outputText, SUBAGENT_SUMMARY_LIMIT);
44841
- const agentId = nativeSubagentId(nativeResult, outputText);
44842
- events.push({
44843
- type: "subagent.completed",
44844
- callId,
44845
- isError,
44846
- ...subagentContinuesInBackground(nativeResult, outputText) ? { continuesInBackground: true } : {},
44847
- ...agentId ? { nativeSubagentId: agentId } : {},
44848
- ...resultSummary ? { resultSummary } : {}
44849
- });
45144
+ const labels = /* @__PURE__ */ new Map();
45145
+ for (const [displayName, group] of groups) {
45146
+ const sorted = [...group].sort((left, right) => left.value.localeCompare(right.value));
45147
+ for (const [index, row] of sorted.entries()) {
45148
+ if (sorted.length === 1) {
45149
+ labels.set(row.value, displayName);
44850
45150
  continue;
44851
45151
  }
44852
- const fileChange = isError ? null : parseClaudeNativeFileChange(tool.name, nativeResult);
44853
- events.push({
44854
- type: "tool.completed",
44855
- callId,
44856
- toolName: tool.name,
44857
- ...outputText ? { outputText } : {},
44858
- ...structuredResult?.success ? { structuredResult: structuredResult.data } : {},
44859
- isError,
44860
- ...fileChange ? { fileChange } : {}
44861
- });
45152
+ const nativeSuffix = ` (${row.value})`;
45153
+ const suffix = displayName.length + nativeSuffix.length <= HARNESS_MODEL_LABEL_MAX_LENGTH ? nativeSuffix : ` (alias ${index + 1})`;
45154
+ labels.set(row.value, `${displayName.slice(0, HARNESS_MODEL_LABEL_MAX_LENGTH - suffix.length)}${suffix}`);
44862
45155
  }
44863
45156
  }
44864
- #messageState(messageId) {
44865
- const existing = this.#messages.get(messageId);
44866
- if (existing)
44867
- return existing;
44868
- const created = { completed: false, reasoning: "", text: "", usagePublished: false };
44869
- this.#messages.set(messageId, created);
44870
- return created;
45157
+ return labels;
45158
+ }
45159
+ function normalizeRows(value) {
45160
+ if (!Array.isArray(value))
45161
+ throw new Error("Claude Code Model catalog is not an array");
45162
+ const byValue = /* @__PURE__ */ new Map();
45163
+ for (const nativeRow of value) {
45164
+ const row = modelInfoSchema.parse(nativeRow);
45165
+ const existing = byValue.get(row.value);
45166
+ if (existing && JSON.stringify(existing) !== JSON.stringify(row)) {
45167
+ throw new Error("Claude Code Model catalog contains conflicting selectable values");
45168
+ }
45169
+ if (!existing)
45170
+ byValue.set(row.value, row);
44871
45171
  }
44872
- #nextMessageId() {
44873
- this.#messageOrdinal += 1;
44874
- return `claude-assistant-${this.#messageOrdinal}`;
45172
+ if (byValue.size === 0)
45173
+ throw new Error("Claude Code Model catalog is empty");
45174
+ if (!byValue.has("default")) {
45175
+ byValue.set("default", { value: "default", displayName: "Default" });
45176
+ }
45177
+ return [...byValue.values()];
45178
+ }
45179
+ function normalizeClaudeModelCatalog(snapshot) {
45180
+ if (!snapshot.canSelectModel)
45181
+ throw new Error("Claude Code Model selection is unavailable");
45182
+ const rows = normalizeRows(snapshot.models);
45183
+ const labels = uniqueDisplayLabels(rows);
45184
+ const models = rows.map((row) => {
45185
+ return {
45186
+ ref: encodeClaudeModelRef(row.value),
45187
+ label: labels.get(row.value) ?? row.displayName,
45188
+ ...row.resolvedModel ? { resolvedModelLabel: row.resolvedModel } : {},
45189
+ supportedThinkingOptionIds: [...CLAUDE_THINKING_OPTION_IDS]
45190
+ };
45191
+ });
45192
+ models.sort((left, right) => {
45193
+ if (left.ref.id === CLAUDE_DEFAULT_MODEL_REF.id)
45194
+ return -1;
45195
+ if (right.ref.id === CLAUDE_DEFAULT_MODEL_REF.id)
45196
+ return 1;
45197
+ return left.label.localeCompare(right.label) || left.ref.id.localeCompare(right.ref.id);
45198
+ });
45199
+ const catalog = harnessModelCatalogSchema.parse({
45200
+ models,
45201
+ defaultModel: CLAUDE_DEFAULT_MODEL_REF,
45202
+ thinkingOptions: [...CLAUDE_THINKING_OPTIONS],
45203
+ defaultThinkingOptionId: CLAUDE_DEFAULT_THINKING_OPTION_ID
45204
+ });
45205
+ return { catalog, defaultModel: CLAUDE_DEFAULT_MODEL_REF };
45206
+ }
45207
+
45208
+ // dist/permission-modes.js
45209
+ var nativePermissionModes = /* @__PURE__ */ new Set([
45210
+ "plan",
45211
+ "default",
45212
+ "acceptEdits",
45213
+ "auto",
45214
+ "bypassPermissions"
45215
+ ]);
45216
+ var CLAUDE_DEFAULT_PERMISSION_MODE_ID = harnessPermissionModeIdSchema.parse("default");
45217
+ var claudePermissionModes = [
45218
+ {
45219
+ id: "plan",
45220
+ label: "Plan mode",
45221
+ description: "Explore and prepare a plan; approval exits planning and resumes the previous permission mode."
45222
+ },
45223
+ {
45224
+ id: "default",
45225
+ label: "Default",
45226
+ description: "Ask before edits and other protected actions."
45227
+ },
45228
+ {
45229
+ id: "acceptEdits",
45230
+ label: "Accept edits",
45231
+ description: "Allow file edits and ask for other protected actions."
45232
+ },
45233
+ {
45234
+ id: "auto",
45235
+ label: "Auto mode",
45236
+ description: "Let Claude classify permission requests."
45237
+ },
45238
+ {
45239
+ id: "bypassPermissions",
45240
+ label: "Bypass permissions",
45241
+ description: "Skip Claude Code permission checks.",
45242
+ dangerous: true
44875
45243
  }
45244
+ ];
45245
+ function createPermissionModeCatalog(includeAuto, includeBypassPermissions) {
45246
+ return harnessPermissionModeCatalogSchema.parse({
45247
+ modes: claudePermissionModes.filter(({ id }) => (includeAuto || id !== "auto") && (includeBypassPermissions || id !== "bypassPermissions")),
45248
+ defaultModeId: CLAUDE_DEFAULT_PERMISSION_MODE_ID
45249
+ });
45250
+ }
45251
+ var CLAUDE_PERMISSION_MODE_CATALOG = createPermissionModeCatalog(true, true);
45252
+ var CLAUDE_PERMISSION_MODE_CATALOGS = {
45253
+ auto: CLAUDE_PERMISSION_MODE_CATALOG,
45254
+ autoWithoutBypass: createPermissionModeCatalog(true, false),
45255
+ withoutAuto: createPermissionModeCatalog(false, true),
45256
+ withoutAutoOrBypass: createPermissionModeCatalog(false, false)
44876
45257
  };
45258
+ var autoModeModelInfoSchema = external_exports.object({ supportsAutoMode: external_exports.literal(true) });
45259
+ function claudePermissionModeCatalogForModels(models, bypassPermissionsAvailable = true) {
45260
+ const supportsAutoMode = Array.isArray(models) && models.some((model) => autoModeModelInfoSchema.safeParse(model).success);
45261
+ if (supportsAutoMode) {
45262
+ return bypassPermissionsAvailable ? CLAUDE_PERMISSION_MODE_CATALOGS.auto : CLAUDE_PERMISSION_MODE_CATALOGS.autoWithoutBypass;
45263
+ }
45264
+ return bypassPermissionsAvailable ? CLAUDE_PERMISSION_MODE_CATALOGS.withoutAuto : CLAUDE_PERMISSION_MODE_CATALOGS.withoutAutoOrBypass;
45265
+ }
45266
+ function claudeBypassPermissionsAvailable(environment, platform = process) {
45267
+ const uid = platform.getuid?.();
45268
+ if (uid === void 0 || uid !== 0)
45269
+ return true;
45270
+ return environment.IS_SANDBOX === "1" || isNativeTruthyFlag(environment.CLAUDE_CODE_BUBBLEWRAP);
45271
+ }
45272
+ function isNativeTruthyFlag(value) {
45273
+ return ["1", "true", "yes", "on"].includes(value?.trim().toLowerCase() ?? "");
45274
+ }
45275
+ var CLAUDE_BYPASS_PERMISSIONS_UNAVAILABLE_MESSAGE = "Bypass permissions is unavailable because Claude Code runs as root without a declared sandbox; set IS_SANDBOX=1 for the codexhost Host and restart it";
45276
+ function decodeClaudePermissionModeId(permissionModeId) {
45277
+ const parsed = harnessPermissionModeIdSchema.parse(permissionModeId);
45278
+ if (!nativePermissionModes.has(parsed)) {
45279
+ throw new Error("Claude Code Permission Mode belongs to another Adapter");
45280
+ }
45281
+ return parsed;
45282
+ }
45283
+ function encodeClaudePermissionModeId(permissionMode) {
45284
+ if (!nativePermissionModes.has(permissionMode)) {
45285
+ throw new Error("Claude Code returned an unsupported Permission Mode");
45286
+ }
45287
+ return harnessPermissionModeIdSchema.parse(permissionMode);
45288
+ }
45289
+ function isClaudePermissionMode(value) {
45290
+ return typeof value === "string" && nativePermissionModes.has(value);
45291
+ }
45292
+
45293
+ // dist/sdk-transport.js
45294
+ import { spawn } from "node:child_process";
45295
+
45296
+ // dist/slash-commands.js
45297
+ var DYNAMIC_ID_PREFIX = "claude.slash.";
45298
+ var CLAUDE_EXCLUDED_COMMANDS = [
45299
+ "advisor",
45300
+ "agents",
45301
+ "design-consent",
45302
+ "design-revoke",
45303
+ "doctor",
45304
+ "extra-usage",
45305
+ "import",
45306
+ "team-onboarding",
45307
+ "ultrareview",
45308
+ "usage-credits",
45309
+ "workflow-launch-exec"
45310
+ ];
45311
+ function parseClaudeSlashCommands(value) {
45312
+ if (!Array.isArray(value))
45313
+ return [];
45314
+ return value.flatMap((entry) => {
45315
+ if (typeof entry !== "object" || entry === null)
45316
+ return [];
45317
+ const record2 = entry;
45318
+ const name = typeof record2.name === "string" ? record2.name.trim().replace(/^\//u, "") : "";
45319
+ if (!name)
45320
+ return [];
45321
+ return [
45322
+ {
45323
+ name,
45324
+ description: typeof record2.description === "string" ? record2.description : "",
45325
+ argumentHint: typeof record2.argumentHint === "string" ? record2.argumentHint : ""
45326
+ }
45327
+ ];
45328
+ });
45329
+ }
45330
+ function claudeLiveCommandCatalog(builtIns, snapshot) {
45331
+ return mergeLiveHarnessCommands(builtIns, DYNAMIC_ID_PREFIX, snapshot?.commands.map((command) => ({
45332
+ name: command.name,
45333
+ description: command.description,
45334
+ kind: snapshot.skillNames.has(command.name) ? "skill" : "command"
45335
+ })) ?? null, { names: CLAUDE_EXCLUDED_COMMANDS });
45336
+ }
45337
+ function claudeDynamicCommandPrompt(catalog, commandId, argumentText) {
45338
+ return liveHarnessCommandPrompt(catalog, DYNAMIC_ID_PREFIX, commandId, argumentText);
45339
+ }
45340
+
45341
+ // dist/account-usage.js
45342
+ function projectClaudeAccountUsage(usage, account) {
45343
+ if (!usage.rate_limits_available || !usage.rate_limits)
45344
+ return null;
45345
+ const limits = usage.rate_limits;
45346
+ const windows = [];
45347
+ const add = (product, periodType, value) => {
45348
+ if (!value || typeof value.utilization !== "number" || !Number.isFinite(value.utilization) || value.utilization < 0 || value.utilization > 100)
45349
+ return;
45350
+ windows.push({
45351
+ product,
45352
+ periodType,
45353
+ usagePercent: value.utilization,
45354
+ ...value.resets_at && Number.isFinite(Date.parse(value.resets_at)) ? { resetsAt: value.resets_at } : {}
45355
+ });
45356
+ };
45357
+ add("5-hour window", "five_hour", limits.five_hour);
45358
+ add("7-day window", "seven_day", limits.seven_day);
45359
+ add("OAuth apps · 7-day", "seven_day", limits.seven_day_oauth_apps);
45360
+ add("Opus · 7-day", "seven_day", limits.seven_day_opus);
45361
+ add("Sonnet · 7-day", "seven_day", limits.seven_day_sonnet);
45362
+ for (const window2 of limits.model_scoped ?? [])
45363
+ add(`${window2.display_name} · 7-day`, "seven_day", window2);
45364
+ const [primary, ...others] = windows;
45365
+ if (!primary)
45366
+ return null;
45367
+ const genericPrimary = primary.product === "5-hour window" || primary.product === "7-day window";
45368
+ return {
45369
+ ...account.email ? { email: account.email } : {},
45370
+ ...usage.subscription_type ? { plan: usage.subscription_type } : {},
45371
+ credits: {
45372
+ usedPercent: primary.usagePercent,
45373
+ periodType: primary.periodType,
45374
+ ...!genericPrimary ? { label: primary.product } : {},
45375
+ ...primary.resetsAt ? { resetsAt: primary.resetsAt } : {},
45376
+ ...others.length ? {
45377
+ productUsage: others.map(({ product, usagePercent, resetsAt }) => ({
45378
+ product,
45379
+ usagePercent,
45380
+ ...resetsAt ? { resetsAt } : {}
45381
+ }))
45382
+ } : {}
45383
+ }
45384
+ };
45385
+ }
44877
45386
 
44878
45387
  // dist/process-fence.js
44879
- import { execFile } from "node:child_process";
44880
- import path11 from "node:path";
45388
+ import { execFile as execFile2 } from "node:child_process";
45389
+ import path13 from "node:path";
44881
45390
  import { setTimeout as setTimeout2 } from "node:timers/promises";
44882
45391
  import { promisify } from "node:util";
44883
- var executeFile = promisify(execFile);
45392
+ var executeFile = promisify(execFile2);
44884
45393
  function signalGroup(pid, signal) {
44885
45394
  try {
44886
45395
  process.kill(-pid, signal);
@@ -44901,9 +45410,9 @@ async function closeClaudeProcessGroup(child, timeoutMs) {
44901
45410
  if (child.exitCode !== null || child.signalCode !== null)
44902
45411
  throw new Error("Claude process tree cannot be confirmed after its Windows root exited");
44903
45412
  const root = process.env.SystemRoot ?? process.env.SYSTEMROOT;
44904
- if (!root || !path11.win32.isAbsolute(root))
45413
+ if (!root || !path13.win32.isAbsolute(root))
44905
45414
  throw new Error("Windows SystemRoot is unavailable");
44906
- await executeFile(path11.win32.join(root, "System32", "taskkill.exe"), ["/PID", String(pid), "/T", "/F"], {
45415
+ await executeFile(path13.win32.join(root, "System32", "taskkill.exe"), ["/PID", String(pid), "/T", "/F"], {
44907
45416
  timeout: timeoutMs,
44908
45417
  windowsHide: true
44909
45418
  });
@@ -44984,9 +45493,6 @@ function rejectAfter(milliseconds, message) {
44984
45493
  }
44985
45494
  };
44986
45495
  }
44987
- function allowsDangerouslySkipPermissions(getuid = process.getuid) {
44988
- return getuid === void 0 || getuid() !== 0;
44989
- }
44990
45496
  function processExited(child) {
44991
45497
  return child.exitCode !== null || child.signalCode !== null;
44992
45498
  }
@@ -45124,6 +45630,9 @@ function canDeliverSettlementImmediately(event, pendingEvents) {
45124
45630
  if (event.type !== "subagent.settled")
45125
45631
  return false;
45126
45632
  return !pendingEvents.some((pending) => {
45633
+ if (pending.type === "tool.completed") {
45634
+ return event.callId !== void 0 && pending.callId === event.callId;
45635
+ }
45127
45636
  if (pending.type !== "subagent.started" && pending.type !== "subagent.updated" && pending.type !== "subagent.completed") {
45128
45637
  return false;
45129
45638
  }
@@ -45145,6 +45654,7 @@ var ClaudeSdkTransport = class {
45145
45654
  #onPlanLimit;
45146
45655
  #openMode;
45147
45656
  #permissionMode;
45657
+ #allowDangerouslySkipPermissions;
45148
45658
  #queryFactory;
45149
45659
  #thinkingOptionId;
45150
45660
  #active = null;
@@ -45177,6 +45687,7 @@ var ClaudeSdkTransport = class {
45177
45687
  this.#onPlanLimit = options.onPlanLimit;
45178
45688
  this.#openMode = options.openMode;
45179
45689
  this.#permissionMode = options.permissionMode;
45690
+ this.#allowDangerouslySkipPermissions = options.allowDangerouslySkipPermissions ?? false;
45180
45691
  this.#queryFactory = options.queryFactory ?? Okt;
45181
45692
  this.#thinkingOptionId = parseClaudeThinkingOptionId(options.thinkingOptionId);
45182
45693
  }
@@ -45219,7 +45730,7 @@ var ClaudeSdkTransport = class {
45219
45730
  pathToClaudeCodeExecutable: executable,
45220
45731
  settingSources: ["user"],
45221
45732
  permissionMode: this.#permissionMode,
45222
- ...allowsDangerouslySkipPermissions() ? { allowDangerouslySkipPermissions: true } : {},
45733
+ ...this.#allowDangerouslySkipPermissions ? { allowDangerouslySkipPermissions: true } : {},
45223
45734
  canUseTool: (toolName, input, options) => this.#canUseTool(toolName, input, options),
45224
45735
  persistSession: true,
45225
45736
  includePartialMessages: true,
@@ -45381,12 +45892,18 @@ var ClaudeSdkTransport = class {
45381
45892
  if (!active || !activeQuery)
45382
45893
  throw new Error("Claude SDK transport has no active Turn");
45383
45894
  active.accumulator.requestCancel();
45384
- const timeout = rejectAfter(this.#abortTimeoutMs, INTERRUPT_TIMEOUT_MESSAGE);
45385
45895
  try {
45386
- await Promise.race([activeQuery.interrupt(), timeout.promise]);
45896
+ await this.#stopRequest(activeQuery.interrupt(), INTERRUPT_TIMEOUT_MESSAGE);
45387
45897
  } catch (error52) {
45388
45898
  await this.close();
45389
45899
  throw error52 instanceof Error ? error52 : new Error(INTERRUPT_TIMEOUT_MESSAGE);
45900
+ }
45901
+ }
45902
+ /** A user stop must answer: native stop requests share the abort timeout. */
45903
+ async #stopRequest(request, timeoutMessage) {
45904
+ const timeout = rejectAfter(this.#abortTimeoutMs, timeoutMessage);
45905
+ try {
45906
+ await Promise.race([request, timeout.promise]);
45390
45907
  } finally {
45391
45908
  timeout.cancel();
45392
45909
  }
@@ -45518,6 +46035,15 @@ var ClaudeSdkTransport = class {
45518
46035
  if (failures.length > 0)
45519
46036
  throw new AggregateError(failures, "Claude SDK shutdown could not be confirmed");
45520
46037
  }
46038
+ hasBackgroundTasks() {
46039
+ return this.#backgroundTasks.size > 0;
46040
+ }
46041
+ /** The native `task_notification` that follows reports the stopped task. */
46042
+ async stopBackgroundTask(taskId) {
46043
+ if (!this.#query)
46044
+ throw new Error("Claude SDK transport is not running");
46045
+ await this.#stopRequest(this.#query.stopTask(taskId), "Claude background task stop timed out");
46046
+ }
45521
46047
  async #stopBackgroundTasks() {
45522
46048
  const requested = /* @__PURE__ */ new Set();
45523
46049
  const deadline = Date.now() + this.#closeTimeoutMs;
@@ -46029,6 +46555,146 @@ var ClaudeTaskTracker = class {
46029
46555
  }
46030
46556
  };
46031
46557
 
46558
+ // dist/background-command-items.js
46559
+ import { open as open2 } from "node:fs/promises";
46560
+ import { StringDecoder } from "node:string_decoder";
46561
+ var POLL_INTERVAL_MS = 1e3;
46562
+ var READ_CHUNK_BYTES = 64 * 1024;
46563
+ var UNAVAILABLE_OUTPUT = "Native output is unavailable.";
46564
+ function notificationOutcome(status) {
46565
+ if (status === "completed")
46566
+ return { status: "succeeded" };
46567
+ if (status === "failed") {
46568
+ return {
46569
+ status: "failed",
46570
+ error: {
46571
+ code: "nativeFailure",
46572
+ message: "Claude Code background command failed",
46573
+ retryable: false
46574
+ }
46575
+ };
46576
+ }
46577
+ return { status: "cancelled", reason: "Background command stopped" };
46578
+ }
46579
+ var ClaudeBackgroundCommandItems = class {
46580
+ /** Keyed by the Bash `tool_use` id. */
46581
+ #commands = /* @__PURE__ */ new Map();
46582
+ #emit;
46583
+ #outputLimit;
46584
+ constructor(options) {
46585
+ this.#emit = options.emit;
46586
+ this.#outputLimit = options.outputLimit;
46587
+ }
46588
+ taskIds() {
46589
+ return [...this.#commands.values()].map(({ command }) => command.taskId);
46590
+ }
46591
+ follow(command) {
46592
+ const followed = {
46593
+ command,
46594
+ outputFile: command.outputFile,
46595
+ offset: 0,
46596
+ decoder: new StringDecoder("utf8"),
46597
+ output: "",
46598
+ opened: false,
46599
+ truncated: false,
46600
+ timer: null,
46601
+ reading: Promise.resolve(),
46602
+ completed: false
46603
+ };
46604
+ this.#commands.set(command.callId, followed);
46605
+ if (followed.outputFile) {
46606
+ followed.timer = setInterval(() => void this.#poll(followed), POLL_INTERVAL_MS);
46607
+ followed.timer.unref();
46608
+ }
46609
+ }
46610
+ /** Returns whether the notification settles a followed command. */
46611
+ settle(notification) {
46612
+ const followed = notification.callId ? this.#commands.get(notification.callId) : void 0;
46613
+ if (!followed)
46614
+ return false;
46615
+ this.#commands.delete(followed.command.callId);
46616
+ if (followed.timer)
46617
+ clearInterval(followed.timer);
46618
+ followed.outputFile ??= notification.outputFile;
46619
+ void this.#poll(followed).then(() => this.#complete(followed, notificationOutcome(notification.status)));
46620
+ return true;
46621
+ }
46622
+ /** The native process is gone; no notification can arrive any more. */
46623
+ abandonAll(reason) {
46624
+ for (const followed of this.#commands.values()) {
46625
+ if (followed.timer)
46626
+ clearInterval(followed.timer);
46627
+ this.#complete(followed, { status: "cancelled", reason });
46628
+ }
46629
+ this.#commands.clear();
46630
+ }
46631
+ #poll(followed) {
46632
+ followed.reading = followed.reading.then(() => this.#read(followed));
46633
+ return followed.reading;
46634
+ }
46635
+ async #read(followed) {
46636
+ if (!followed.outputFile || followed.truncated)
46637
+ return;
46638
+ let handle;
46639
+ try {
46640
+ handle = await open2(followed.outputFile, "r");
46641
+ } catch {
46642
+ return;
46643
+ }
46644
+ followed.opened = true;
46645
+ try {
46646
+ const buffer = Buffer.alloc(READ_CHUNK_BYTES);
46647
+ for (; ; ) {
46648
+ const { bytesRead } = await handle.read(buffer, 0, buffer.length, followed.offset);
46649
+ if (bytesRead === 0)
46650
+ return;
46651
+ followed.offset += bytesRead;
46652
+ this.#append(followed, followed.decoder.write(buffer.subarray(0, bytesRead)));
46653
+ if (followed.truncated)
46654
+ return;
46655
+ }
46656
+ } catch {
46657
+ return;
46658
+ } finally {
46659
+ await handle.close().catch(() => void 0);
46660
+ }
46661
+ }
46662
+ #append(followed, text) {
46663
+ if (text.length === 0 || followed.completed)
46664
+ return;
46665
+ const room = this.#outputLimit - followed.output.length;
46666
+ const accepted = text.length > room ? text.slice(0, Math.max(0, room)) : text;
46667
+ if (text.length > room)
46668
+ followed.truncated = true;
46669
+ if (accepted.length === 0)
46670
+ return;
46671
+ followed.output += accepted;
46672
+ this.#emit({
46673
+ type: "item.updated",
46674
+ turnId: followed.command.turnId,
46675
+ itemId: followed.command.item.itemId,
46676
+ update: { type: "output.append", text: accepted }
46677
+ });
46678
+ }
46679
+ #complete(followed, outcome) {
46680
+ const { command } = followed;
46681
+ followed.completed = true;
46682
+ const output = followed.output.length > 0 ? followed.output : followed.opened ? void 0 : UNAVAILABLE_OUTPUT;
46683
+ this.#emit({
46684
+ type: "item.completed",
46685
+ turnId: command.turnId,
46686
+ snapshot: {
46687
+ item: {
46688
+ ...command.item,
46689
+ ...output !== void 0 ? { output, outputTruncated: followed.truncated } : {},
46690
+ durationMs: Math.max(0, Date.now() - command.startedAtMs)
46691
+ },
46692
+ outcome
46693
+ }
46694
+ });
46695
+ }
46696
+ };
46697
+
46032
46698
  // dist/tool-lifecycle.js
46033
46699
  function isRecord9(value) {
46034
46700
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -46059,15 +46725,20 @@ var ClaudeToolLifecycle = class {
46059
46725
  #cwd;
46060
46726
  #emit;
46061
46727
  #newItemId;
46728
+ #onDetached;
46062
46729
  #outputLimit;
46063
46730
  #taskTracker;
46731
+ #nativeTurnKey;
46064
46732
  #tools = /* @__PURE__ */ new Map();
46733
+ #toolOrdinal = 0;
46065
46734
  constructor(options) {
46066
46735
  this.#cwd = options.cwd;
46067
46736
  this.#emit = options.emit;
46068
46737
  this.#newItemId = options.newItemId;
46738
+ this.#onDetached = options.onDetached;
46069
46739
  this.#outputLimit = options.outputLimit;
46070
46740
  this.#taskTracker = options.taskTracker;
46741
+ this.#nativeTurnKey = options.nativeTurnKey;
46071
46742
  }
46072
46743
  get size() {
46073
46744
  return this.#tools.size;
@@ -46075,15 +46746,16 @@ var ClaudeToolLifecycle = class {
46075
46746
  start(turnId, event) {
46076
46747
  if (this.#tools.has(event.callId))
46077
46748
  throw new Error("Claude Code Tool started more than once");
46749
+ const itemId = claudeTranscriptItemId(this.#nativeTurnKey, "tool", this.#toolOrdinal += 1);
46078
46750
  const command = event.toolName === "Bash" ? stringField2(event.arguments, "command") : void 0;
46079
46751
  const item = command ? {
46080
46752
  type: "commandExecution",
46081
- itemId: this.#newItemId(),
46753
+ itemId,
46082
46754
  command,
46083
46755
  cwd: this.#cwd
46084
46756
  } : {
46085
46757
  type: "toolExecution",
46086
- itemId: this.#newItemId(),
46758
+ itemId,
46087
46759
  toolName: isClaudeTaskTool(event.toolName) ? "Todo" : event.toolName,
46088
46760
  arguments: isClaudeTaskTool(event.toolName) ? {} : event.arguments
46089
46761
  };
@@ -46108,6 +46780,18 @@ var ClaudeToolLifecycle = class {
46108
46780
  throw new Error("Claude Code Tool completion references an unknown Tool");
46109
46781
  }
46110
46782
  this.#tools.delete(event.callId);
46783
+ if (tool.item.type === "commandExecution" && event.backgroundTaskId && !event.isError && !cancellationRequested) {
46784
+ this.#emit({ type: "item.detached", turnId, itemId: tool.item.itemId });
46785
+ this.#onDetached({
46786
+ turnId,
46787
+ callId: event.callId,
46788
+ taskId: event.backgroundTaskId,
46789
+ item: tool.item,
46790
+ startedAtMs: tool.startedAtMs,
46791
+ ...event.backgroundOutputFile ? { outputFile: event.backgroundOutputFile } : {}
46792
+ });
46793
+ return;
46794
+ }
46111
46795
  const output = boundedToolOutput(event.outputText, this.#outputLimit);
46112
46796
  const durationMs = Math.max(tool.elapsedMs, Date.now() - tool.startedAtMs, 0);
46113
46797
  if (tool.item.type === "commandExecution") {
@@ -46361,6 +47045,37 @@ function faultError() {
46361
47045
  retryable: true
46362
47046
  };
46363
47047
  }
47048
+ function claudePermissionModeSelectionFailure(permissionMode, error52) {
47049
+ const nativeMessage = error52 instanceof Error ? error52.message.toLowerCase() : "";
47050
+ if (permissionMode === "auto" && nativeMessage.includes("auto mode unavailable")) {
47051
+ return {
47052
+ code: "nativeFailure",
47053
+ message: "Auto mode is unavailable for the current Claude Code Model",
47054
+ retryable: true
47055
+ };
47056
+ }
47057
+ if (permissionMode === "bypassPermissions") {
47058
+ if (nativeMessage.includes("not launched with --dangerously-skip-permissions")) {
47059
+ return {
47060
+ code: "nativeFailure",
47061
+ message: "Claude Code started this Session without bypass permissions support; when running as root, set IS_SANDBOX=1 for the codexhost Host, restart it, and reopen the Session",
47062
+ retryable: false
47063
+ };
47064
+ }
47065
+ if (nativeMessage.includes("disabled by settings or configuration")) {
47066
+ return {
47067
+ code: "nativeFailure",
47068
+ message: "Bypass permissions is disabled by Claude Code settings (permissions.disableBypassPermissionsMode) or organization policy",
47069
+ retryable: false
47070
+ };
47071
+ }
47072
+ }
47073
+ return {
47074
+ code: "nativeFailure",
47075
+ message: "Claude Code rejected the Permission Mode selection",
47076
+ retryable: true
47077
+ };
47078
+ }
46364
47079
  function delay2(milliseconds) {
46365
47080
  return new Promise((resolve2) => setTimeout(resolve2, milliseconds));
46366
47081
  }
@@ -46432,6 +47147,7 @@ var ClaudeHarnessSession = class {
46432
47147
  #cancelTimeoutMs;
46433
47148
  #closeTimeoutMs;
46434
47149
  #createTransport;
47150
+ #bypassPermissionsAvailable;
46435
47151
  #cwd;
46436
47152
  #nativeRef;
46437
47153
  #onClosed;
@@ -46448,6 +47164,7 @@ var ClaudeHarnessSession = class {
46448
47164
  #readSessionMessages;
46449
47165
  #sessionId;
46450
47166
  #toolOutputLimit;
47167
+ #backgroundCommands;
46451
47168
  #continuationQuiescenceMs;
46452
47169
  #taskTracker = new ClaudeTaskTracker();
46453
47170
  #acceptingTurn = false;
@@ -46482,6 +47199,7 @@ var ClaudeHarnessSession = class {
46482
47199
  this.#pendingSessions = options.pendingSessions;
46483
47200
  const environment = options.environment;
46484
47201
  this.#createTransport = environment ? (input) => dependencies.createTransport({ ...input, environment }) : dependencies.createTransport;
47202
+ this.#bypassPermissionsAvailable = options.bypassPermissionsAvailable;
46485
47203
  this.#randomUUID = dependencies.randomUUID;
46486
47204
  this.#readSessionMessages = dependencies.readSessionMessages;
46487
47205
  this.#cancelTimeoutMs = options.cancelTimeoutMs;
@@ -46494,6 +47212,10 @@ var ClaudeHarnessSession = class {
46494
47212
  this.#requestedThinkingOptionId = options.requestedThinkingOptionId;
46495
47213
  this.#sessionId = options.sessionId;
46496
47214
  this.#toolOutputLimit = options.toolOutputLimit;
47215
+ this.#backgroundCommands = new ClaudeBackgroundCommandItems({
47216
+ outputLimit: options.toolOutputLimit,
47217
+ emit: (event) => this.#event(event)
47218
+ });
46497
47219
  this.#continuationQuiescenceMs = options.continuationQuiescenceMs;
46498
47220
  this.#nativeRef = options.nativeRef ?? nativeSessionRefSchema.parse({
46499
47221
  harnessId: this.harnessId,
@@ -46695,8 +47417,10 @@ var ClaudeHarnessSession = class {
46695
47417
  cwd: this.#cwd,
46696
47418
  outputLimit: this.#toolOutputLimit,
46697
47419
  taskTracker: this.#taskTracker,
47420
+ nativeTurnKey,
46698
47421
  newItemId: () => hostItemIdSchema.parse(this.#randomUUID()),
46699
- emit: (event) => this.#event(event)
47422
+ emit: (event) => this.#event(event),
47423
+ onDetached: (command2) => this.#backgroundCommands.follow(command2)
46700
47424
  }),
46701
47425
  interactions: /* @__PURE__ */ new Map(),
46702
47426
  interactionByRequestId: /* @__PURE__ */ new Map(),
@@ -46806,8 +47530,10 @@ var ClaudeHarnessSession = class {
46806
47530
  cwd: this.#cwd,
46807
47531
  outputLimit: this.#toolOutputLimit,
46808
47532
  taskTracker: this.#taskTracker,
47533
+ nativeTurnKey,
46809
47534
  newItemId: () => hostItemIdSchema.parse(this.#randomUUID()),
46810
- emit: (event) => this.#event(event)
47535
+ emit: (event) => this.#event(event),
47536
+ onDetached: (command2) => this.#backgroundCommands.follow(command2)
46811
47537
  }),
46812
47538
  interactions: /* @__PURE__ */ new Map(),
46813
47539
  interactionByRequestId: /* @__PURE__ */ new Map(),
@@ -46840,6 +47566,28 @@ var ClaudeHarnessSession = class {
46840
47566
  }
46841
47567
  return { ok: true, value: { turnId: command.turnId } };
46842
47568
  }
47569
+ /** Closing the native process stops its background tasks, so they keep the Session. */
47570
+ hasBackgroundWork() {
47571
+ return this.#transport?.hasBackgroundTasks() ?? false;
47572
+ }
47573
+ async stopBackgroundWork() {
47574
+ const transport = this.#transport;
47575
+ if (!transport)
47576
+ return { ok: true, value: void 0 };
47577
+ try {
47578
+ await Promise.all(this.#backgroundCommands.taskIds().map((taskId) => transport.stopBackgroundTask(taskId)));
47579
+ return { ok: true, value: void 0 };
47580
+ } catch (error52) {
47581
+ return {
47582
+ ok: false,
47583
+ error: {
47584
+ code: "nativeFailure",
47585
+ message: error52 instanceof Error ? error52.message : String(error52),
47586
+ retryable: true
47587
+ }
47588
+ };
47589
+ }
47590
+ }
46843
47591
  refreshUsage() {
46844
47592
  if (this.#phase !== "open" || !this.#transport)
46845
47593
  return Promise.resolve();
@@ -47001,6 +47749,21 @@ var ClaudeHarnessSession = class {
47001
47749
  }
47002
47750
  };
47003
47751
  }
47752
+ let permissionModeId = command.permissionModeId;
47753
+ if (permissionMode === "bypassPermissions" && !this.#bypassPermissionsAvailable) {
47754
+ if (this.#transport || this.#startupTask) {
47755
+ return {
47756
+ ok: false,
47757
+ error: {
47758
+ code: "unsupported",
47759
+ message: CLAUDE_BYPASS_PERMISSIONS_UNAVAILABLE_MESSAGE,
47760
+ retryable: false
47761
+ }
47762
+ };
47763
+ }
47764
+ permissionMode = "default";
47765
+ permissionModeId = CLAUDE_DEFAULT_PERMISSION_MODE_ID;
47766
+ }
47004
47767
  this.#usageGeneration += 1;
47005
47768
  this.#contextUsageFreshUntilMs = 0;
47006
47769
  this.#contextUsageCooldownUntilMs = 0;
@@ -47014,18 +47777,13 @@ var ClaudeHarnessSession = class {
47014
47777
  try {
47015
47778
  await transport.setPermissionMode(permissionMode);
47016
47779
  } catch (error52) {
47017
- const nativeMessage = error52 instanceof Error ? error52.message.toLowerCase() : "";
47018
47780
  return {
47019
47781
  ok: false,
47020
- error: {
47021
- code: "nativeFailure",
47022
- message: permissionMode === "auto" && nativeMessage.includes("auto mode unavailable") ? "Auto mode is unavailable for the current Claude Code Model" : "Claude Code rejected the Permission Mode selection",
47023
- retryable: true
47024
- }
47782
+ error: claudePermissionModeSelectionFailure(permissionMode, error52)
47025
47783
  };
47026
47784
  }
47027
47785
  }
47028
- this.#requestedPermissionModeId = transport ? encodeClaudePermissionModeId(transport.getPermissionMode()) : command.permissionModeId;
47786
+ this.#requestedPermissionModeId = transport ? encodeClaudePermissionModeId(transport.getPermissionMode()) : permissionModeId;
47029
47787
  const persistenceError = await this.#savePendingConfiguration();
47030
47788
  if (persistenceError)
47031
47789
  return { ok: false, error: persistenceError };
@@ -47195,6 +47953,7 @@ var ClaudeHarnessSession = class {
47195
47953
  const active = this.#active;
47196
47954
  if (active)
47197
47955
  this.#finishFailed(active, invalidState("Claude Code Session closed during active Turn"));
47956
+ this.#backgroundCommands.abandonAll("Claude Code Session closed");
47198
47957
  this.#phase = "closed";
47199
47958
  this.#channel.end();
47200
47959
  this.#onClosed();
@@ -47235,6 +47994,7 @@ var ClaudeHarnessSession = class {
47235
47994
  ...model ? { model } : {},
47236
47995
  thinkingOptionId: this.#requestedThinkingOptionId,
47237
47996
  permissionMode,
47997
+ allowDangerouslySkipPermissions: this.#bypassPermissionsAvailable,
47238
47998
  onPermissionModeChanged: (mode) => this.#handlePermissionModeChanged(mode),
47239
47999
  onFault: () => this.#fault(faultError()),
47240
48000
  onPlanLimit: (planLimit) => this.#handlePlanLimit(planLimit)
@@ -47242,9 +48002,8 @@ var ClaudeHarnessSession = class {
47242
48002
  this.#transport = transport;
47243
48003
  transport.setAutonomousTurnHandler((turn) => this.#handleAutonomousTurn(turn));
47244
48004
  transport.setThreadEventHandler((event) => {
47245
- if (event.type === "subagent.settled") {
47246
- this.#settleBackgroundSubagent(event.status, event.nativeSubagentId, event.callId, event.resultSummary);
47247
- }
48005
+ if (event.type === "subagent.settled")
48006
+ this.#settleNativeTask(event);
47248
48007
  });
47249
48008
  transport.setIdleTurnHandler({
47250
48009
  onEvent: (event) => {
@@ -47253,9 +48012,8 @@ var ClaudeHarnessSession = class {
47253
48012
  this.#handleTurnEvent(active, event);
47254
48013
  return;
47255
48014
  }
47256
- if (event.type === "subagent.settled") {
47257
- this.#settleBackgroundSubagent(event.status, event.nativeSubagentId, event.callId, event.resultSummary);
47258
- }
48015
+ if (event.type === "subagent.settled")
48016
+ this.#settleNativeTask(event);
47259
48017
  },
47260
48018
  onTerminal: (result) => {
47261
48019
  const active = this.#active;
@@ -47435,7 +48193,7 @@ var ClaudeHarnessSession = class {
47435
48193
  return;
47436
48194
  }
47437
48195
  case "subagent.settled":
47438
- this.#settleBackgroundSubagent(event.status, event.nativeSubagentId, event.callId, event.resultSummary);
48196
+ this.#settleNativeTask(event);
47439
48197
  return;
47440
48198
  case "subagent.transcript.changed": {
47441
48199
  const nativeSubagentId2 = active.subagents.nativeSubagentId(event.callId);
@@ -47702,8 +48460,10 @@ var ClaudeHarnessSession = class {
47702
48460
  cwd: this.#cwd,
47703
48461
  outputLimit: this.#toolOutputLimit,
47704
48462
  taskTracker: this.#taskTracker,
48463
+ nativeTurnKey,
47705
48464
  newItemId: () => hostItemIdSchema.parse(this.#randomUUID()),
47706
- emit: (event) => this.#event(event)
48465
+ emit: (event) => this.#event(event),
48466
+ onDetached: (command) => this.#backgroundCommands.follow(command)
47707
48467
  }),
47708
48468
  interactions: /* @__PURE__ */ new Map(),
47709
48469
  interactionByRequestId: /* @__PURE__ */ new Map(),
@@ -47741,6 +48501,15 @@ var ClaudeHarnessSession = class {
47741
48501
  this.#handleTurnEvent(active, event);
47742
48502
  this.#finishResult(active, turn.result);
47743
48503
  }
48504
+ /**
48505
+ * A native `task_notification` names the tool call that started its task: a
48506
+ * followed background command settles here, anything else is a Subagent.
48507
+ */
48508
+ #settleNativeTask(event) {
48509
+ if (this.#backgroundCommands.settle(event))
48510
+ return;
48511
+ this.#settleBackgroundSubagent(event.status, event.nativeSubagentId, event.callId, event.resultSummary);
48512
+ }
47744
48513
  #settleBackgroundSubagent(status, nativeSubagentId2, callId, resultSummary) {
47745
48514
  this.#occupancy.notify(callId, nativeSubagentId2);
47746
48515
  const active = this.#active;
@@ -48130,6 +48899,7 @@ var ClaudeHarnessSession = class {
48130
48899
  const active = this.#active;
48131
48900
  if (active)
48132
48901
  this.#finishFailed(active, error52);
48902
+ this.#backgroundCommands.abandonAll("Claude Code Session faulted");
48133
48903
  this.#phase = "faulted";
48134
48904
  this.#event({ type: "session.faulted", error: error52 });
48135
48905
  this.#channel.end();
@@ -48145,22 +48915,10 @@ var ClaudeCodeAdapter = class {
48145
48915
  harnessId = claudeCodeHarnessId2;
48146
48916
  sessionImport = Object.freeze({
48147
48917
  listCandidates: async () => {
48148
- const result = await this.#readImport((signal) => this.#importIndex.list(signal));
48918
+ const result = await this.#importScope.read((signal) => this.#importIndex.list(signal));
48149
48919
  return result.ok ? { ok: true, value: result.value.map(({ candidate }) => candidate) } : result;
48150
48920
  },
48151
- resolveCandidate: async (nativeSessionId) => {
48152
- const result = await this.#readImport((signal) => this.#importIndex.resolve(nativeSessionId, signal));
48153
- if (!result.ok)
48154
- return result;
48155
- return result.value ? { ok: true, value: result.value } : {
48156
- ok: false,
48157
- error: {
48158
- code: "sessionNotFound",
48159
- message: "Claude Code Session is no longer importable",
48160
- retryable: false
48161
- }
48162
- };
48163
- }
48921
+ resolveCandidate: (nativeSessionId) => this.#importScope.resolve((signal) => this.#importIndex.resolve(nativeSessionId, signal))
48164
48922
  });
48165
48923
  subagents = {
48166
48924
  readSnapshot: async (input) => {
@@ -48205,9 +48963,12 @@ var ClaudeCodeAdapter = class {
48205
48963
  #cancelTimeoutMs;
48206
48964
  #closeTimeoutMs;
48207
48965
  #dependencies;
48208
- #importAbort = new AbortController();
48209
48966
  #importIndex;
48210
- #importRequests = /* @__PURE__ */ new Set();
48967
+ #importScope = new SessionImportScope({
48968
+ closedMessage: "Claude Code Adapter is closed",
48969
+ unavailableMessage: "Claude Code Session discovery failed; check storage access and duplicate Session identities, then retry after closing native clients",
48970
+ notFoundMessage: "Claude Code Session is no longer importable"
48971
+ });
48211
48972
  #pendingSessions;
48212
48973
  #toolOutputLimit;
48213
48974
  #continuationQuiescenceMs;
@@ -48237,6 +48998,7 @@ var ClaudeCodeAdapter = class {
48237
48998
  }
48238
48999
  this.#dependencies = dependencies ?? {
48239
49000
  randomUUID: randomUUID3,
49001
+ bypassPermissionsAvailable: (environment2) => claudeBypassPermissionsAvailable(environment2 ?? options.environment ?? process.env),
48240
49002
  inspectInstallation: () => {
48241
49003
  resolveClaudeCodeExecutable({
48242
49004
  ...options.command ? { command: options.command } : {},
@@ -48275,24 +49037,6 @@ var ClaudeCodeAdapter = class {
48275
49037
  readSubagentMessages: ({ cwd, sessionId, nativeSubagentId: nativeSubagentId2 }) => jkt(sessionId, nativeSubagentId2, { dir: cwd })
48276
49038
  };
48277
49039
  }
48278
- #readImport(operation) {
48279
- if (this.#importAbort.signal.aborted) {
48280
- return Promise.resolve({
48281
- ok: false,
48282
- error: invalidState("Claude Code Adapter is closed")
48283
- });
48284
- }
48285
- const request = operation(this.#importAbort.signal).then((value) => ({ ok: true, value })).catch(() => ({
48286
- ok: false,
48287
- error: {
48288
- code: "unavailable",
48289
- message: "Claude Code Session discovery failed; check storage access and duplicate Session identities, then retry after closing native clients",
48290
- retryable: true
48291
- }
48292
- })).finally(() => this.#importRequests.delete(request));
48293
- this.#importRequests.add(request);
48294
- return request;
48295
- }
48296
49040
  async inspect(input = {}) {
48297
49041
  if (this.#closePromise) {
48298
49042
  return {
@@ -48300,7 +49044,7 @@ var ClaudeCodeAdapter = class {
48300
49044
  error: invalidState("Claude Code Adapter is closing")
48301
49045
  };
48302
49046
  }
48303
- const cwd = path12.resolve(input.cwd ?? process.cwd());
49047
+ const cwd = path14.resolve(input.cwd ?? process.cwd());
48304
49048
  if (!input.refresh) {
48305
49049
  const cached2 = this.#inspectionCache.get(cwd);
48306
49050
  if (cached2)
@@ -48359,7 +49103,7 @@ var ClaudeCodeAdapter = class {
48359
49103
  this.#inspectors.add(inspector);
48360
49104
  stage = "model-catalog";
48361
49105
  const snapshot = await inspector.inspect();
48362
- const permissionModes = snapshot.canSelectPermissionMode ? claudePermissionModeCatalogForModels(snapshot.models) : void 0;
49106
+ const permissionModes = snapshot.canSelectPermissionMode ? claudePermissionModeCatalogForModels(snapshot.models, this.#dependencies.bypassPermissionsAvailable()) : void 0;
48363
49107
  if (!snapshot.canSelectModel) {
48364
49108
  return {
48365
49109
  status: "unavailable",
@@ -48481,7 +49225,21 @@ var ClaudeCodeAdapter = class {
48481
49225
  }
48482
49226
  };
48483
49227
  }
48484
- const cwd = path12.resolve(input.cwd);
49228
+ const bypassPermissionsAvailable = this.#dependencies.bypassPermissionsAvailable(input.environment);
49229
+ if (!bypassPermissionsAvailable && requestedPermissionModeId === "bypassPermissions") {
49230
+ if (input.kind === "create") {
49231
+ return {
49232
+ ok: false,
49233
+ error: {
49234
+ code: "unsupported",
49235
+ message: CLAUDE_BYPASS_PERMISSIONS_UNAVAILABLE_MESSAGE,
49236
+ retryable: false
49237
+ }
49238
+ };
49239
+ }
49240
+ requestedPermissionModeId = CLAUDE_DEFAULT_PERMISSION_MODE_ID;
49241
+ }
49242
+ const cwd = path14.resolve(input.cwd);
48485
49243
  if (input.kind === "rollbackLastTurn") {
48486
49244
  for (const source of this.#sessions) {
48487
49245
  const ready = await source.prepareRollback(input.sourceRef.nativeSessionId);
@@ -48540,7 +49298,10 @@ var ClaudeCodeAdapter = class {
48540
49298
  decodeClaudePermissionModeId(pending.configuration.effectivePermissionModeId);
48541
49299
  requestedModel = pending.configuration.effectiveModel ?? requestedModel;
48542
49300
  requestedThinkingOptionId = pending.configuration.effectiveThinkingOptionId ?? requestedThinkingOptionId;
48543
- requestedPermissionModeId = input.kind === "resume" && input.permissionModeId ? input.permissionModeId : pending.configuration.effectivePermissionModeId ?? requestedPermissionModeId;
49301
+ requestedPermissionModeId = input.kind === "resume" && input.permissionModeId ? requestedPermissionModeId : pending.configuration.effectivePermissionModeId ?? requestedPermissionModeId;
49302
+ if (!bypassPermissionsAvailable && requestedPermissionModeId === "bypassPermissions") {
49303
+ requestedPermissionModeId = CLAUDE_DEFAULT_PERMISSION_MODE_ID;
49304
+ }
48544
49305
  } catch {
48545
49306
  return {
48546
49307
  ok: false,
@@ -48554,6 +49315,7 @@ var ClaudeCodeAdapter = class {
48554
49315
  }
48555
49316
  const session = new ClaudeHarnessSession(cwd, this.#dependencies, this.#closeTimeoutMs, () => this.#sessions.delete(session), (planLimit) => this.#recordPlanLimit(session, planLimit), {
48556
49317
  ...input.environment ? { environment: input.environment } : {},
49318
+ bypassPermissionsAvailable,
48557
49319
  openMode,
48558
49320
  pendingSessions: this.#pendingSessions,
48559
49321
  knownConfiguration: input.kind === "rollbackLastTurn" || input.kind === "resume" && Boolean(input.model || input.thinkingOptionId) || Boolean(durableRef && isPendingClaudeSession(durableRef)),
@@ -48590,10 +49352,9 @@ var ClaudeCodeAdapter = class {
48590
49352
  }
48591
49353
  close() {
48592
49354
  if (!this.#closePromise) {
48593
- this.#importAbort.abort();
48594
49355
  this.#inspectionCache.clear();
48595
49356
  this.#closePromise = Promise.all([
48596
- ...this.#importRequests,
49357
+ this.#importScope.close(),
48597
49358
  ...[...this.#inspectors].map((inspector) => inspector.close()),
48598
49359
  ...[...this.#sessions].map((session) => session.close()),
48599
49360
  ...this.#inspectionInFlight.values()
@@ -48603,9 +49364,75 @@ var ClaudeCodeAdapter = class {
48603
49364
  }
48604
49365
  };
48605
49366
 
49367
+ // dist/installation.js
49368
+ import { readFile as readFile6, realpath as realpath3 } from "node:fs/promises";
49369
+ import { homedir as homedir2 } from "node:os";
49370
+ import path15 from "node:path";
49371
+ async function readSettings(file2) {
49372
+ const text = await readFile6(file2, "utf8").catch((error52) => {
49373
+ if (error52.code === "ENOENT")
49374
+ return "{}";
49375
+ throw error52;
49376
+ });
49377
+ const settings = JSON.parse(text);
49378
+ if (!settings || typeof settings !== "object" || Array.isArray(settings))
49379
+ throw new Error("Claude update settings are invalid");
49380
+ return settings;
49381
+ }
49382
+ function createClaudeInstallation(environment, command) {
49383
+ let update;
49384
+ return createInstallationManager({
49385
+ async check() {
49386
+ const executable = resolveClaudeCodeExecutable({
49387
+ environment,
49388
+ ...command ? { command } : {}
49389
+ });
49390
+ const home = environment.HOME ?? environment.USERPROFILE ?? homedir2();
49391
+ const config2 = environment.CLAUDE_CONFIG_DIR ? path15.resolve(home, environment.CLAUDE_CONFIG_DIR) : path15.join(home, ".claude");
49392
+ const managedFile = process.platform === "darwin" ? "/Library/Application Support/ClaudeCode/managed-settings.json" : process.platform === "win32" ? path15.join(environment.ProgramFiles ?? "C:\\Program Files", "ClaudeCode", "managed-settings.json") : "/etc/claude-code/managed-settings.json";
49393
+ const user = await readSettings(path15.join(config2, "settings.json"));
49394
+ const managed = await readSettings(managedFile);
49395
+ const settings = { ...user, ...managed, env: { ...user.env, ...managed.env } };
49396
+ const env = { ...environment, ...settings.env };
49397
+ const currentVersion = versionFromOutput(await runInstallationCommand(executable, ["--version"], {
49398
+ ...env,
49399
+ DISABLE_AUTOUPDATER: "1"
49400
+ }));
49401
+ const channel = settings.autoUpdatesChannel ?? "latest";
49402
+ if (channel !== "latest" && channel !== "stable")
49403
+ throw new Error("Unknown Claude release channel");
49404
+ const latestVersion = installationVersion(await fetchInstallationText(`https://downloads.claude.ai/claude-code-releases/${channel}`));
49405
+ const npm = await npmInstallation(executable, ["@anthropic-ai/claude-code"], env);
49406
+ const launcher = path15.join(home, ".local", "bin", process.platform === "win32" ? "claude.exe" : "claude");
49407
+ const selected = await realpath3(executable);
49408
+ const versions = path15.join(home, ".local", "share", "claude", "versions") + path15.sep;
49409
+ const native = path15.resolve(executable) === launcher && (selected.startsWith(versions) || process.platform === "win32" && selected === launcher);
49410
+ const blocked = !!env.DISABLE_UPDATES && env.DISABLE_UPDATES !== "0" || !!settings.minimumVersion && newerInstallationVersion(latestVersion, installationVersion(settings.minimumVersion)) || !!settings.requiredMaximumVersion && newerInstallationVersion(installationVersion(settings.requiredMaximumVersion), latestVersion);
49411
+ const canUpdate = !blocked && (npm?.canUpdate ?? native);
49412
+ update = async () => {
49413
+ const updateEnv = npm ? { ...env, npm_config_prefix: npm.prefix, NPM_CONFIG_PREFIX: npm.prefix } : env;
49414
+ await runInstallationCommand(executable, ["update"], updateEnv, 3e5);
49415
+ };
49416
+ return {
49417
+ currentVersion,
49418
+ latestVersion,
49419
+ updateAvailable: newerInstallationVersion(currentVersion, latestVersion),
49420
+ canUpdate,
49421
+ ...!canUpdate ? {
49422
+ messageCode: blocked ? "claude-policy-restricted" : "original-installer",
49423
+ message: blocked ? "Claude updates are restricted by the installation's settings or policy." : "Use the original installer or package manager for this Claude installation."
49424
+ } : {}
49425
+ };
49426
+ },
49427
+ async update() {
49428
+ await update();
49429
+ }
49430
+ });
49431
+ }
49432
+
48606
49433
  // dist/user-shell-environment.js
48607
- import path13 from "node:path";
48608
- import { execFile as execFile2 } from "node:child_process";
49434
+ import path16 from "node:path";
49435
+ import { execFile as execFile3 } from "node:child_process";
48609
49436
  var ENVIRONMENT_MARKER = Buffer.from("\0CODEXHOST_USER_SHELL_ENV_V1\0");
48610
49437
  var ENVIRONMENT_COMMAND = "printf '\\0CODEXHOST_USER_SHELL_ENV_V1\\0'; /usr/bin/env -0";
48611
49438
  var SHELL_ENVIRONMENT_TIMEOUT_MS = 3e3;
@@ -48647,14 +49474,14 @@ async function withUserShellEnvironment(environment, dependencies) {
48647
49474
  if (platform === "win32" || !environment.HOME)
48648
49475
  return environment;
48649
49476
  const shell = environment.SHELL?.trim() || defaultShell(platform);
48650
- if (!shell || !SUPPORTED_SHELLS.has(path13.basename(shell)))
49477
+ if (!shell || !SUPPORTED_SHELLS.has(path16.basename(shell)))
48651
49478
  return environment;
48652
49479
  const cacheKey = `${platform}\0${shell}\0${environment.HOME}`;
48653
49480
  const cached2 = dependencies ? void 0 : shellEnvironmentCache.get(cacheKey);
48654
49481
  if (cached2)
48655
49482
  return mergeMissingEnvironment(environment, cached2);
48656
49483
  const run = dependencies?.run ?? ((command, arguments_, options) => new Promise((resolve2) => {
48657
- const child = execFile2(command, arguments_, {
49484
+ const child = execFile3(command, arguments_, {
48658
49485
  ...options,
48659
49486
  encoding: "buffer",
48660
49487
  killSignal: "SIGKILL"
@@ -48691,9 +49518,15 @@ async function createHarnessAdapter(context) {
48691
49518
  ...context.brokerDescriptorPath ? { descriptorPath: context.brokerDescriptorPath } : {}
48692
49519
  });
48693
49520
  }
48694
- return new ClaudeCodeAdapter({
49521
+ return Object.assign(new ClaudeCodeAdapter({
48695
49522
  ...environment[CLAUDE_CODE_COMMAND_ENV] ? { command: environment[CLAUDE_CODE_COMMAND_ENV] } : {},
48696
49523
  environment
49524
+ }), {
49525
+ installation: createClaudeInstallation(environment, environment[CLAUDE_CODE_COMMAND_ENV]),
49526
+ install: createHarnessInstaller(environment, {
49527
+ posix: "https://claude.ai/install.sh",
49528
+ windows: "https://claude.ai/install.ps1"
49529
+ })
48697
49530
  });
48698
49531
  }
48699
49532
  async function warmup(adapter) {