@codexhost/cli-win32-arm64 0.13.3 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/README.md +1 -1
  2. package/app/codexhost-distribution.json +1 -1
  3. package/app/console-server.mjs +109 -11
  4. package/app/console-web.js +649 -132
  5. package/app/desktop-controller.mjs +120 -12
  6. package/app/host-runtime.mjs +1124 -293
  7. package/app/plugins/antigravity/plugin.mjs +431 -66
  8. package/app/plugins/claude-code/plugin.mjs +761 -139
  9. package/app/plugins/codebuddy/plugin.mjs +322 -68
  10. package/app/plugins/codex-usage/plugin.mjs +249 -102
  11. package/app/plugins/copilot/assets/icon.png +0 -0
  12. package/app/plugins/copilot/manifest.json +26 -0
  13. package/app/plugins/copilot/plugin.mjs +34591 -0
  14. package/app/plugins/cursor-cli/plugin.mjs +21011 -44970
  15. package/app/plugins/deepseek-harness/plugin.mjs +160 -43
  16. package/app/plugins/enabled.json +1 -0
  17. package/app/plugins/grok/plugin.mjs +565 -107
  18. package/app/plugins/hermes/plugin.mjs +128 -12
  19. package/app/plugins/kimi-code/plugin.mjs +136 -22
  20. package/app/plugins/kiro-cli/plugin.mjs +136 -22
  21. package/app/plugins/omp/plugin.mjs +2236 -2036
  22. package/app/plugins/opencode/plugin.mjs +187 -68
  23. package/app/plugins/pi/plugin.mjs +2621 -2304
  24. package/app/plugins/qoder/plugin.mjs +153 -36
  25. package/app/plugins/qoder-cn/plugin.mjs +153 -36
  26. package/app/plugins/workbuddy/plugin.mjs +583 -92
  27. package/app/plugins/zcode/plugin.mjs +183 -40
  28. package/app/renderer-extension.js +1758 -392
  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/package.json +1 -1
@@ -3040,10 +3040,10 @@ var $ZodObject = /* @__PURE__ */ $constructor("$ZodObject", (inst, def) => {
3040
3040
  const shape = def.shape;
3041
3041
  const propValues = {};
3042
3042
  for (const key in shape) {
3043
- const field = shape[key]._zod;
3044
- if (field.values) {
3043
+ const field2 = shape[key]._zod;
3044
+ if (field2.values) {
3045
3045
  propValues[key] ?? (propValues[key] = /* @__PURE__ */ new Set());
3046
- for (const v of field.values)
3046
+ for (const v of field2.values)
3047
3047
  propValues[key].add(v);
3048
3048
  }
3049
3049
  }
@@ -14662,10 +14662,19 @@ var model = external_exports.string().min(1).max(512);
14662
14662
  var project = external_exports.string().min(1).max(4096);
14663
14663
  var usageStatisticsParamsSchema = external_exports.strictObject({
14664
14664
  range: external_exports.enum(USAGE_STATISTICS_RANGES),
14665
+ /** Display timezone for ranges, dates and hourly buckets; omitted means the Host's local zone. */
14666
+ timeZone: external_exports.string().min(1).max(128).refine((value) => {
14667
+ try {
14668
+ new Intl.DateTimeFormat("en", { timeZone: value });
14669
+ return true;
14670
+ } catch {
14671
+ return false;
14672
+ }
14673
+ }, "Unsupported usage statistics timezone").optional(),
14665
14674
  harness: harness.optional(),
14666
14675
  model: model.nullable().optional(),
14667
14676
  project: project.nullable().optional(),
14668
- /** One local date inside the range. */
14677
+ /** One date in the query timezone inside the range. */
14669
14678
  date: localDate.optional()
14670
14679
  });
14671
14680
  var usageStatisticsTotalsSchema = external_exports.strictObject({
@@ -14701,7 +14710,7 @@ var usageStatisticsSessionSchema = external_exports.strictObject({
14701
14710
  });
14702
14711
  var usageStatisticsResultSchema = external_exports.strictObject({
14703
14712
  range: external_exports.enum(USAGE_STATISTICS_RANGES),
14704
- /** First local date of the range; null for all time. */
14713
+ /** First date in the query timezone (Host local when omitted); null for all time. */
14705
14714
  from: localDate.nullable(),
14706
14715
  to: localDate,
14707
14716
  /** The filters these figures apply, echoed so a late answer to older filters is recognised. */
@@ -14741,7 +14750,7 @@ var usageStatisticsResultSchema = external_exports.strictObject({
14741
14750
  totals: usageStatisticsTotalsSchema,
14742
14751
  /** Each date and Harness of the range: every filter except the day. */
14743
14752
  daily: external_exports.array(external_exports.strictObject({ date: localDate, harness, ...totals })).max(2e5),
14744
- /** Local weekday (0 = Sunday) and hour, all filters applied. */
14753
+ /** Weekday (0 = Sunday) and hour in the query timezone, all filters applied. */
14745
14754
  hourly: external_exports.array(external_exports.strictObject({
14746
14755
  weekday: external_exports.number().int().min(0).max(6),
14747
14756
  hour: external_exports.number().int().min(0).max(23),
@@ -14781,6 +14790,51 @@ var hostInteractionIdSchema = opaqueIdSchema.brand();
14781
14790
  var threadPrewarmDiscardParamsSchema = external_exports.object({ threadId: hostThreadIdSchema });
14782
14791
  var threadPrewarmDiscardResultSchema = external_exports.object({ discarded: external_exports.boolean() });
14783
14792
 
14793
+ // ../../shared-contracts/dist/thread-questions.js
14794
+ var field = external_exports.discriminatedUnion("type", [
14795
+ external_exports.object({
14796
+ id: external_exports.string().min(1),
14797
+ type: external_exports.literal("choice"),
14798
+ prompt: external_exports.string(),
14799
+ options: external_exports.array(external_exports.object({
14800
+ value: external_exports.string().min(1),
14801
+ label: external_exports.string(),
14802
+ description: external_exports.string().optional()
14803
+ })).min(1),
14804
+ multiple: external_exports.boolean(),
14805
+ allowOther: external_exports.boolean(),
14806
+ optional: external_exports.boolean()
14807
+ }),
14808
+ external_exports.object({
14809
+ id: external_exports.string().min(1),
14810
+ type: external_exports.literal("text"),
14811
+ prompt: external_exports.string(),
14812
+ multiline: external_exports.boolean(),
14813
+ secret: external_exports.literal(false),
14814
+ optional: external_exports.boolean(),
14815
+ placeholder: external_exports.string().optional(),
14816
+ prefill: external_exports.string().optional()
14817
+ })
14818
+ ]);
14819
+ var threadQuestionSchema = external_exports.object({
14820
+ interactionId: external_exports.string().min(1),
14821
+ turnId: external_exports.string().min(1),
14822
+ title: external_exports.string().optional(),
14823
+ questions: external_exports.array(field).min(1)
14824
+ }).refine(({ questions }) => questions.some((q) => q.type === "choice" && q.multiple), {
14825
+ message: "Shared cards require at least one multi-select question"
14826
+ });
14827
+ var threadQuestionsListParamsSchema = external_exports.strictObject({ threadId: external_exports.string().min(1) });
14828
+ var threadQuestionsResultSchema = external_exports.object({ questions: external_exports.array(threadQuestionSchema) });
14829
+ var threadQuestionRespondParamsSchema = external_exports.strictObject({
14830
+ threadId: external_exports.string().min(1),
14831
+ turnId: external_exports.string().min(1),
14832
+ interactionId: external_exports.string().min(1),
14833
+ answers: external_exports.record(external_exports.string(), external_exports.array(external_exports.string())),
14834
+ cancelled: external_exports.boolean().default(false)
14835
+ });
14836
+ var threadQuestionRespondResultSchema = external_exports.object({ accepted: external_exports.literal(true) });
14837
+
14784
14838
  // ../../shared-contracts/dist/console.js
14785
14839
  var consoleAnnouncementSchema = external_exports.strictObject({
14786
14840
  title: external_exports.string().trim().min(1).max(200),
@@ -14801,6 +14855,8 @@ var CONSOLE_HOST_METHODS = Object.freeze([
14801
14855
  "codexhost/harness/display-settings/set",
14802
14856
  "codexhost/harness/inspect",
14803
14857
  "codexhost/harness/installation",
14858
+ "codexhost/harness/installation/start",
14859
+ "codexhost/harness/installation/status",
14804
14860
  "codexhost/harness/launch-settings/get",
14805
14861
  "codexhost/harness/launch-settings/set",
14806
14862
  "codexhost/harness/web-ui/open",
@@ -14876,7 +14932,18 @@ var threadManualCompactionStartedSchema = external_exports.strictObject({
14876
14932
  var nonNegativeSafeIntegerSchema = external_exports.number().int().safe().nonnegative();
14877
14933
  var finiteNonNegativeNumberSchema = external_exports.number().finite().nonnegative();
14878
14934
  var cacheHitRatePercentSchema = external_exports.number().finite().min(0).max(100);
14935
+ var indicatorTextSchema = (maximum) => harnessLocalizedTextSchema.refine((entries) => Object.values(entries).every((text2) => text2.length <= maximum));
14936
+ var composerIndicatorsSchema = external_exports.array(external_exports.object({
14937
+ kind: external_exports.literal("countdown"),
14938
+ id: external_exports.string().min(1).max(64),
14939
+ expiresAtUnix: nonNegativeSafeIntegerSchema,
14940
+ label: indicatorTextSchema(256).optional(),
14941
+ tooltip: indicatorTextSchema(1024).optional()
14942
+ }).strict()).max(2).refine((entries) => new Set(entries.map(({ id }) => id)).size === entries.length, {
14943
+ message: "Composer indicator IDs must be unique"
14944
+ });
14879
14945
  var threadUsageSnapshotSchema = external_exports.object({
14946
+ composerIndicators: composerIndicatorsSchema.optional(),
14880
14947
  inputTokens: nonNegativeSafeIntegerSchema.optional(),
14881
14948
  cachedInputTokens: nonNegativeSafeIntegerSchema.optional(),
14882
14949
  cacheWriteInputTokens: nonNegativeSafeIntegerSchema.optional(),
@@ -15284,7 +15351,9 @@ var harnessSessionCapabilitiesSchema = external_exports.object({
15284
15351
  }).strict().optional(),
15285
15352
  autonomousTurns: external_exports.object({
15286
15353
  observe: external_exports.boolean()
15287
- }).strict().optional()
15354
+ }).strict().optional(),
15355
+ /** True only when `turn.steer` delivers input into the active Turn through a native primitive. */
15356
+ steer: external_exports.boolean().optional()
15288
15357
  }).strict();
15289
15358
  var harnessConfigurationStateSchema = external_exports.object({
15290
15359
  effectiveModel: harnessModelRefSchema.optional(),
@@ -15331,7 +15400,9 @@ var harnessInspectionSchema = external_exports.union([
15331
15400
  var harnessInspectParamsSchema = external_exports.object({
15332
15401
  harnessId: harnessIdSchema,
15333
15402
  cwd: nonBlankTextSchema2.max(16384).optional(),
15334
- refresh: external_exports.boolean().optional()
15403
+ refresh: external_exports.boolean().optional(),
15404
+ /** `availability` asks only whether the Harness can run; see `InspectHarnessInput.purpose`. */
15405
+ purpose: external_exports.literal("availability").optional()
15335
15406
  }).strict();
15336
15407
  var harnessWebUiOpenParamsSchema = external_exports.object({
15337
15408
  harnessId: harnessIdSchema
@@ -15414,6 +15485,15 @@ var threadOwnershipListResultSchema = external_exports.object({
15414
15485
  seen.add(thread.threadId);
15415
15486
  }
15416
15487
  });
15488
+ var threadSteeringInspectParamsSchema = external_exports.object({
15489
+ threadId: hostThreadIdSchema,
15490
+ /** The text about to be steered; a Harness command always stops and restarts. */
15491
+ text: external_exports.string().optional()
15492
+ }).strict();
15493
+ var threadSteerDeliverySchema = external_exports.enum(["activeTurn", "newTurn"]);
15494
+ var threadSteeringInspectResultSchema = external_exports.object({
15495
+ delivery: external_exports.enum(["official", "activeTurn", "newTurn"])
15496
+ }).strict();
15417
15497
 
15418
15498
  // ../../shared-contracts/dist/harness-plugins.js
15419
15499
  var HARNESS_PLUGIN_MANIFEST_MAX_BYTES = 32 * 1024;
@@ -15515,6 +15595,10 @@ var harnessInstallationStateSchema = external_exports.object({
15515
15595
  latestVersion: external_exports.string().min(1).max(128),
15516
15596
  updateAvailable: external_exports.boolean(),
15517
15597
  canUpdate: external_exports.boolean(),
15598
+ /** Defaults to CLI; some Harnesses ship only inside a desktop application. */
15599
+ versionKind: external_exports.enum(["cli", "application"]).optional(),
15600
+ /** Official download opened by the user; does not imply an automatic installation. */
15601
+ manualUpdateUrl: external_exports.url().max(2048).refine((value) => /^https:\/\/[^/?#@]+(?:[/?#]|$)/iu.test(value), "Manual updates require a credential-free HTTPS URL").optional(),
15518
15602
  // Adapter-owned diagnostic text; UI uses messageCode rather than displaying it verbatim.
15519
15603
  message: external_exports.string().max(2048).optional(),
15520
15604
  messageCode: external_exports.string().min(1).max(128).optional(),
@@ -15522,6 +15606,20 @@ var harnessInstallationStateSchema = external_exports.object({
15522
15606
  notice: harnessLocalizedTextSchema.optional(),
15523
15607
  latestVersionKind: external_exports.enum(["unknown", "tracking-branch"]).optional()
15524
15608
  }).strict();
15609
+ var harnessInstallationTaskParamsSchema = external_exports.object({ taskId: external_exports.string().uuid() }).strict();
15610
+ var harnessInstallationTaskSchema = external_exports.discriminatedUnion("status", [
15611
+ external_exports.object({ taskId: external_exports.string().uuid(), status: external_exports.literal("running") }).strict(),
15612
+ external_exports.object({
15613
+ taskId: external_exports.string().uuid(),
15614
+ status: external_exports.literal("succeeded"),
15615
+ result: harnessInstallationStateSchema
15616
+ }).strict(),
15617
+ external_exports.object({
15618
+ taskId: external_exports.string().uuid(),
15619
+ status: external_exports.literal("failed"),
15620
+ error: external_exports.object({ code: external_exports.number().int(), message: external_exports.string().min(1).max(2048) }).strict()
15621
+ }).strict()
15622
+ ]);
15525
15623
 
15526
15624
  // ../../shared-contracts/dist/codex-accounts.js
15527
15625
  var accountIdSchema = external_exports.string().min(1).max(256).regex(/^[A-Za-z0-9._~-]+$/u);
@@ -16024,6 +16122,18 @@ function sanitizeDiagnosticTail(value) {
16024
16122
  return redacted.length <= DIAGNOSTIC_TAIL_MAX_LENGTH ? redacted : redacted.slice(-DIAGNOSTIC_TAIL_MAX_LENGTH);
16025
16123
  }
16026
16124
 
16125
+ // ../../harness-adapter/dist/steer.js
16126
+ function unsupportedSteer(harnessLabel) {
16127
+ return {
16128
+ ok: false,
16129
+ error: {
16130
+ code: "unsupported",
16131
+ message: `${harnessLabel} cannot steer an active Turn natively`,
16132
+ retryable: false
16133
+ }
16134
+ };
16135
+ }
16136
+
16027
16137
  // ../../harness-adapter/dist/usage.js
16028
16138
  var tokenFields = [
16029
16139
  "inputTokens",
@@ -16051,6 +16161,7 @@ var usageFields = /* @__PURE__ */ new Set([
16051
16161
  ...safeIntegerFields,
16052
16162
  ...percentFields,
16053
16163
  "sessionCacheUsage",
16164
+ "composerIndicators",
16054
16165
  "totalCostUsd",
16055
16166
  "totalCredits",
16056
16167
  "contextUsagePercent",
@@ -16073,26 +16184,27 @@ function parseHostUsage(value) {
16073
16184
  throw new Error(`Harness Usage contains unknown field '${key}'`);
16074
16185
  }
16075
16186
  }
16076
- for (const field of [
16187
+ const indicators = value.composerIndicators === void 0 ? {} : { composerIndicators: composerIndicatorsSchema.parse(value.composerIndicators) };
16188
+ for (const field2 of [
16077
16189
  "totalCredits",
16078
16190
  "contextUsagePercent",
16079
16191
  "apiOutputTokensPerSecond"
16080
16192
  ]) {
16081
- const candidate = value[field];
16193
+ const candidate = value[field2];
16082
16194
  if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isFinite(candidate) || candidate < 0)) {
16083
- throw new Error(`Harness Usage '${field}' must be a finite non-negative number`);
16195
+ throw new Error(`Harness Usage '${field2}' must be a finite non-negative number`);
16084
16196
  }
16085
16197
  }
16086
- for (const field of tokenFields) {
16087
- const candidate = value[field];
16198
+ for (const field2 of tokenFields) {
16199
+ const candidate = value[field2];
16088
16200
  if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isSafeInteger(candidate) || candidate < 0)) {
16089
- throw new Error(`Harness Usage '${field}' must be a non-negative safe integer`);
16201
+ throw new Error(`Harness Usage '${field2}' must be a non-negative safe integer`);
16090
16202
  }
16091
16203
  }
16092
- for (const field of safeIntegerFields) {
16093
- const candidate = value[field];
16204
+ for (const field2 of safeIntegerFields) {
16205
+ const candidate = value[field2];
16094
16206
  if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isSafeInteger(candidate) || candidate < 0)) {
16095
- throw new Error(`Harness Usage '${field}' must be a non-negative safe integer`);
16207
+ throw new Error(`Harness Usage '${field2}' must be a non-negative safe integer`);
16096
16208
  }
16097
16209
  }
16098
16210
  if (value.outputTokensPerSecond !== void 0 && (typeof value.outputTokensPerSecond !== "number" || !Number.isFinite(value.outputTokensPerSecond) || value.outputTokensPerSecond < 0)) {
@@ -16101,10 +16213,10 @@ function parseHostUsage(value) {
16101
16213
  if (value.totalCostUsd !== void 0 && (typeof value.totalCostUsd !== "number" || !Number.isFinite(value.totalCostUsd) || value.totalCostUsd < 0)) {
16102
16214
  throw new Error("Harness Usage 'totalCostUsd' must be a finite non-negative number");
16103
16215
  }
16104
- for (const field of percentFields) {
16105
- const candidate = value[field];
16216
+ for (const field2 of percentFields) {
16217
+ const candidate = value[field2];
16106
16218
  if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isFinite(candidate) || candidate < 0 || candidate > 100)) {
16107
- throw new Error(`Harness Usage '${field}' must be between 0 and 100`);
16219
+ throw new Error(`Harness Usage '${field2}' must be between 0 and 100`);
16108
16220
  }
16109
16221
  }
16110
16222
  if (value.sessionCacheUsage !== void 0) {
@@ -16143,9 +16255,9 @@ function parseHostUsage(value) {
16143
16255
  if (value.costSource !== "publicPrice") {
16144
16256
  throw new Error("Harness Usage 'unpricedModels' must be provided with a 'publicPrice' cost");
16145
16257
  }
16146
- return { ...value, unpricedModels: [...models] };
16258
+ return { ...value, ...indicators, unpricedModels: [...models] };
16147
16259
  }
16148
- return { ...value };
16260
+ return { ...value, ...indicators };
16149
16261
  }
16150
16262
  var requestTokenFields = [
16151
16263
  "inputTokens",
@@ -16175,19 +16287,19 @@ function parseHostUsageRequest(value) {
16175
16287
  if (typeof value.requestId !== "string" || value.requestId.length === 0) {
16176
16288
  throw new Error("Harness Usage request 'requestId' must be a non-empty string");
16177
16289
  }
16178
- for (const field of ["model", "provider"]) {
16179
- const candidate = value[field];
16290
+ for (const field2 of ["model", "provider"]) {
16291
+ const candidate = value[field2];
16180
16292
  if (candidate !== void 0 && (typeof candidate !== "string" || candidate.length === 0)) {
16181
- throw new Error(`Harness Usage request '${field}' must be a non-empty string`);
16293
+ throw new Error(`Harness Usage request '${field2}' must be a non-empty string`);
16182
16294
  }
16183
16295
  }
16184
16296
  if (value.historical !== void 0 && typeof value.historical !== "boolean") {
16185
16297
  throw new Error("Harness Usage request 'historical' must be a boolean");
16186
16298
  }
16187
- for (const field of requestTokenFields) {
16188
- const candidate = value[field];
16299
+ for (const field2 of requestTokenFields) {
16300
+ const candidate = value[field2];
16189
16301
  if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isSafeInteger(candidate) || candidate < 0)) {
16190
- throw new Error(`Harness Usage request '${field}' must be a non-negative safe integer`);
16302
+ throw new Error(`Harness Usage request '${field2}' must be a non-negative safe integer`);
16191
16303
  }
16192
16304
  }
16193
16305
  if (value.inputTokens === void 0 || value.outputTokens === void 0) {
@@ -16293,6 +16405,7 @@ var HARNESS_BROKER_PROTOCOL_VERSION = 1;
16293
16405
  var HARNESS_BROKER_MAX_FRAME_BYTES = 8 * 1024 * 1024;
16294
16406
  var HARNESS_BROKER_MAX_PENDING_REQUESTS = 32;
16295
16407
  var HARNESS_BROKER_REQUEST_TIMEOUT_MS = 15e3;
16408
+ var HARNESS_BROKER_SESSION_IMPORT_PAGE_SIZE = 100;
16296
16409
  var HARNESS_BROKER_IDLE_TIMEOUT_MS = 60 * 60 * 1e3;
16297
16410
  var HARNESS_BROKER_RETIRING_ERROR_CODE = "brokerRetiring";
16298
16411
  var harnessBrokerMethodSchema = external_exports.enum([
@@ -16300,8 +16413,11 @@ var harnessBrokerMethodSchema = external_exports.enum([
16300
16413
  "adapter.inspectAccount",
16301
16414
  "adapter.credits",
16302
16415
  "adapter.open",
16416
+ "adapter.sessionImport.list",
16417
+ "adapter.sessionImport.resolve",
16303
16418
  "adapter.subagent.readSnapshot",
16304
16419
  "session.readSnapshot",
16420
+ "session.readCapabilities",
16305
16421
  "session.refreshUsage",
16306
16422
  "session.execute",
16307
16423
  "session.commands.list",
@@ -16401,30 +16517,6 @@ function consumeBrokerFrames(socket, onFrame, onError) {
16401
16517
  });
16402
16518
  }
16403
16519
 
16404
- // ../../harness-broker/dist/paths.js
16405
- import os from "node:os";
16406
- import path from "node:path";
16407
- var HARNESS_BROKER_DESCRIPTOR_ENV = "CODEXHOST_CLAUDE_BROKER_DESCRIPTOR";
16408
- var HARNESS_BROKER_DESCRIPTOR_FILE = "claude-code-broker-v1.json";
16409
- function defaultHarnessBrokerDirectory(environment = process.env) {
16410
- const home = environment.HOME || os.homedir();
16411
- return path.join(home, ".codexhost", "harness-broker");
16412
- }
16413
- function defaultHarnessBrokerDescriptorPath(environment = process.env, harnessId = "claude-code") {
16414
- harnessPluginIdSchema.parse(harnessId);
16415
- if (harnessId !== "claude-code")
16416
- return path.join(defaultHarnessBrokerDirectory(environment), `${harnessId}-broker-v1.json`);
16417
- return environment[HARNESS_BROKER_DESCRIPTOR_ENV] ?? path.join(defaultHarnessBrokerDirectory(environment), HARNESS_BROKER_DESCRIPTOR_FILE);
16418
- }
16419
- function harnessBrokerLaunchAgentLabel(harnessId = "claude-code") {
16420
- harnessPluginIdSchema.parse(harnessId);
16421
- return harnessId === "claude-code" ? "ai.bytepioneer.codexhost.native-harness-broker" : `ai.bytepioneer.codexhost.${harnessId}-broker`;
16422
- }
16423
- function harnessBrokerLaunchAgentPlistPath(environment = process.env, harnessId = "claude-code") {
16424
- const home = environment.HOME || os.homedir();
16425
- return path.join(home, "Library", "LaunchAgents", `${harnessBrokerLaunchAgentLabel(harnessId)}.plist`);
16426
- }
16427
-
16428
16520
  // ../../harness-broker/dist/validation.js
16429
16521
  var cwdSchema = external_exports.string().min(1).max(16384);
16430
16522
  var brokerEnvironmentSchema = external_exports.object({
@@ -16475,13 +16567,42 @@ var brokerOpenInputSchema = external_exports.discriminatedUnion("kind", [
16475
16567
  forkSchema,
16476
16568
  rollbackSchema
16477
16569
  ]);
16478
- var brokerInspectInputSchema = external_exports.object({ cwd: cwdSchema.optional(), refresh: external_exports.boolean().optional() }).strict();
16570
+ var brokerInspectInputSchema = external_exports.object({
16571
+ cwd: cwdSchema.optional(),
16572
+ refresh: external_exports.boolean().optional(),
16573
+ purpose: external_exports.literal("availability").optional()
16574
+ }).strict();
16575
+ var brokerSessionImportListParamsSchema = external_exports.object({
16576
+ offset: external_exports.number().int().nonnegative().safe(),
16577
+ limit: external_exports.number().int().min(1).max(HARNESS_BROKER_SESSION_IMPORT_PAGE_SIZE)
16578
+ }).strict();
16579
+ var brokerSessionImportResolveParamsSchema = external_exports.object({ nativeSessionId: harnessSessionImportIdSchema }).strict();
16580
+ var brokerSessionImportPageSchema = external_exports.object({
16581
+ candidates: external_exports.array(harnessSessionImportCandidateSchema).max(HARNESS_BROKER_SESSION_IMPORT_PAGE_SIZE),
16582
+ total: external_exports.number().int().nonnegative().safe()
16583
+ }).strict();
16584
+ var brokerSessionImportSourceSchema = external_exports.object({
16585
+ candidate: harnessSessionImportCandidateSchema,
16586
+ nativeRef: nativeSessionRefSchema
16587
+ }).strict().superRefine((source, context) => {
16588
+ if (source.nativeRef.nativeSessionId !== source.candidate.nativeSessionId) {
16589
+ context.addIssue({
16590
+ code: "custom",
16591
+ message: "Session import source identity does not match"
16592
+ });
16593
+ }
16594
+ });
16479
16595
  var textInputSchema = external_exports.object({ type: external_exports.literal("text"), text: external_exports.string().max(4e6) }).strict();
16480
16596
  var turnStartSchema = external_exports.object({
16481
16597
  type: external_exports.literal("turn.start"),
16482
16598
  turnId: hostTurnIdSchema,
16483
16599
  input: external_exports.array(textInputSchema)
16484
16600
  }).strict();
16601
+ var turnSteerSchema = external_exports.object({
16602
+ type: external_exports.literal("turn.steer"),
16603
+ turnId: hostTurnIdSchema,
16604
+ input: external_exports.array(textInputSchema)
16605
+ }).strict();
16485
16606
  var turnCancelSchema = external_exports.object({ type: external_exports.literal("turn.cancel"), turnId: hostTurnIdSchema }).strict();
16486
16607
  var interactionResponseSchema = external_exports.union([
16487
16608
  external_exports.object({
@@ -16507,6 +16628,7 @@ var permissionSelectSchema = external_exports.object({
16507
16628
  }).strict();
16508
16629
  var brokerHostCommandSchema = external_exports.discriminatedUnion("type", [
16509
16630
  turnStartSchema,
16631
+ turnSteerSchema,
16510
16632
  turnCancelSchema,
16511
16633
  interactionRespondSchema,
16512
16634
  modelSelectSchema,
@@ -16640,6 +16762,107 @@ var harnessOutputSchema = external_exports.custom((value) => {
16640
16762
  return false;
16641
16763
  });
16642
16764
 
16765
+ // ../../harness-broker/dist/session-import-client.js
16766
+ function createBrokerSessionImportCapability(input) {
16767
+ let listing = null;
16768
+ const closed = () => ({
16769
+ ok: false,
16770
+ error: { code: "invalidState", message: "Harness broker adapter is closed", retryable: false }
16771
+ });
16772
+ const invalid = () => ({
16773
+ ok: false,
16774
+ error: {
16775
+ code: "protocolError",
16776
+ message: "Harness broker returned invalid Session import metadata",
16777
+ retryable: false
16778
+ }
16779
+ });
16780
+ const list = async () => {
16781
+ try {
16782
+ const candidates = [];
16783
+ const identities = /* @__PURE__ */ new Set();
16784
+ let total;
16785
+ for (; ; ) {
16786
+ if (input.isClosed())
16787
+ return closed();
16788
+ const result = await input.request("adapter.sessionImport.list", {
16789
+ offset: candidates.length,
16790
+ limit: HARNESS_BROKER_SESSION_IMPORT_PAGE_SIZE
16791
+ });
16792
+ if (input.isClosed())
16793
+ return closed();
16794
+ if (!result.ok)
16795
+ return result;
16796
+ const page = brokerSessionImportPageSchema.safeParse(result.value);
16797
+ if (!page.success || total !== void 0 && total !== page.data.total || page.data.total < candidates.length + page.data.candidates.length || page.data.candidates.length === 0 && candidates.length < page.data.total)
16798
+ return invalid();
16799
+ total = page.data.total;
16800
+ for (const candidate of page.data.candidates) {
16801
+ if (identities.has(candidate.nativeSessionId))
16802
+ return invalid();
16803
+ identities.add(candidate.nativeSessionId);
16804
+ candidates.push(candidate);
16805
+ }
16806
+ if (candidates.length === total)
16807
+ return { ok: true, value: candidates };
16808
+ }
16809
+ } catch (error51) {
16810
+ return { ok: false, error: input.error(error51) };
16811
+ }
16812
+ };
16813
+ return {
16814
+ listCandidates() {
16815
+ if (input.isClosed())
16816
+ return Promise.resolve(closed());
16817
+ listing ??= list().finally(() => {
16818
+ listing = null;
16819
+ });
16820
+ return listing;
16821
+ },
16822
+ async resolveCandidate(nativeSessionId) {
16823
+ if (input.isClosed())
16824
+ return closed();
16825
+ try {
16826
+ const result = await input.request("adapter.sessionImport.resolve", { nativeSessionId });
16827
+ if (input.isClosed())
16828
+ return closed();
16829
+ if (!result.ok)
16830
+ return result;
16831
+ const source = brokerSessionImportSourceSchema.safeParse(result.value);
16832
+ if (!source.success || source.data.nativeRef.harnessId !== input.harnessId || source.data.candidate.nativeSessionId !== nativeSessionId)
16833
+ return invalid();
16834
+ return { ok: true, value: source.data };
16835
+ } catch (error51) {
16836
+ return { ok: false, error: input.error(error51) };
16837
+ }
16838
+ }
16839
+ };
16840
+ }
16841
+
16842
+ // ../../harness-broker/dist/paths.js
16843
+ import os from "node:os";
16844
+ import path from "node:path";
16845
+ var HARNESS_BROKER_DESCRIPTOR_ENV = "CODEXHOST_CLAUDE_BROKER_DESCRIPTOR";
16846
+ var HARNESS_BROKER_DESCRIPTOR_FILE = "claude-code-broker-v1.json";
16847
+ function defaultHarnessBrokerDirectory(environment = process.env) {
16848
+ const home = environment.HOME || os.homedir();
16849
+ return path.join(home, ".codexhost", "harness-broker");
16850
+ }
16851
+ function defaultHarnessBrokerDescriptorPath(environment = process.env, harnessId = "claude-code") {
16852
+ harnessPluginIdSchema.parse(harnessId);
16853
+ if (harnessId !== "claude-code")
16854
+ return path.join(defaultHarnessBrokerDirectory(environment), `${harnessId}-broker-v1.json`);
16855
+ return environment[HARNESS_BROKER_DESCRIPTOR_ENV] ?? path.join(defaultHarnessBrokerDirectory(environment), HARNESS_BROKER_DESCRIPTOR_FILE);
16856
+ }
16857
+ function harnessBrokerLaunchAgentLabel(harnessId = "claude-code") {
16858
+ harnessPluginIdSchema.parse(harnessId);
16859
+ return harnessId === "claude-code" ? "ai.bytepioneer.codexhost.native-harness-broker" : `ai.bytepioneer.codexhost.${harnessId}-broker`;
16860
+ }
16861
+ function harnessBrokerLaunchAgentPlistPath(environment = process.env, harnessId = "claude-code") {
16862
+ const home = environment.HOME || os.homedir();
16863
+ return path.join(home, "Library", "LaunchAgents", `${harnessBrokerLaunchAgentLabel(harnessId)}.plist`);
16864
+ }
16865
+
16643
16866
  // ../../harness-broker/dist/client.js
16644
16867
  function unavailable(message, retryable = true) {
16645
16868
  return { code: "unavailable", message, retryable, stage: "harnessBroker" };
@@ -16699,6 +16922,7 @@ function parseSessionMetadata(value) {
16699
16922
  sessionId: candidate.sessionId,
16700
16923
  sessionGeneration: candidate.sessionGeneration,
16701
16924
  capabilities: harnessSessionCapabilitiesSchema.parse(candidate.capabilities),
16925
+ readCapabilities: candidate.readCapabilities === true,
16702
16926
  initialState: state,
16703
16927
  initialUsage: candidate.initialUsage === null ? null : parseHostUsage(candidate.initialUsage),
16704
16928
  commands: candidate.commands === true
@@ -17050,6 +17274,11 @@ var BrokeredHarnessSession = class {
17050
17274
  event: { type: "session.faulted", error: unavailable(error51.message) }
17051
17275
  });
17052
17276
  }
17277
+ async readCapabilities() {
17278
+ if (!this.#metadata.readCapabilities)
17279
+ return { ...this.capabilities, steer: false };
17280
+ return harnessSessionCapabilitiesSchema.parse(await this.#request("session.readCapabilities", {}));
17281
+ }
17053
17282
  async refreshUsage() {
17054
17283
  await this.#request("session.refreshUsage", {});
17055
17284
  }
@@ -17081,6 +17310,8 @@ var BrokeredHarnessSession = class {
17081
17310
  try {
17082
17311
  return parseHarnessResult(await this.#request("session.execute", { command }));
17083
17312
  } catch (error51) {
17313
+ if (command.type === "turn.steer")
17314
+ throw error51;
17084
17315
  return {
17085
17316
  ok: false,
17086
17317
  error: unavailable(error51 instanceof Error ? error51.message : String(error51))
@@ -17168,6 +17399,7 @@ var BrokeredHarnessAdapter = class {
17168
17399
  commandCatalog;
17169
17400
  liveCommandCatalog;
17170
17401
  harnessId;
17402
+ sessionImport;
17171
17403
  credits;
17172
17404
  refreshCredits;
17173
17405
  #descriptorPath;
@@ -17190,6 +17422,14 @@ var BrokeredHarnessAdapter = class {
17190
17422
  };
17191
17423
  constructor(input = {}) {
17192
17424
  this.harnessId = harnessPluginIdSchema.parse(input.harnessId ?? "claude-code");
17425
+ if (input.sessionImport) {
17426
+ this.sessionImport = createBrokerSessionImportCapability({
17427
+ harnessId: this.harnessId,
17428
+ request: async (method, params) => parseHarnessResult(await this.#request(method, params, method === "adapter.sessionImport.resolve")),
17429
+ isClosed: () => this.#closed,
17430
+ error: (error51) => this.#error(error51)
17431
+ });
17432
+ }
17193
17433
  if (input.accountCredits !== false) {
17194
17434
  this.credits = () => this.#credits;
17195
17435
  this.refreshCredits = () => this.#refreshAccountCredits();
@@ -17391,10 +17631,13 @@ function usageSessionTitle(value) {
17391
17631
  return void 0;
17392
17632
  if (normalized.length <= MAX_SESSION_TITLE_LENGTH)
17393
17633
  return normalized;
17394
- const characters = [...normalized];
17395
- if (characters.length <= MAX_SESSION_TITLE_LENGTH)
17396
- return normalized;
17397
- return `${characters.slice(0, MAX_SESSION_TITLE_LENGTH - 1).join("").trimEnd()}…`;
17634
+ let title = "";
17635
+ for (const character of normalized) {
17636
+ if (title.length + character.length >= MAX_SESSION_TITLE_LENGTH)
17637
+ break;
17638
+ title += character;
17639
+ }
17640
+ return `${title.trimEnd()}…`;
17398
17641
  }
17399
17642
  function sessionIdOk(value) {
17400
17643
  return typeof value === "string" && value.length > 0 && value.length <= MAX_SESSION_ID_LENGTH;
@@ -19036,7 +19279,7 @@ function createCodeBuddyUsageStatistics(environment, profile) {
19036
19279
  import { stat as stat3 } from "node:fs/promises";
19037
19280
 
19038
19281
  // ../codebuddy/dist/acp-client.js
19039
- import { execFile as execFile2, spawn } from "node:child_process";
19282
+ import { execFile as execFile3, spawn } from "node:child_process";
19040
19283
  import { Readable as Readable2, Writable } from "node:stream";
19041
19284
 
19042
19285
  // ../../../node_modules/@agentclientprotocol/sdk/dist/schema/index.js
@@ -23201,9 +23444,23 @@ var ClientSideConnection = class {
23201
23444
 
23202
23445
  // ../codebuddy/dist/copy-cleanup.js
23203
23446
  import { randomBytes } from "node:crypto";
23447
+
23448
+ // ../codebuddy/dist/acp-stdio.js
23204
23449
  import { createInterface as createInterface2 } from "node:readline";
23205
- import { stripVTControlCharacters } from "node:util";
23206
23450
  import { Readable } from "node:stream";
23451
+ import { stripVTControlCharacters } from "node:util";
23452
+ function codeBuddyAcpOutput(stdout, onLine) {
23453
+ return Readable.from((async function* () {
23454
+ for await (const line of createInterface2({ input: stdout })) {
23455
+ onLine?.(stripVTControlCharacters(line));
23456
+ if (line.trimStart().startsWith("{"))
23457
+ yield Buffer.from(`${line}
23458
+ `);
23459
+ }
23460
+ })());
23461
+ }
23462
+
23463
+ // ../codebuddy/dist/copy-cleanup.js
23207
23464
  var CodeBuddyCopyCleanup = class {
23208
23465
  copyId;
23209
23466
  cwd;
@@ -23233,17 +23490,11 @@ var CodeBuddyCopyCleanup = class {
23233
23490
  }
23234
23491
  /** Native --serve banners include its password; never pass them to the ACP parser/logs. */
23235
23492
  protocolOutput(stdout) {
23236
- return Readable.from(this.#protocolLines(stdout));
23237
- }
23238
- async *#protocolLines(stdout) {
23239
- for await (const line of createInterface2({ input: stdout })) {
23240
- const endpoint = /^\s*Endpoint\s+(http:\/\/127\.0\.0\.1:\d+)\s*$/u.exec(stripVTControlCharacters(line));
23493
+ return codeBuddyAcpOutput(stdout, (line) => {
23494
+ const endpoint = /^\s*Endpoint\s+(http:\/\/127\.0\.0\.1:\d+)\s*$/u.exec(line);
23241
23495
  if (endpoint)
23242
23496
  this.#endpoint = endpoint[1];
23243
- if (line.trimStart().startsWith("{"))
23244
- yield Buffer.from(`${line}
23245
- `);
23246
- }
23497
+ });
23247
23498
  }
23248
23499
  async remove() {
23249
23500
  if (!this.#endpoint)
@@ -23508,6 +23759,88 @@ function resolveHarnessExecutable(spec, input, dependencies = {}) {
23508
23759
  return void 0;
23509
23760
  }
23510
23761
 
23762
+ // ../../harness-discovery/dist/installation.js
23763
+ import { execFile as execFile2 } from "node:child_process";
23764
+ import { homedir as homedir2 } from "node:os";
23765
+ function runInstallationCommand(command, args, environment, timeout = 3e4) {
23766
+ const env = withNodeRuntimeOnPath(environment);
23767
+ const invocation = /\.[cm]?js$/i.test(command) ? commandInvocation(process.execPath, [command, ...args], env) : commandInvocation(command, args, env);
23768
+ return new Promise((resolve, reject) => {
23769
+ const child = execFile2(invocation.command, invocation.arguments, {
23770
+ env,
23771
+ cwd: env.HOME ?? env.USERPROFILE ?? homedir2(),
23772
+ encoding: "utf8",
23773
+ timeout,
23774
+ killSignal: "SIGKILL",
23775
+ maxBuffer: 1024 * 1024,
23776
+ windowsHide: true,
23777
+ windowsVerbatimArguments: invocation.windowsVerbatimArguments
23778
+ }, (error51, stdout, stderr) => {
23779
+ if (error51)
23780
+ reject(new Error(error51.killed ? "Harness command timed out" : "Harness command failed; check the native installation and retry"));
23781
+ else
23782
+ resolve((stdout || stderr).trim());
23783
+ });
23784
+ child.stdin?.end();
23785
+ });
23786
+ }
23787
+ function installationVersion(value) {
23788
+ if (typeof value !== "string" || !/^v?\d+(?:\.\d+){1,3}(?:-[\w.-]+)?(?:\+[\w.-]+)?$/.test(value.trim()))
23789
+ throw new Error("Harness returned an invalid version");
23790
+ return value.trim().replace(/^v/, "");
23791
+ }
23792
+ function versionFromOutput(output) {
23793
+ return installationVersion(output.match(/\b\d+(?:\.\d+){1,3}(?:-[\w.-]+)?(?:\+[\w.-]+)?\b/)?.[0]);
23794
+ }
23795
+ function newerInstallationVersion(current, latest) {
23796
+ const a = installationVersion(current).replace(/\+.*/, "");
23797
+ const b = installationVersion(latest).replace(/\+.*/, "");
23798
+ const coreA = a.replace(/-.*/, "").split(".").map(BigInt);
23799
+ const coreB = b.replace(/-.*/, "").split(".").map(BigInt);
23800
+ for (let i = 0; i < Math.max(coreA.length, coreB.length); i++) {
23801
+ if ((coreA[i] ?? 0n) !== (coreB[i] ?? 0n))
23802
+ return (coreB[i] ?? 0n) > (coreA[i] ?? 0n);
23803
+ }
23804
+ const preA = a.includes("-") ? a.slice(a.indexOf("-") + 1).split(".") : [];
23805
+ const preB = b.includes("-") ? b.slice(b.indexOf("-") + 1).split(".") : [];
23806
+ if (!preA.length || !preB.length)
23807
+ return !!preA.length && !preB.length;
23808
+ for (let i = 0; i < Math.max(preA.length, preB.length); i++) {
23809
+ const x = preA[i];
23810
+ const y = preB[i];
23811
+ if (x === y)
23812
+ continue;
23813
+ if (x === void 0 || y === void 0)
23814
+ return x === void 0;
23815
+ const numericX = /^\d+$/.test(x);
23816
+ const numericY = /^\d+$/.test(y);
23817
+ if (numericX && numericY) {
23818
+ if (BigInt(x) === BigInt(y))
23819
+ continue;
23820
+ return BigInt(y) > BigInt(x);
23821
+ }
23822
+ if (numericX !== numericY)
23823
+ return numericX;
23824
+ return y > x;
23825
+ }
23826
+ return false;
23827
+ }
23828
+ async function fetchInstallationText(url2) {
23829
+ const request = async () => {
23830
+ const response = await fetch(url2, { signal: AbortSignal.timeout(15e3) });
23831
+ if (!response.ok)
23832
+ throw new Error("Could not check the latest Harness version");
23833
+ return response.text();
23834
+ };
23835
+ try {
23836
+ return await request();
23837
+ } catch (error51) {
23838
+ if (error51 instanceof DOMException && (error51.name === "AbortError" || error51.name === "TimeoutError"))
23839
+ throw error51;
23840
+ return request();
23841
+ }
23842
+ }
23843
+
23511
23844
  // ../codebuddy/dist/command.js
23512
23845
  var codeBuddyDiscoverySpec = {
23513
23846
  id: "codebuddy",
@@ -23607,7 +23940,7 @@ var CodeBuddyAcpClient = class {
23607
23940
  return { outcome: "cancelled" };
23608
23941
  return options.handlers.question(params);
23609
23942
  }
23610
- }), ndJsonStream2(Writable.toWeb(this.#child.stdin), Readable2.toWeb(this.#copyCleanup?.protocolOutput(this.#child.stdout) ?? this.#child.stdout)));
23943
+ }), ndJsonStream2(Writable.toWeb(this.#child.stdin), Readable2.toWeb(this.#copyCleanup?.protocolOutput(this.#child.stdout) ?? (invocation.arguments.includes("--serve") ? codeBuddyAcpOutput(this.#child.stdout) : this.#child.stdout))));
23611
23944
  void this.#connection.closed.then(() => {
23612
23945
  this.#fault(new CodeBuddyError("processExited", "ACP connection closed"));
23613
23946
  }).catch((error51) => {
@@ -23700,7 +24033,7 @@ var CodeBuddyAcpClient = class {
23700
24033
  }
23701
24034
  const pid = this.#child.pid;
23702
24035
  if (pid && process.platform === "win32") {
23703
- await new Promise((resolve) => execFile2("taskkill", ["/PID", String(pid), "/T", "/F"], { windowsHide: true, timeout: 3e3 }, () => resolve()));
24036
+ await new Promise((resolve) => execFile3("taskkill", ["/PID", String(pid), "/T", "/F"], { windowsHide: true, timeout: 3e3 }, () => resolve()));
23704
24037
  } else if (pid) {
23705
24038
  try {
23706
24039
  process.kill(-pid, "SIGKILL");
@@ -23713,7 +24046,7 @@ var CodeBuddyAcpClient = class {
23713
24046
 
23714
24047
  // ../codebuddy/dist/derivation.js
23715
24048
  import { randomUUID as randomUUID3 } from "node:crypto";
23716
- import { execFile as execFile3, spawn as spawn2 } from "node:child_process";
24049
+ import { execFile as execFile4, spawn as spawn2 } from "node:child_process";
23717
24050
  import { lstat as lstat3, mkdir, readFile as readFile3, realpath as realpath4, unlink, writeFile } from "node:fs/promises";
23718
24051
  import path8 from "node:path";
23719
24052
  import { isDeepStrictEqual as isDeepStrictEqual3 } from "node:util";
@@ -23963,7 +24296,7 @@ async function copyCodeBuddySession(cwd, sourceId, targetId, environment, signal
23963
24296
  child.stderr.destroy();
23964
24297
  } else if (process.platform === "win32" && child.pid) {
23965
24298
  termination = new Promise((done) => {
23966
- execFile3("taskkill", ["/PID", String(child.pid), "/T", "/F"], { windowsHide: true, timeout: 3e3 }, () => {
24299
+ execFile4("taskkill", ["/PID", String(child.pid), "/T", "/F"], { windowsHide: true, timeout: 3e3 }, () => {
23967
24300
  child.kill();
23968
24301
  done();
23969
24302
  });
@@ -25634,6 +25967,8 @@ var CodeBuddySession = class {
25634
25967
  async #execute(command, nativeCommand = false) {
25635
25968
  if (this.#closed || this.#fault)
25636
25969
  return failure("invalidState", "Session is closed or faulted", this.profile);
25970
+ if (command.type === "turn.steer")
25971
+ return unsupportedSteer(this.profile.displayName);
25637
25972
  if (command.type === "interaction.respond")
25638
25973
  return this.#interactions.respond(command);
25639
25974
  if (command.type === "turn.cancel") {
@@ -25992,8 +26327,9 @@ var CodeBuddyAdapter = class {
25992
26327
  };
25993
26328
 
25994
26329
  // dist/command.js
25995
- import { lstatSync } from "node:fs";
25996
- import { homedir as homedir2 } from "node:os";
26330
+ import { lstatSync, statSync } from "node:fs";
26331
+ import { randomBytes as randomBytes2 } from "node:crypto";
26332
+ import { homedir as homedir3 } from "node:os";
25997
26333
 
25998
26334
  // dist/delegation.js
25999
26335
  var DELEGATION_ENVIRONMENT_KEYS = [
@@ -26068,8 +26404,57 @@ var WORKBUDDY_CREDENTIAL_PRELOAD = String.raw`
26068
26404
  socketPath = path.join(directory, "c");
26069
26405
  }
26070
26406
  const cleanup = () => {
26407
+ clearTimeout(readyTimer);
26408
+ readyServer && readyServer.close();
26409
+ for (const connection of readyConnections) connection.destroy();
26071
26410
  if (directory) try { fs.rmSync(directory, {recursive:true,force:true}); } catch {}
26072
26411
  };
26412
+ const needsReady = process.argv.includes("--serve");
26413
+ let credentialReady = false;
26414
+ let runtimeReady = !needsReady;
26415
+ let readyTimer;
26416
+ let readyServer;
26417
+ const readyConnections = new Set();
26418
+ const cleanupWhenReady = () => {
26419
+ if (!credentialReady || !runtimeReady) return;
26420
+ cleanup();
26421
+ process.removeListener("exit", cleanup);
26422
+ };
26423
+ if (needsReady) {
26424
+ readyServer = net.createServer(connection => {
26425
+ readyConnections.add(connection);
26426
+ connection.once("close", () => readyConnections.delete(connection));
26427
+ connection.on("error", () => connection.destroy());
26428
+ let input = "";
26429
+ connection.on("data", chunk => {
26430
+ input += chunk;
26431
+ if (input.length > 4096) return connection.destroy();
26432
+ if (!input.includes("\n")) return;
26433
+ try {
26434
+ const request = JSON.parse(input.slice(0, input.indexOf("\n")));
26435
+ const params = request.params;
26436
+ if (request.jsonrpc !== "2.0" || request.method !== "session.ready" ||
26437
+ typeof request.id !== "string" || params?.protocolVersion !== 1 ||
26438
+ params.token !== token || params.sessionId !== sessionId || params.pid !== process.pid ||
26439
+ !Number.isInteger(params.port) || params.port < 1 || params.port > 65535) {
26440
+ connection.destroy();
26441
+ return;
26442
+ }
26443
+ runtimeReady = true;
26444
+ connection.end(JSON.stringify({jsonrpc:"2.0",id:request.id,result:{ok:true}}) + "\n", cleanupWhenReady);
26445
+ } catch { connection.destroy(); }
26446
+ });
26447
+ });
26448
+ readyServer.once("error", () => {
26449
+ process.stderr.write("WorkBuddy runtime readiness listener failed\n");
26450
+ process.exit(1);
26451
+ });
26452
+ readyServer.listen(socketPath + "-ready");
26453
+ readyTimer = setTimeout(() => {
26454
+ process.stderr.write("WorkBuddy runtime readiness timed out\n");
26455
+ process.exit(1);
26456
+ }, 15000);
26457
+ }
26073
26458
  process.once("exit", cleanup);
26074
26459
  Object.assign(env, {
26075
26460
  WORKBUDDY_AT_REST_ENCRYPTION: "fields",
@@ -26092,8 +26477,8 @@ var WORKBUDDY_CREDENTIAL_PRELOAD = String.raw`
26092
26477
  clearTimeout(timer);
26093
26478
  socket && socket.destroy();
26094
26479
  message = "";
26095
- cleanup();
26096
- process.removeListener("exit", cleanup);
26480
+ credentialReady = success;
26481
+ if (success) cleanupWhenReady();
26097
26482
  if (!success) {
26098
26483
  process.stderr.write("WorkBuddy credential bootstrap failed\n");
26099
26484
  process.exit(1);
@@ -26232,7 +26617,7 @@ function bundledProductConfigPath(environment, platform, dependencies) {
26232
26617
  function workBuddyEnvironment(environment, platform = process.platform) {
26233
26618
  const paths = targetPath(platform);
26234
26619
  const configuredRoot = environment.WORKBUDDY_CONFIG_DIR;
26235
- const root = paths.resolve(configuredRoot?.trim() ? configuredRoot : paths.join(environment.HOME || environment.USERPROFILE || homedir2(), ".workbuddy-ai"));
26620
+ const root = paths.resolve(configuredRoot?.trim() ? configuredRoot : paths.join(environment.HOME || environment.USERPROFILE || homedir3(), ".workbuddy-ai"));
26236
26621
  return {
26237
26622
  ...environment,
26238
26623
  // The bundled core reads CODEBUDDY_CONFIG_DIR. Force both names to one
@@ -26242,9 +26627,7 @@ function workBuddyEnvironment(environment, platform = process.platform) {
26242
26627
  DISABLE_AUTOUPDATER: environment.DISABLE_AUTOUPDATER ?? "1"
26243
26628
  };
26244
26629
  }
26245
- function workBuddyInvocation(environment, ephemeral, dependenciesOrArguments = {}, argumentsOverride) {
26246
- const dependencies = Array.isArray(dependenciesOrArguments) ? {} : dependenciesOrArguments;
26247
- const nativeArguments = Array.isArray(dependenciesOrArguments) ? dependenciesOrArguments : argumentsOverride;
26630
+ function resolveWorkBuddyLaunch(environment, dependencies = {}) {
26248
26631
  const platform = dependencies.platform ?? process.platform;
26249
26632
  const configured = environmentValue(environment, "CODEXHOST_WORKBUDDY_COMMAND")?.trim() || void 0;
26250
26633
  if (!configured && platform !== "darwin" && platform !== "win32")
@@ -26257,6 +26640,29 @@ function workBuddyInvocation(environment, ephemeral, dependenciesOrArguments = {
26257
26640
  const executable = configured && !explicitDesktop && !configuredDirectory ? explicitExecutable : bundle?.executable;
26258
26641
  if (!executable)
26259
26642
  throw new CodeBuddyError("notInstalled", "WorkBuddy AI app or its bundled CLI is unavailable");
26643
+ return { executable, bundle };
26644
+ }
26645
+ function workBuddyInvocation(environment, ephemeral, dependenciesOrArguments = {}, argumentsOverride) {
26646
+ const dependencies = Array.isArray(dependenciesOrArguments) ? {} : dependenciesOrArguments;
26647
+ const nativeArguments = Array.isArray(dependenciesOrArguments) ? dependenciesOrArguments : argumentsOverride;
26648
+ const platform = dependencies.platform ?? process.platform;
26649
+ const { executable, bundle } = resolveWorkBuddyLaunch(environment, dependencies);
26650
+ const paths = targetPath(platform);
26651
+ const cliDist = bundle && paths.join(paths.dirname(paths.dirname(bundle.cli)), "dist");
26652
+ const isFile = dependencies.isFile ?? ((candidate) => {
26653
+ try {
26654
+ return statSync(candidate).isFile();
26655
+ } catch {
26656
+ return false;
26657
+ }
26658
+ });
26659
+ const liteOnly = Boolean(cliDist && isFile(paths.join(cliDist, "codebuddy-lite-wb.mjs")) && !isFile(paths.join(cliDist, "codebuddy.js")) && !isFile(paths.join(cliDist, "codebuddy-headless.js")));
26660
+ const acpArguments = nativeArguments ?? [
26661
+ "--acp",
26662
+ ...ephemeral ? ["--no-session-persistence"] : [],
26663
+ ...workBuddyDelegationArguments(environment, ephemeral)
26664
+ ];
26665
+ const serve = liteOnly && acpArguments.includes("--acp") && !acpArguments.includes("--serve");
26260
26666
  const configuredEnvironment = withNodeRuntimeOnPath(workBuddyEnvironment(environment, platform), process.execPath, platform);
26261
26667
  const productConfigPath = bundle ? bundledProductConfigPath(configuredEnvironment, platform, dependencies) : void 0;
26262
26668
  const childEnvironment = bundle ? {
@@ -26265,17 +26671,20 @@ function workBuddyInvocation(environment, ephemeral, dependenciesOrArguments = {
26265
26671
  // waits for its telemetry channel before copying; normal ACP keeps its policy.
26266
26672
  ...nativeArguments?.includes("--print") && nativeArguments.includes("--fork-session") && configuredEnvironment.DISABLE_TELEMETRY === void 0 ? { DISABLE_TELEMETRY: "1" } : {},
26267
26673
  ...productConfigPath ? { [WORKBUDDY_PRODUCT_CONFIG_PATH_ENV]: productConfigPath } : {},
26674
+ ...liteOnly ? { CODEBUDDY_FORCE_LITE_WB_BUNDLE: "1" } : {},
26675
+ ...serve ? {
26676
+ CODEBUDDY_GATEWAY_AUTH: "password",
26677
+ CODEBUDDY_GATEWAY_PASSWORD: randomBytes2(32).toString("base64url"),
26678
+ CODEBUDDY_GATEWAY_BASE_PATH: ""
26679
+ } : {},
26268
26680
  ELECTRON_RUN_AS_NODE: "1"
26269
26681
  } : configuredEnvironment;
26270
26682
  return {
26271
26683
  ...commandInvocation(executable, [
26272
26684
  ...bundle ? ["--eval", `${WORKBUDDY_CREDENTIAL_PRELOAD}
26273
26685
  require(process.argv[1]);`, bundle.cli] : [],
26274
- ...nativeArguments ?? [
26275
- "--acp",
26276
- ...ephemeral ? ["--no-session-persistence"] : [],
26277
- ...workBuddyDelegationArguments(childEnvironment, ephemeral)
26278
- ]
26686
+ ...acpArguments,
26687
+ ...serve ? ["--serve", "--host", "127.0.0.1", "--port", "0", "--auth", "password"] : []
26279
26688
  ], childEnvironment, platform),
26280
26689
  environment: childEnvironment
26281
26690
  };
@@ -26480,14 +26889,95 @@ var WorkBuddyAdapter = class extends CodeBuddyAdapter {
26480
26889
  }
26481
26890
  };
26482
26891
 
26892
+ // dist/installation.js
26893
+ import { readFile as readFile6, stat as stat5 } from "node:fs/promises";
26894
+ var applicationNotice = {
26895
+ en: "These are WorkBuddy desktop app versions. Its bundled CLI updates with the app. Download the official installer, complete installation, then reopen Connections to verify the version. Existing sessions keep their running CLI.",
26896
+ "zh-CN": "此处显示 WorkBuddy 桌面应用版本,内置 CLI 随应用更新。请下载官方安装包并完成安装,再重新打开连接页确认版本。已有会话继续使用运行中的 CLI。"
26897
+ };
26898
+ function appVersion(value) {
26899
+ const version2 = installationVersion(value);
26900
+ return version2.replace(/^(\d+\.\d+\.\d+)\.\d+$/u, "$1");
26901
+ }
26902
+ async function readProduct(file2) {
26903
+ const metadata = await stat5(file2);
26904
+ if (!metadata.isFile() || metadata.size <= 0 || metadata.size > 8 * 1024 * 1024)
26905
+ throw new Error("WorkBuddy product metadata is unavailable");
26906
+ return JSON.parse(await readFile6(file2, "utf8"));
26907
+ }
26908
+ function createWorkBuddyInstallation(environment, dependencies = {}) {
26909
+ const platform = dependencies.platform ?? process.platform;
26910
+ const arch = dependencies.arch ?? process.arch;
26911
+ return async (action) => {
26912
+ if (action === "update")
26913
+ throw new Error("Complete the update with WorkBuddy's official desktop installer");
26914
+ const { executable, bundle } = resolveWorkBuddyLaunch(environment, { platform });
26915
+ if (!bundle)
26916
+ return {
26917
+ currentVersion: versionFromOutput(await runInstallationCommand(executable, ["--version"], environment)),
26918
+ latestVersion: "Unknown",
26919
+ latestVersionKind: "unknown",
26920
+ updateAvailable: false,
26921
+ canUpdate: false,
26922
+ notice: {
26923
+ en: "This is a custom CLI. Use its original installer to update; WorkBuddy desktop releases do not identify this CLI's latest version.",
26924
+ "zh-CN": "当前使用自定义 CLI,请通过原安装方式更新;WorkBuddy 桌面应用版本不代表此 CLI 的最新版本。"
26925
+ }
26926
+ };
26927
+ const paths = targetPath(platform);
26928
+ const product = await (dependencies.readProduct ?? readProduct)(paths.join(paths.dirname(paths.dirname(bundle.cli)), "product.json"));
26929
+ const currentVersion = appVersion(product.genieVersion);
26930
+ const unknown2 = {
26931
+ currentVersion,
26932
+ versionKind: "application",
26933
+ latestVersion: "Unknown",
26934
+ latestVersionKind: "unknown",
26935
+ updateAvailable: false,
26936
+ canUpdate: false,
26937
+ notice: {
26938
+ en: "The installed WorkBuddy desktop app version is shown. Check and install updates in WorkBuddy itself; this installation's update channel could not be checked here.",
26939
+ "zh-CN": "此处显示已安装的 WorkBuddy 桌面应用版本。当前无法查询此安装的更新渠道,请在 WorkBuddy 应用内检查并安装更新。"
26940
+ }
26941
+ };
26942
+ const root = product.applicationName === "workbuddy-ai" && product.updateUrl === "https://www.workbuddy.ai" ? "https://www.workbuddy.ai" : product.applicationName === "workbuddy" && product.updateUrl === "https://www.workbuddy.cn" ? "https://www.workbuddy.cn" : void 0;
26943
+ const target = platform === "darwin" && (arch === "arm64" || arch === "x64") ? `darwin-${arch}` : platform === "win32" && arch === "x64" ? "win32-x64-user" : void 0;
26944
+ if (!root || !target || environment.WORKBUDDY_UPDATE_URL?.trim() && environment.WORKBUDDY_UPDATE_URL.trim() !== root)
26945
+ return unknown2;
26946
+ try {
26947
+ const feed = JSON.parse(await (dependencies.fetchText ?? fetchInstallationText)(`${root}/v2/update?platform=workbuddy-${target}`));
26948
+ const feedVersion = installationVersion(feed.version);
26949
+ const latestVersion = appVersion(feedVersion);
26950
+ const download = new URL(typeof feed.url === "string" ? feed.url : "");
26951
+ const downloadHost = root.endsWith(".ai") ? "download.codebuddy.ai" : "download.codebuddy.cn";
26952
+ if (download.origin !== `https://${downloadHost}` || download.username || download.password || download.search || download.hash || !download.pathname.startsWith(`/workbuddy/saas/${target}/WorkBuddy-${target}-${feedVersion}-`) || !download.pathname.endsWith(platform === "darwin" ? ".zip" : ".exe"))
26953
+ throw new Error("WorkBuddy update feed returned an invalid installer URL");
26954
+ if (platform === "darwin")
26955
+ download.pathname = download.pathname.replace(/\.zip$/u, ".dmg");
26956
+ const updateAvailable = newerInstallationVersion(currentVersion, latestVersion);
26957
+ return {
26958
+ currentVersion,
26959
+ versionKind: "application",
26960
+ latestVersion,
26961
+ updateAvailable,
26962
+ canUpdate: false,
26963
+ ...updateAvailable ? { manualUpdateUrl: download.href } : {},
26964
+ notice: applicationNotice
26965
+ };
26966
+ } catch {
26967
+ return unknown2;
26968
+ }
26969
+ };
26970
+ }
26971
+
26483
26972
  // dist/plugin.js
26484
26973
  function createHarnessAdapter(context) {
26485
26974
  if (context.platform === "darwin" && context.managedRemoteHost) {
26486
- const environment = {
26975
+ const environment2 = {
26487
26976
  ...context.environment,
26488
26977
  ...context.launchCommand ? { CODEXHOST_WORKBUDDY_COMMAND: context.launchCommand } : {}
26489
26978
  };
26490
26979
  return new BrokeredHarnessAdapter({
26980
+ sessionImport: true,
26491
26981
  accountCredits: false,
26492
26982
  harnessId: "workbuddy",
26493
26983
  commandCatalog: WORKBUDDY_COMMAND_CATALOG,
@@ -26495,7 +26985,7 @@ function createHarnessAdapter(context) {
26495
26985
  environment: { ...context.environment },
26496
26986
  isInstalled: () => {
26497
26987
  try {
26498
- workBuddyInvocation(environment, true);
26988
+ workBuddyInvocation(environment2, true);
26499
26989
  return true;
26500
26990
  } catch (error51) {
26501
26991
  return !(error51 instanceof CodeBuddyError && error51.code === "notInstalled");
@@ -26504,11 +26994,12 @@ function createHarnessAdapter(context) {
26504
26994
  ...context.brokerDescriptorPath ? { descriptorPath: context.brokerDescriptorPath } : {}
26505
26995
  });
26506
26996
  }
26507
- return new WorkBuddyAdapter({
26508
- environment: {
26509
- ...context.environment,
26510
- ...context.launchCommand ? { CODEXHOST_WORKBUDDY_COMMAND: context.launchCommand } : {}
26511
- }
26997
+ const environment = {
26998
+ ...context.environment,
26999
+ ...context.launchCommand ? { CODEXHOST_WORKBUDDY_COMMAND: context.launchCommand } : {}
27000
+ };
27001
+ return Object.assign(new WorkBuddyAdapter({ environment }), {
27002
+ installation: createWorkBuddyInstallation(environment)
26512
27003
  });
26513
27004
  }
26514
27005
  export {