@codexhost/cli-linux-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 (33) 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 +0 -0
  30. package/libexec/codexhost-shim +0 -0
  31. package/libexec/codexhost-updater +0 -0
  32. package/licenses/OpenCode-v2-Client-LICENSE.txt +21 -0
  33. 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, path9) {
780
- if (!path9)
779
+ function getElementAtPath(obj, path10) {
780
+ if (!path10)
781
781
  return obj;
782
- return path9.reduce((acc, key) => acc?.[key], obj);
782
+ return path10.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(x, startIndex = 0) {
1188
1188
  }
1189
1189
  return false;
1190
1190
  }
1191
- function prefixIssues(path9, issues) {
1191
+ function prefixIssues(path10, issues) {
1192
1192
  return issues.map((iss) => {
1193
1193
  var _a3;
1194
1194
  (_a3 = iss).path ?? (_a3.path = []);
1195
- iss.path.unshift(path9);
1195
+ iss.path.unshift(path10);
1196
1196
  return iss;
1197
1197
  });
1198
1198
  }
@@ -1339,16 +1339,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
1339
1339
  }
1340
1340
  function formatError(error51, mapper = (issue2) => issue2.message) {
1341
1341
  const fieldErrors = { _errors: [] };
1342
- const processError = (error52, path9 = []) => {
1342
+ const processError = (error52, path10 = []) => {
1343
1343
  for (const issue2 of error52.issues) {
1344
1344
  if (issue2.code === "invalid_union" && issue2.errors.length) {
1345
- issue2.errors.map((issues) => processError({ issues }, [...path9, ...issue2.path]));
1345
+ issue2.errors.map((issues) => processError({ issues }, [...path10, ...issue2.path]));
1346
1346
  } else if (issue2.code === "invalid_key") {
1347
- processError({ issues: issue2.issues }, [...path9, ...issue2.path]);
1347
+ processError({ issues: issue2.issues }, [...path10, ...issue2.path]);
1348
1348
  } else if (issue2.code === "invalid_element") {
1349
- processError({ issues: issue2.issues }, [...path9, ...issue2.path]);
1349
+ processError({ issues: issue2.issues }, [...path10, ...issue2.path]);
1350
1350
  } else {
1351
- const fullpath = [...path9, ...issue2.path];
1351
+ const fullpath = [...path10, ...issue2.path];
1352
1352
  if (fullpath.length === 0) {
1353
1353
  fieldErrors._errors.push(mapper(issue2));
1354
1354
  } else {
@@ -1375,17 +1375,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
1375
1375
  }
1376
1376
  function treeifyError(error51, mapper = (issue2) => issue2.message) {
1377
1377
  const result = { errors: [] };
1378
- const processError = (error52, path9 = []) => {
1378
+ const processError = (error52, path10 = []) => {
1379
1379
  var _a3, _b;
1380
1380
  for (const issue2 of error52.issues) {
1381
1381
  if (issue2.code === "invalid_union" && issue2.errors.length) {
1382
- issue2.errors.map((issues) => processError({ issues }, [...path9, ...issue2.path]));
1382
+ issue2.errors.map((issues) => processError({ issues }, [...path10, ...issue2.path]));
1383
1383
  } else if (issue2.code === "invalid_key") {
1384
- processError({ issues: issue2.issues }, [...path9, ...issue2.path]);
1384
+ processError({ issues: issue2.issues }, [...path10, ...issue2.path]);
1385
1385
  } else if (issue2.code === "invalid_element") {
1386
- processError({ issues: issue2.issues }, [...path9, ...issue2.path]);
1386
+ processError({ issues: issue2.issues }, [...path10, ...issue2.path]);
1387
1387
  } else {
1388
- const fullpath = [...path9, ...issue2.path];
1388
+ const fullpath = [...path10, ...issue2.path];
1389
1389
  if (fullpath.length === 0) {
1390
1390
  result.errors.push(mapper(issue2));
1391
1391
  continue;
@@ -1417,8 +1417,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
1417
1417
  }
1418
1418
  function toDotPath(_path) {
1419
1419
  const segs = [];
1420
- const path9 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
1421
- for (const seg of path9) {
1420
+ const path10 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
1421
+ for (const seg of path10) {
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 path9 = ref.slice(1).split("/").filter(Boolean);
14114
- if (path9.length === 0) {
14113
+ const path10 = ref.slice(1).split("/").filter(Boolean);
14114
+ if (path10.length === 0) {
14115
14115
  return ctx.rootSchema;
14116
14116
  }
14117
14117
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
14118
- if (path9[0] === defsKey) {
14119
- const key = path9[1];
14118
+ if (path10[0] === defsKey) {
14119
+ const key = path10[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
 
@@ -15876,6 +16019,7 @@ function defaultHarnessBrokerDescriptorPath(environment = process.env, harnessId
15876
16019
  var cwdSchema = external_exports.string().min(1).max(16384);
15877
16020
  var brokerEnvironmentSchema = external_exports.object({
15878
16021
  CODEXHOST_CLI_PATH: external_exports.string().max(16384).optional(),
16022
+ CODEXHOST_CLI_NODE_PATH: external_exports.string().max(16384).optional(),
15879
16023
  CODEXHOST_RUNTIME_ENDPOINT: external_exports.string().max(16384).optional(),
15880
16024
  CODEXHOST_RUNTIME_TOKEN: external_exports.string().max(16384).optional(),
15881
16025
  CODEXHOST_THREAD_ID: external_exports.string().max(256).optional()
@@ -16030,6 +16174,7 @@ var eventKeys = /* @__PURE__ */ new Map([
16030
16174
  ["item.started", /* @__PURE__ */ new Set(["type", "turnId", "item"])],
16031
16175
  ["item.updated", /* @__PURE__ */ new Set(["type", "turnId", "itemId", "update"])],
16032
16176
  ["item.completed", /* @__PURE__ */ new Set(["type", "turnId", "snapshot"])],
16177
+ ["item.detached", /* @__PURE__ */ new Set(["type", "turnId", "itemId"])],
16033
16178
  ["interaction.closed", /* @__PURE__ */ new Set(["type", "interactionId", "turnId", "reason"])],
16034
16179
  ["turn.completed", /* @__PURE__ */ new Set(["type", "turnId", "nativeTurnRef", "outcome"])],
16035
16180
  ["session.faulted", /* @__PURE__ */ new Set(["type", "error"])]
@@ -16598,6 +16743,7 @@ var BrokeredHarnessAdapter = class {
16598
16743
  if (this.#forwardEnvironment && input.environment) {
16599
16744
  const allowed = [
16600
16745
  "CODEXHOST_CLI_PATH",
16746
+ "CODEXHOST_CLI_NODE_PATH",
16601
16747
  "CODEXHOST_RUNTIME_ENDPOINT",
16602
16748
  "CODEXHOST_RUNTIME_TOKEN",
16603
16749
  "CODEXHOST_THREAD_ID"
@@ -16654,7 +16800,7 @@ var BrokeredHarnessAdapter = class {
16654
16800
  };
16655
16801
 
16656
16802
  // ../codebuddy/dist/codebuddy-adapter.js
16657
- import { stat as stat2 } from "node:fs/promises";
16803
+ import { stat as stat3 } from "node:fs/promises";
16658
16804
 
16659
16805
  // ../codebuddy/dist/acp-client.js
16660
16806
  import { execFile, spawn } from "node:child_process";
@@ -21582,16 +21728,16 @@ var Diff = class {
21582
21728
  }
21583
21729
  }
21584
21730
  }
21585
- addToPath(path9, added, removed, oldPosInc, options) {
21586
- const last = path9.lastComponent;
21731
+ addToPath(path10, added, removed, oldPosInc, options) {
21732
+ const last = path10.lastComponent;
21587
21733
  if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
21588
21734
  return {
21589
- oldPos: path9.oldPos + oldPosInc,
21735
+ oldPos: path10.oldPos + oldPosInc,
21590
21736
  lastComponent: { count: last.count + 1, added, removed, previousComponent: last.previousComponent }
21591
21737
  };
21592
21738
  } else {
21593
21739
  return {
21594
- oldPos: path9.oldPos + oldPosInc,
21740
+ oldPos: path10.oldPos + oldPosInc,
21595
21741
  lastComponent: { count: 1, added, removed, previousComponent: last }
21596
21742
  };
21597
21743
  }
@@ -23474,6 +23620,345 @@ async function deriveCodeBuddySession(options) {
23474
23620
  }
23475
23621
  }
23476
23622
 
23623
+ // ../codebuddy/dist/session-import.js
23624
+ import { createReadStream } from "node:fs";
23625
+ import { opendir, readFile as readFile4, stat as stat2 } from "node:fs/promises";
23626
+ import path7 from "node:path";
23627
+ import { createInterface as createInterface2 } from "node:readline";
23628
+
23629
+ // ../../harness-adapter/dist/session-import.js
23630
+ import { lstat as lstat3 } from "node:fs/promises";
23631
+ var SessionImportChangedError = class extends Error {
23632
+ constructor(message = "Native Session changed during discovery; refresh and retry") {
23633
+ super(message);
23634
+ this.name = "SessionImportChangedError";
23635
+ }
23636
+ };
23637
+ function isMissingFileError(error51) {
23638
+ return typeof error51 === "object" && error51 !== null && "code" in error51 && error51.code === "ENOENT";
23639
+ }
23640
+ function sameFileFingerprint(left, right) {
23641
+ 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;
23642
+ }
23643
+ var STORAGE_ACCESS_ERRORS = /* @__PURE__ */ new Set(["EACCES", "EPERM", "EIO", "EMFILE", "ENFILE"]);
23644
+ function isStorageAccessError(error51) {
23645
+ return typeof error51 === "object" && error51 !== null && "code" in error51 && typeof error51.code === "string" && STORAGE_ACCESS_ERRORS.has(error51.code);
23646
+ }
23647
+ async function optionalLstat(file2) {
23648
+ try {
23649
+ return await lstat3(file2);
23650
+ } catch (error51) {
23651
+ if (isMissingFileError(error51))
23652
+ return null;
23653
+ throw error51;
23654
+ }
23655
+ }
23656
+ async function readStableFiles(files, read) {
23657
+ const before = await Promise.all(files.map(optionalLstat));
23658
+ const value = await read(before);
23659
+ const after = await Promise.all(files.map(optionalLstat));
23660
+ if (before.some((info, index) => !sameFileFingerprint(info, after[index] ?? null)))
23661
+ throw new SessionImportChangedError();
23662
+ return value;
23663
+ }
23664
+ function sessionImportTitle(value, maxLength = HARNESS_SESSION_IMPORT_TITLE_MAX_LENGTH) {
23665
+ if (typeof value !== "string")
23666
+ return null;
23667
+ const normalized = value.replaceAll("\0", "").replaceAll(/\s+/gu, " ").trim();
23668
+ if (!normalized)
23669
+ return null;
23670
+ if (normalized.length <= maxLength)
23671
+ return normalized;
23672
+ const characters = [...normalized];
23673
+ if (characters.length <= maxLength)
23674
+ return normalized;
23675
+ return `${characters.slice(0, maxLength - 1).join("").trimEnd()}…`;
23676
+ }
23677
+ function sessionImportCandidate(input) {
23678
+ const time3 = typeof input.updatedAt === "number" ? input.updatedAt : typeof input.updatedAt === "string" ? Date.parse(input.updatedAt) : Number.NaN;
23679
+ const parsed = harnessSessionImportCandidateSchema.safeParse({
23680
+ nativeSessionId: input.nativeSessionId,
23681
+ cwd: input.cwd,
23682
+ title: typeof input.title === "string" && input.title.trim().length > 0 ? input.title : null,
23683
+ updatedAt: Math.floor(time3),
23684
+ // Unknown must stay unknown; only an explicit boolean is a native statement.
23685
+ running: typeof input.running === "boolean" ? input.running : null
23686
+ });
23687
+ return parsed.success ? parsed.data : null;
23688
+ }
23689
+ var SessionImportScope = class {
23690
+ #abort = new AbortController();
23691
+ #options;
23692
+ #pending = /* @__PURE__ */ new Set();
23693
+ constructor(options) {
23694
+ this.#options = options;
23695
+ }
23696
+ #closed() {
23697
+ return {
23698
+ ok: false,
23699
+ error: { code: "invalidState", message: this.#options.closedMessage, retryable: false }
23700
+ };
23701
+ }
23702
+ read(operation) {
23703
+ const signal = this.#abort.signal;
23704
+ if (signal.aborted)
23705
+ return Promise.resolve(this.#closed());
23706
+ let started;
23707
+ try {
23708
+ started = operation(signal);
23709
+ } catch (error51) {
23710
+ started = Promise.reject(error51 instanceof Error ? error51 : new Error("Session read failed"));
23711
+ }
23712
+ const request = started.then((value) => signal.aborted ? this.#closed() : { ok: true, value }).catch(() => signal.aborted ? this.#closed() : {
23713
+ ok: false,
23714
+ error: {
23715
+ code: "unavailable",
23716
+ message: this.#options.unavailableMessage,
23717
+ retryable: true
23718
+ }
23719
+ }).finally(() => this.#pending.delete(request));
23720
+ this.#pending.add(request);
23721
+ return request;
23722
+ }
23723
+ /** `read` for `resolveCandidate`: a null source is the selected Session having disappeared. */
23724
+ async resolve(operation) {
23725
+ const result = await this.read(operation);
23726
+ if (!result.ok)
23727
+ return result;
23728
+ return result.value ? { ok: true, value: result.value } : {
23729
+ ok: false,
23730
+ error: {
23731
+ code: "sessionNotFound",
23732
+ message: this.#options.notFoundMessage,
23733
+ retryable: false
23734
+ }
23735
+ };
23736
+ }
23737
+ /** Idempotent. Resolves after every started read has settled. */
23738
+ async close() {
23739
+ this.#abort.abort();
23740
+ await Promise.allSettled(this.#pending);
23741
+ }
23742
+ };
23743
+
23744
+ // ../codebuddy/dist/session-import.js
23745
+ var SESSION_FILE = /^([A-Za-z0-9][A-Za-z0-9_-]{0,199})\.jsonl$/u;
23746
+ var MAX_HISTORY_BYTES = 64e6;
23747
+ var MAX_MARKER_BYTES = 64 * 1024;
23748
+ function processAlive(pid) {
23749
+ if (typeof pid !== "number" || !Number.isSafeInteger(pid) || pid <= 0)
23750
+ return false;
23751
+ try {
23752
+ process.kill(pid, 0);
23753
+ return true;
23754
+ } catch (error51) {
23755
+ return record2(error51).code === "EPERM";
23756
+ }
23757
+ }
23758
+ function userText(row) {
23759
+ if (row.type !== "message" || row.role !== "user")
23760
+ return null;
23761
+ const { content } = row;
23762
+ if (typeof content === "string")
23763
+ return content;
23764
+ if (!Array.isArray(content))
23765
+ return "";
23766
+ return content.map((part) => record2(part)).filter((part) => typeof part.text === "string").map((part) => String(part.text)).join(" ");
23767
+ }
23768
+ async function readFacts(file2, signal) {
23769
+ const stream = createReadStream(file2, { encoding: "utf8", signal });
23770
+ const lines = createInterface2({ input: stream, crlfDelay: Infinity });
23771
+ let cwd = null;
23772
+ let customTitle = null;
23773
+ let generatedTitle = null;
23774
+ let firstPrompt = null;
23775
+ let hasUser = false;
23776
+ let updatedAt = null;
23777
+ try {
23778
+ for await (const line of lines) {
23779
+ signal.throwIfAborted();
23780
+ if (!line.trim())
23781
+ continue;
23782
+ let parsed;
23783
+ try {
23784
+ parsed = JSON.parse(line);
23785
+ } catch {
23786
+ return null;
23787
+ }
23788
+ const row = record2(parsed);
23789
+ if (typeof row.cwd === "string" && path7.isAbsolute(row.cwd))
23790
+ cwd ??= row.cwd;
23791
+ if (typeof row.timestamp === "number" && Number.isFinite(row.timestamp))
23792
+ updatedAt = row.timestamp;
23793
+ if (row.type === "custom-title")
23794
+ customTitle = sessionImportTitle(row.customTitle);
23795
+ else if (row.type === "ai-title")
23796
+ generatedTitle = sessionImportTitle(row.aiTitle);
23797
+ else {
23798
+ const text2 = userText(row);
23799
+ if (text2 !== null) {
23800
+ hasUser = true;
23801
+ firstPrompt ??= sessionImportTitle(text2);
23802
+ }
23803
+ }
23804
+ }
23805
+ } finally {
23806
+ lines.close();
23807
+ stream.destroy();
23808
+ }
23809
+ if (!hasUser || !cwd)
23810
+ return null;
23811
+ return { cwd, title: customTitle ?? generatedTitle ?? firstPrompt, updatedAt };
23812
+ }
23813
+ var CodeBuddySessionImport = class {
23814
+ #environment;
23815
+ #profile;
23816
+ #scope;
23817
+ constructor(environment, profile = CODEBUDDY_RUNTIME_PROFILE) {
23818
+ this.#environment = { ...environment };
23819
+ this.#profile = profile;
23820
+ this.#scope = new SessionImportScope({
23821
+ closedMessage: `${profile.displayName} Session import is closed`,
23822
+ unavailableMessage: `${profile.displayName} sessions could not be read; close native clients, check storage access and retry`,
23823
+ notFoundMessage: `${profile.displayName} Session is no longer importable`
23824
+ });
23825
+ }
23826
+ listCandidates() {
23827
+ return this.#scope.read(async (signal) => {
23828
+ const active = await this.#activeSessions(signal);
23829
+ const candidates = [];
23830
+ for (const [nativeSessionId, files] of await this.#sessionFiles(signal)) {
23831
+ if (files.length !== 1 || !files[0])
23832
+ continue;
23833
+ try {
23834
+ const source = await this.#source(nativeSessionId, files[0], active, signal);
23835
+ if (source)
23836
+ candidates.push(source.candidate);
23837
+ } catch (error51) {
23838
+ if (!(error51 instanceof SessionImportChangedError))
23839
+ throw error51;
23840
+ }
23841
+ }
23842
+ return candidates;
23843
+ });
23844
+ }
23845
+ resolveCandidate(nativeSessionId) {
23846
+ return this.#scope.resolve(async (signal) => {
23847
+ const files = (await this.#sessionFiles(signal)).get(nativeSessionId);
23848
+ if (files?.length !== 1 || !files[0])
23849
+ return null;
23850
+ return this.#source(nativeSessionId, files[0], await this.#activeSessions(signal), signal);
23851
+ });
23852
+ }
23853
+ close() {
23854
+ return this.#scope.close();
23855
+ }
23856
+ #root() {
23857
+ return codeBuddyConfigRoot(this.#environment, this.#profile);
23858
+ }
23859
+ /** IDs a live native process registered in `<config>/sessions/<pid>.json`. */
23860
+ async #activeSessions(signal) {
23861
+ const active = /* @__PURE__ */ new Set();
23862
+ const directory = path7.join(this.#root(), "sessions");
23863
+ const markers = await opendir(directory).catch((error51) => {
23864
+ if (isMissingFileError(error51) || record2(error51).code === "ENOTDIR")
23865
+ return null;
23866
+ throw error51;
23867
+ });
23868
+ if (!markers)
23869
+ return active;
23870
+ for await (const marker of markers) {
23871
+ signal.throwIfAborted();
23872
+ if (!marker.isFile() || !marker.name.endsWith(".json"))
23873
+ continue;
23874
+ try {
23875
+ const file2 = path7.join(directory, marker.name);
23876
+ if ((await stat2(file2)).size > MAX_MARKER_BYTES)
23877
+ continue;
23878
+ const entry = record2(JSON.parse(await readFile4(file2, { encoding: "utf8", signal })));
23879
+ if (typeof entry.sessionId === "string" && processAlive(entry.pid))
23880
+ active.add(entry.sessionId);
23881
+ } catch (error51) {
23882
+ signal.throwIfAborted();
23883
+ if (isStorageAccessError(error51))
23884
+ throw error51;
23885
+ }
23886
+ }
23887
+ return active;
23888
+ }
23889
+ /** Session ID to every project file claiming it. Enumerated links are not followed. */
23890
+ async #sessionFiles(signal) {
23891
+ const root = path7.join(this.#root(), "projects");
23892
+ const found = /* @__PURE__ */ new Map();
23893
+ const info = await optionalLstat(root);
23894
+ if (!info)
23895
+ return found;
23896
+ if (!info.isDirectory())
23897
+ throw new Error(`${this.#profile.displayName} Session store is not a directory`);
23898
+ for await (const project of await opendir(root)) {
23899
+ signal.throwIfAborted();
23900
+ if (!project.isDirectory())
23901
+ continue;
23902
+ const projectDirectory = path7.join(root, project.name);
23903
+ const entries = await opendir(projectDirectory).catch((error51) => {
23904
+ if (isMissingFileError(error51))
23905
+ return null;
23906
+ throw error51;
23907
+ });
23908
+ if (!entries)
23909
+ continue;
23910
+ for await (const entry of entries) {
23911
+ signal.throwIfAborted();
23912
+ const nativeSessionId = entry.isFile() ? SESSION_FILE.exec(entry.name)?.[1] : void 0;
23913
+ if (!nativeSessionId)
23914
+ continue;
23915
+ const files = found.get(nativeSessionId) ?? [];
23916
+ files.push(path7.join(projectDirectory, entry.name));
23917
+ found.set(nativeSessionId, files);
23918
+ }
23919
+ }
23920
+ return found;
23921
+ }
23922
+ async #source(nativeSessionId, file2, active, signal) {
23923
+ signal.throwIfAborted();
23924
+ return readStableFiles([file2], async ([info]) => {
23925
+ if (!info?.isFile() || info.size === 0 || info.size > MAX_HISTORY_BYTES)
23926
+ return null;
23927
+ try {
23928
+ const facts = await readFacts(file2, signal);
23929
+ if (!facts)
23930
+ return null;
23931
+ const cwd = path7.resolve(facts.cwd);
23932
+ if (!(await stat2(cwd)).isDirectory())
23933
+ return null;
23934
+ const nativeRef = nativeSessionRefSchema.parse({
23935
+ harnessId: this.#profile.harnessId,
23936
+ nativeSessionId,
23937
+ formatVersion: 1
23938
+ });
23939
+ signal.throwIfAborted();
23940
+ const history = await codeBuddyNativeHistory(cwd, nativeRef, this.#environment, this.#profile);
23941
+ if (path7.resolve(history.file) !== path7.resolve(file2))
23942
+ return null;
23943
+ const candidate = sessionImportCandidate({
23944
+ nativeSessionId,
23945
+ cwd,
23946
+ title: facts.title,
23947
+ updatedAt: facts.updatedAt ?? info.mtimeMs,
23948
+ // A registered live process holds the Session. Absence is not proof of idleness.
23949
+ running: active.has(nativeSessionId) ? true : null
23950
+ });
23951
+ return candidate ? { candidate, nativeRef } : null;
23952
+ } catch (error51) {
23953
+ signal.throwIfAborted();
23954
+ if (isStorageAccessError(error51))
23955
+ throw error51;
23956
+ return null;
23957
+ }
23958
+ });
23959
+ }
23960
+ };
23961
+
23477
23962
  // ../codebuddy/dist/interactions.js
23478
23963
  var CodeBuddyInteractions = class {
23479
23964
  emit;
@@ -23617,7 +24102,7 @@ var CodeBuddyInteractions = class {
23617
24102
 
23618
24103
  // ../codebuddy/dist/subagent-history.js
23619
24104
  import { readdir as readdir2, realpath as realpath5 } from "node:fs/promises";
23620
- import path7 from "node:path";
24105
+ import path8 from "node:path";
23621
24106
  var equalPath2 = (a, b) => process.platform === "win32" ? a.toLowerCase() === b.toLowerCase() : a === b;
23622
24107
  var MAX_CACHED_CHILDREN = 16;
23623
24108
  var CodeBuddyChildObserver = class {
@@ -23681,8 +24166,8 @@ var CodeBuddyChildObserver = class {
23681
24166
  }
23682
24167
  async #directory() {
23683
24168
  const history = await this.#parentHistory();
23684
- const project = path7.dirname(await realpath5(history.file));
23685
- const expected = path7.join(project, this.parent.nativeSessionId, "subagents");
24169
+ const project = path8.dirname(await realpath5(history.file));
24170
+ const expected = path8.join(project, this.parent.nativeSessionId, "subagents");
23686
24171
  const actual = await realpath5(expected);
23687
24172
  this.#assertOpen();
23688
24173
  if (!equalPath2(actual, expected))
@@ -23692,7 +24177,7 @@ var CodeBuddyChildObserver = class {
23692
24177
  async #child(directory, childId) {
23693
24178
  if (!validCodeBuddyChildId(childId))
23694
24179
  throw new CodeBuddyError("invalidRequest", "Invalid native Subagent ID");
23695
- const file2 = path7.join(directory, `${childId}.jsonl`);
24180
+ const file2 = path8.join(directory, `${childId}.jsonl`);
23696
24181
  const before = await codeBuddyFileVersion(file2);
23697
24182
  if (!equalPath2(before.realFile, file2))
23698
24183
  throw new CodeBuddyError("invalidRequest", "Redirected Subagent transcript");
@@ -24404,6 +24889,7 @@ var CodeBuddyAdapter = class {
24404
24889
  harnessId;
24405
24890
  commandCatalog;
24406
24891
  liveCommandCatalog = true;
24892
+ sessionImport;
24407
24893
  subagents = {
24408
24894
  readSnapshot: async ({ parent, nativeSubagentId, cwd }) => {
24409
24895
  try {
@@ -24437,6 +24923,7 @@ var CodeBuddyAdapter = class {
24437
24923
  this.commandCatalog = commandCatalog2;
24438
24924
  }
24439
24925
  this.#environment = { ...options.environment ?? process.env };
24926
+ this.sessionImport = new CodeBuddySessionImport(this.#environment, this.#profile);
24440
24927
  this.#invocation = options.invocationFactory ?? codeBuddyInvocation;
24441
24928
  this.#factory = options.clientFactory ?? ((clientOptions) => new CodeBuddyAcpClient(clientOptions, void 0, this.#invocation));
24442
24929
  }
@@ -24456,7 +24943,7 @@ var CodeBuddyAdapter = class {
24456
24943
  try {
24457
24944
  if (this.#closed)
24458
24945
  throw new CodeBuddyError("invalidState", "Adapter is closed");
24459
- if (!(await stat2(cwd)).isDirectory())
24946
+ if (!(await stat3(cwd)).isDirectory())
24460
24947
  throw new CodeBuddyError("invalidRequest", "Working directory is not a directory");
24461
24948
  client2 = this.#factory({
24462
24949
  cwd,
@@ -24502,7 +24989,7 @@ var CodeBuddyAdapter = class {
24502
24989
  return failure("invalidRequest", "Unattended execution requires native fullAccess permissions", this.#profile);
24503
24990
  let session;
24504
24991
  try {
24505
- if (!(await stat2(input.cwd)).isDirectory())
24992
+ if (!(await stat3(input.cwd)).isDirectory())
24506
24993
  throw new CodeBuddyError("invalidRequest", "Working directory is not a directory");
24507
24994
  if (this.#closed)
24508
24995
  throw new CodeBuddyError("invalidState", "Adapter closed while opening Session");
@@ -24565,7 +25052,7 @@ var CodeBuddyAdapter = class {
24565
25052
  async close() {
24566
25053
  this.#closed = true;
24567
25054
  this.#abort.abort();
24568
- await Promise.allSettled([...this.#derivations]);
25055
+ await Promise.allSettled([this.sessionImport.close(), ...this.#derivations]);
24569
25056
  const results = await Promise.allSettled([...this.#sessions, ...this.#inspections].map((resource) => resource.close()));
24570
25057
  this.#sessions.clear();
24571
25058
  this.#inspections.clear();
@@ -24784,8 +25271,8 @@ var WORKBUDDY_RUNTIME_PROFILE = {
24784
25271
  };
24785
25272
 
24786
25273
  // dist/product-models.js
24787
- import { readFile as readFile4, stat as stat3 } from "node:fs/promises";
24788
- import path8 from "node:path";
25274
+ import { readFile as readFile5, stat as stat4 } from "node:fs/promises";
25275
+ import path9 from "node:path";
24789
25276
  var MAX_PRODUCT_SNAPSHOT_BYTES = 8 * 1024 * 1024;
24790
25277
  var PRODUCT_CONFIG_PATH_ENV = "ACC_PRODUCT_CONFIG_PATH";
24791
25278
  var PRODUCT_CONFIG_INLINE_ENVS = [
@@ -24838,16 +25325,16 @@ function parseWorkBuddyProductModels(value) {
24838
25325
  return parsed;
24839
25326
  }
24840
25327
  async function readProductJson(file2) {
24841
- const metadata = await stat3(file2);
25328
+ const metadata = await stat4(file2);
24842
25329
  if (!metadata.isFile() || metadata.size <= 0 || metadata.size > MAX_PRODUCT_SNAPSHOT_BYTES)
24843
25330
  return;
24844
- return JSON.parse(await readFile4(file2, "utf8"));
25331
+ return JSON.parse(await readFile5(file2, "utf8"));
24845
25332
  }
24846
25333
  function bundledFallbackProductPath(invocation) {
24847
25334
  const cli = invocation.arguments[0];
24848
25335
  if (!cli || cli.startsWith("-"))
24849
25336
  return;
24850
- return path8.join(path8.dirname(path8.dirname(cli)), "product.json");
25337
+ return path9.join(path9.dirname(path9.dirname(cli)), "product.json");
24851
25338
  }
24852
25339
  async function loadWorkBuddyProductModels(environment) {
24853
25340
  const invocation = workBuddyInvocation(environment, true);