@karlorz/codexhost-cli-win32-arm64 0.13.3-6 → 0.14.0-0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/README.md +1 -1
  2. package/app/codexhost-distribution.json +1 -1
  3. package/app/console-server.mjs +539 -95
  4. package/app/console-web.js +879 -73
  5. package/app/cpa-live-voice-hook.js +605 -37
  6. package/app/desktop-controller.mjs +94 -9
  7. package/app/host-runtime.mjs +1662 -642
  8. package/app/plugins/antigravity/plugin.mjs +113 -13
  9. package/app/plugins/claude-code/plugin.mjs +429 -26
  10. package/app/plugins/codebuddy/plugin.mjs +139 -22
  11. package/app/plugins/codex-usage/plugin.mjs +198 -74
  12. package/app/plugins/copilot/assets/icon.png +0 -0
  13. package/app/plugins/copilot/manifest.json +26 -0
  14. package/app/plugins/copilot/plugin.mjs +34645 -0
  15. package/app/plugins/cursor-cli/plugin.mjs +20877 -44973
  16. package/app/plugins/deepseek-harness/plugin.mjs +105 -11
  17. package/app/plugins/enabled.json +1 -0
  18. package/app/plugins/grok/plugin.mjs +1073 -214
  19. package/app/plugins/hermes/plugin.mjs +102 -9
  20. package/app/plugins/kimi-code/plugin.mjs +98 -7
  21. package/app/plugins/kiro-cli/plugin.mjs +98 -7
  22. package/app/plugins/omp/plugin.mjs +2177 -2000
  23. package/app/plugins/opencode/plugin.mjs +107 -11
  24. package/app/plugins/pi/plugin.mjs +2554 -2285
  25. package/app/plugins/qoder/plugin.mjs +105 -11
  26. package/app/plugins/qoder-cn/plugin.mjs +105 -11
  27. package/app/plugins/workbuddy/plugin.mjs +400 -46
  28. package/app/plugins/zcode/plugin.mjs +106 -11
  29. package/app/renderer-extension.js +2717 -1237
  30. package/bin/codexhost.exe +0 -0
  31. package/libexec/codexhost-node-repl.exe +0 -0
  32. package/libexec/codexhost-shim.exe +0 -0
  33. package/libexec/codexhost-updater.exe +0 -0
  34. package/package.json +1 -1
@@ -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),
@@ -14832,8 +14841,12 @@ var CONSOLE_HOST_METHODS = Object.freeze([
14832
14841
  "codexhost/harness/display-settings/set",
14833
14842
  "codexhost/harness/inspect",
14834
14843
  "codexhost/harness/installation",
14844
+ "codexhost/harness/installation/start",
14845
+ "codexhost/harness/installation/status",
14835
14846
  "codexhost/harness/launch-settings/get",
14836
14847
  "codexhost/harness/launch-settings/set",
14848
+ "codexhost/harness/grok-computer-use/get",
14849
+ "codexhost/harness/grok-computer-use/set",
14837
14850
  "codexhost/harness/web-ui/open",
14838
14851
  "codexhost/harness/accounts/sources",
14839
14852
  "codexhost/harness/accounts/list",
@@ -14907,7 +14920,18 @@ var threadManualCompactionStartedSchema = external_exports.strictObject({
14907
14920
  var nonNegativeSafeIntegerSchema = external_exports.number().int().safe().nonnegative();
14908
14921
  var finiteNonNegativeNumberSchema = external_exports.number().finite().nonnegative();
14909
14922
  var cacheHitRatePercentSchema = external_exports.number().finite().min(0).max(100);
14923
+ var indicatorTextSchema = (maximum) => harnessLocalizedTextSchema.refine((entries) => Object.values(entries).every((text2) => text2.length <= maximum));
14924
+ var composerIndicatorsSchema = external_exports.array(external_exports.object({
14925
+ kind: external_exports.literal("countdown"),
14926
+ id: external_exports.string().min(1).max(64),
14927
+ expiresAtUnix: nonNegativeSafeIntegerSchema,
14928
+ label: indicatorTextSchema(256).optional(),
14929
+ tooltip: indicatorTextSchema(1024).optional()
14930
+ }).strict()).max(2).refine((entries) => new Set(entries.map(({ id }) => id)).size === entries.length, {
14931
+ message: "Composer indicator IDs must be unique"
14932
+ });
14910
14933
  var threadUsageSnapshotSchema = external_exports.object({
14934
+ composerIndicators: composerIndicatorsSchema.optional(),
14911
14935
  inputTokens: nonNegativeSafeIntegerSchema.optional(),
14912
14936
  cachedInputTokens: nonNegativeSafeIntegerSchema.optional(),
14913
14937
  cacheWriteInputTokens: nonNegativeSafeIntegerSchema.optional(),
@@ -15315,7 +15339,9 @@ var harnessSessionCapabilitiesSchema = external_exports.object({
15315
15339
  }).strict().optional(),
15316
15340
  autonomousTurns: external_exports.object({
15317
15341
  observe: external_exports.boolean()
15318
- }).strict().optional()
15342
+ }).strict().optional(),
15343
+ /** True only when `turn.steer` delivers input into the active Turn through a native primitive. */
15344
+ steer: external_exports.boolean().optional()
15319
15345
  }).strict();
15320
15346
  var harnessConfigurationStateSchema = external_exports.object({
15321
15347
  effectiveModel: harnessModelRefSchema.optional(),
@@ -15362,7 +15388,9 @@ var harnessInspectionSchema = external_exports.union([
15362
15388
  var harnessInspectParamsSchema = external_exports.object({
15363
15389
  harnessId: harnessIdSchema,
15364
15390
  cwd: nonBlankTextSchema2.max(16384).optional(),
15365
- refresh: external_exports.boolean().optional()
15391
+ refresh: external_exports.boolean().optional(),
15392
+ /** `availability` asks only whether the Harness can run; see `InspectHarnessInput.purpose`. */
15393
+ purpose: external_exports.literal("availability").optional()
15366
15394
  }).strict();
15367
15395
  var harnessWebUiOpenParamsSchema = external_exports.object({
15368
15396
  harnessId: harnessIdSchema
@@ -15445,6 +15473,15 @@ var threadOwnershipListResultSchema = external_exports.object({
15445
15473
  seen.add(thread.threadId);
15446
15474
  }
15447
15475
  });
15476
+ var threadSteeringInspectParamsSchema = external_exports.object({
15477
+ threadId: hostThreadIdSchema,
15478
+ /** The text about to be steered; a Harness command always stops and restarts. */
15479
+ text: external_exports.string().optional()
15480
+ }).strict();
15481
+ var threadSteerDeliverySchema = external_exports.enum(["activeTurn", "newTurn"]);
15482
+ var threadSteeringInspectResultSchema = external_exports.object({
15483
+ delivery: external_exports.enum(["official", "activeTurn", "newTurn"])
15484
+ }).strict();
15448
15485
 
15449
15486
  // ../../shared-contracts/dist/harness-plugins.js
15450
15487
  var HARNESS_PLUGIN_MANIFEST_MAX_BYTES = 32 * 1024;
@@ -15536,6 +15573,26 @@ var harnessLaunchSettingsSchema = external_exports.object({
15536
15573
  restartRequired: external_exports.boolean()
15537
15574
  }).strict();
15538
15575
 
15576
+ // ../../shared-contracts/dist/grok-computer-use.js
15577
+ var grokComputerUseGetSchema = external_exports.object({}).strict();
15578
+ var grokComputerUseSetSchema = external_exports.object({
15579
+ enabled: external_exports.boolean().optional(),
15580
+ browser: external_exports.boolean().optional()
15581
+ }).strict().refine((value) => value.enabled !== void 0 || value.browser !== void 0, {
15582
+ message: "Expected enabled or browser"
15583
+ });
15584
+ var grokComputerUseSettingsSchema = external_exports.object({
15585
+ enabled: external_exports.boolean(),
15586
+ available: external_exports.boolean(),
15587
+ unavailableReason: external_exports.string().min(1).max(500).optional(),
15588
+ browser: external_exports.boolean().optional(),
15589
+ browserFilesPresent: external_exports.boolean().optional(),
15590
+ browserAvailable: external_exports.boolean().optional(),
15591
+ browserUnavailableReason: external_exports.string().min(1).max(500).optional(),
15592
+ applyFailed: external_exports.boolean().optional(),
15593
+ applyError: external_exports.string().min(1).max(500).optional()
15594
+ }).strict();
15595
+
15539
15596
  // ../../shared-contracts/dist/harness-installation.js
15540
15597
  var harnessInstallationParamsSchema = external_exports.object({
15541
15598
  harnessId: harnessIdSchema,
@@ -15546,6 +15603,10 @@ var harnessInstallationStateSchema = external_exports.object({
15546
15603
  latestVersion: external_exports.string().min(1).max(128),
15547
15604
  updateAvailable: external_exports.boolean(),
15548
15605
  canUpdate: external_exports.boolean(),
15606
+ /** Defaults to CLI; some Harnesses ship only inside a desktop application. */
15607
+ versionKind: external_exports.enum(["cli", "application"]).optional(),
15608
+ /** Official download opened by the user; does not imply an automatic installation. */
15609
+ manualUpdateUrl: external_exports.url().max(2048).refine((value) => /^https:\/\/[^/?#@]+(?:[/?#]|$)/iu.test(value), "Manual updates require a credential-free HTTPS URL").optional(),
15549
15610
  // Adapter-owned diagnostic text; UI uses messageCode rather than displaying it verbatim.
15550
15611
  message: external_exports.string().max(2048).optional(),
15551
15612
  messageCode: external_exports.string().min(1).max(128).optional(),
@@ -15553,6 +15614,20 @@ var harnessInstallationStateSchema = external_exports.object({
15553
15614
  notice: harnessLocalizedTextSchema.optional(),
15554
15615
  latestVersionKind: external_exports.enum(["unknown", "tracking-branch"]).optional()
15555
15616
  }).strict();
15617
+ var harnessInstallationTaskParamsSchema = external_exports.object({ taskId: external_exports.string().uuid() }).strict();
15618
+ var harnessInstallationTaskSchema = external_exports.discriminatedUnion("status", [
15619
+ external_exports.object({ taskId: external_exports.string().uuid(), status: external_exports.literal("running") }).strict(),
15620
+ external_exports.object({
15621
+ taskId: external_exports.string().uuid(),
15622
+ status: external_exports.literal("succeeded"),
15623
+ result: harnessInstallationStateSchema
15624
+ }).strict(),
15625
+ external_exports.object({
15626
+ taskId: external_exports.string().uuid(),
15627
+ status: external_exports.literal("failed"),
15628
+ error: external_exports.object({ code: external_exports.number().int(), message: external_exports.string().min(1).max(2048) }).strict()
15629
+ }).strict()
15630
+ ]);
15556
15631
 
15557
15632
  // ../../shared-contracts/dist/codex-accounts.js
15558
15633
  var accountIdSchema = external_exports.string().min(1).max(256).regex(/^[A-Za-z0-9._~-]+$/u);
@@ -16101,6 +16176,18 @@ function sanitizeDiagnosticTail(value) {
16101
16176
  return redacted.length <= DIAGNOSTIC_TAIL_MAX_LENGTH ? redacted : redacted.slice(-DIAGNOSTIC_TAIL_MAX_LENGTH);
16102
16177
  }
16103
16178
 
16179
+ // ../../harness-adapter/dist/steer.js
16180
+ function unsupportedSteer(harnessLabel) {
16181
+ return {
16182
+ ok: false,
16183
+ error: {
16184
+ code: "unsupported",
16185
+ message: `${harnessLabel} cannot steer an active Turn natively`,
16186
+ retryable: false
16187
+ }
16188
+ };
16189
+ }
16190
+
16104
16191
  // ../../harness-adapter/dist/usage.js
16105
16192
  var tokenFields = [
16106
16193
  "inputTokens",
@@ -16128,6 +16215,7 @@ var usageFields = /* @__PURE__ */ new Set([
16128
16215
  ...safeIntegerFields,
16129
16216
  ...percentFields,
16130
16217
  "sessionCacheUsage",
16218
+ "composerIndicators",
16131
16219
  "totalCostUsd",
16132
16220
  "totalCredits",
16133
16221
  "contextUsagePercent",
@@ -16150,6 +16238,7 @@ function parseHostUsage(value) {
16150
16238
  throw new Error(`Harness Usage contains unknown field '${key}'`);
16151
16239
  }
16152
16240
  }
16241
+ const indicators = value.composerIndicators === void 0 ? {} : { composerIndicators: composerIndicatorsSchema.parse(value.composerIndicators) };
16153
16242
  for (const field of [
16154
16243
  "totalCredits",
16155
16244
  "contextUsagePercent",
@@ -16220,9 +16309,9 @@ function parseHostUsage(value) {
16220
16309
  if (value.costSource !== "publicPrice") {
16221
16310
  throw new Error("Harness Usage 'unpricedModels' must be provided with a 'publicPrice' cost");
16222
16311
  }
16223
- return { ...value, unpricedModels: [...models] };
16312
+ return { ...value, ...indicators, unpricedModels: [...models] };
16224
16313
  }
16225
- return { ...value };
16314
+ return { ...value, ...indicators };
16226
16315
  }
16227
16316
  var requestTokenFields = [
16228
16317
  "inputTokens",
@@ -16379,6 +16468,7 @@ var harnessBrokerMethodSchema = external_exports.enum([
16379
16468
  "adapter.open",
16380
16469
  "adapter.subagent.readSnapshot",
16381
16470
  "session.readSnapshot",
16471
+ "session.readCapabilities",
16382
16472
  "session.refreshUsage",
16383
16473
  "session.execute",
16384
16474
  "session.commands.list",
@@ -16559,6 +16649,11 @@ var turnStartSchema = external_exports.object({
16559
16649
  turnId: hostTurnIdSchema,
16560
16650
  input: external_exports.array(textInputSchema)
16561
16651
  }).strict();
16652
+ var turnSteerSchema = external_exports.object({
16653
+ type: external_exports.literal("turn.steer"),
16654
+ turnId: hostTurnIdSchema,
16655
+ input: external_exports.array(textInputSchema)
16656
+ }).strict();
16562
16657
  var turnCancelSchema = external_exports.object({ type: external_exports.literal("turn.cancel"), turnId: hostTurnIdSchema }).strict();
16563
16658
  var interactionResponseSchema = external_exports.union([
16564
16659
  external_exports.object({
@@ -16584,6 +16679,7 @@ var permissionSelectSchema = external_exports.object({
16584
16679
  }).strict();
16585
16680
  var brokerHostCommandSchema = external_exports.discriminatedUnion("type", [
16586
16681
  turnStartSchema,
16682
+ turnSteerSchema,
16587
16683
  turnCancelSchema,
16588
16684
  interactionRespondSchema,
16589
16685
  modelSelectSchema,
@@ -16776,6 +16872,7 @@ function parseSessionMetadata(value) {
16776
16872
  sessionId: candidate.sessionId,
16777
16873
  sessionGeneration: candidate.sessionGeneration,
16778
16874
  capabilities: harnessSessionCapabilitiesSchema.parse(candidate.capabilities),
16875
+ readCapabilities: candidate.readCapabilities === true,
16779
16876
  initialState: state,
16780
16877
  initialUsage: candidate.initialUsage === null ? null : parseHostUsage(candidate.initialUsage),
16781
16878
  commands: candidate.commands === true
@@ -17127,6 +17224,11 @@ var BrokeredHarnessSession = class {
17127
17224
  event: { type: "session.faulted", error: unavailable(error51.message) }
17128
17225
  });
17129
17226
  }
17227
+ async readCapabilities() {
17228
+ if (!this.#metadata.readCapabilities)
17229
+ return { ...this.capabilities, steer: false };
17230
+ return harnessSessionCapabilitiesSchema.parse(await this.#request("session.readCapabilities", {}));
17231
+ }
17130
17232
  async refreshUsage() {
17131
17233
  await this.#request("session.refreshUsage", {});
17132
17234
  }
@@ -17158,6 +17260,8 @@ var BrokeredHarnessSession = class {
17158
17260
  try {
17159
17261
  return parseHarnessResult(await this.#request("session.execute", { command }));
17160
17262
  } catch (error51) {
17263
+ if (command.type === "turn.steer")
17264
+ throw error51;
17161
17265
  return {
17162
17266
  ok: false,
17163
17267
  error: unavailable(error51 instanceof Error ? error51.message : String(error51))
@@ -17468,10 +17572,13 @@ function usageSessionTitle(value) {
17468
17572
  return void 0;
17469
17573
  if (normalized.length <= MAX_SESSION_TITLE_LENGTH)
17470
17574
  return normalized;
17471
- const characters = [...normalized];
17472
- if (characters.length <= MAX_SESSION_TITLE_LENGTH)
17473
- return normalized;
17474
- return `${characters.slice(0, MAX_SESSION_TITLE_LENGTH - 1).join("").trimEnd()}…`;
17575
+ let title = "";
17576
+ for (const character of normalized) {
17577
+ if (title.length + character.length >= MAX_SESSION_TITLE_LENGTH)
17578
+ break;
17579
+ title += character;
17580
+ }
17581
+ return `${title.trimEnd()}…`;
17475
17582
  }
17476
17583
  function sessionIdOk(value) {
17477
17584
  return typeof value === "string" && value.length > 0 && value.length <= MAX_SESSION_ID_LENGTH;
@@ -19113,7 +19220,7 @@ function createCodeBuddyUsageStatistics(environment, profile) {
19113
19220
  import { stat as stat3 } from "node:fs/promises";
19114
19221
 
19115
19222
  // ../codebuddy/dist/acp-client.js
19116
- import { execFile as execFile2, spawn } from "node:child_process";
19223
+ import { execFile as execFile3, spawn } from "node:child_process";
19117
19224
  import { Readable as Readable2, Writable } from "node:stream";
19118
19225
 
19119
19226
  // ../../../node_modules/@agentclientprotocol/sdk/dist/schema/index.js
@@ -23278,9 +23385,23 @@ var ClientSideConnection = class {
23278
23385
 
23279
23386
  // ../codebuddy/dist/copy-cleanup.js
23280
23387
  import { randomBytes } from "node:crypto";
23388
+
23389
+ // ../codebuddy/dist/acp-stdio.js
23281
23390
  import { createInterface as createInterface2 } from "node:readline";
23282
- import { stripVTControlCharacters } from "node:util";
23283
23391
  import { Readable } from "node:stream";
23392
+ import { stripVTControlCharacters } from "node:util";
23393
+ function codeBuddyAcpOutput(stdout, onLine) {
23394
+ return Readable.from((async function* () {
23395
+ for await (const line of createInterface2({ input: stdout })) {
23396
+ onLine?.(stripVTControlCharacters(line));
23397
+ if (line.trimStart().startsWith("{"))
23398
+ yield Buffer.from(`${line}
23399
+ `);
23400
+ }
23401
+ })());
23402
+ }
23403
+
23404
+ // ../codebuddy/dist/copy-cleanup.js
23284
23405
  var CodeBuddyCopyCleanup = class {
23285
23406
  copyId;
23286
23407
  cwd;
@@ -23310,17 +23431,11 @@ var CodeBuddyCopyCleanup = class {
23310
23431
  }
23311
23432
  /** Native --serve banners include its password; never pass them to the ACP parser/logs. */
23312
23433
  protocolOutput(stdout) {
23313
- return Readable.from(this.#protocolLines(stdout));
23314
- }
23315
- async *#protocolLines(stdout) {
23316
- for await (const line of createInterface2({ input: stdout })) {
23317
- const endpoint = /^\s*Endpoint\s+(http:\/\/127\.0\.0\.1:\d+)\s*$/u.exec(stripVTControlCharacters(line));
23434
+ return codeBuddyAcpOutput(stdout, (line) => {
23435
+ const endpoint = /^\s*Endpoint\s+(http:\/\/127\.0\.0\.1:\d+)\s*$/u.exec(line);
23318
23436
  if (endpoint)
23319
23437
  this.#endpoint = endpoint[1];
23320
- if (line.trimStart().startsWith("{"))
23321
- yield Buffer.from(`${line}
23322
- `);
23323
- }
23438
+ });
23324
23439
  }
23325
23440
  async remove() {
23326
23441
  if (!this.#endpoint)
@@ -23585,6 +23700,88 @@ function resolveHarnessExecutable(spec, input, dependencies = {}) {
23585
23700
  return void 0;
23586
23701
  }
23587
23702
 
23703
+ // ../../harness-discovery/dist/installation.js
23704
+ import { execFile as execFile2 } from "node:child_process";
23705
+ import { homedir as homedir2 } from "node:os";
23706
+ function runInstallationCommand(command, args, environment, timeout = 3e4) {
23707
+ const env = withNodeRuntimeOnPath(environment);
23708
+ const invocation = /\.[cm]?js$/i.test(command) ? commandInvocation(process.execPath, [command, ...args], env) : commandInvocation(command, args, env);
23709
+ return new Promise((resolve, reject) => {
23710
+ const child = execFile2(invocation.command, invocation.arguments, {
23711
+ env,
23712
+ cwd: env.HOME ?? env.USERPROFILE ?? homedir2(),
23713
+ encoding: "utf8",
23714
+ timeout,
23715
+ killSignal: "SIGKILL",
23716
+ maxBuffer: 1024 * 1024,
23717
+ windowsHide: true,
23718
+ windowsVerbatimArguments: invocation.windowsVerbatimArguments
23719
+ }, (error51, stdout, stderr) => {
23720
+ if (error51)
23721
+ reject(new Error(error51.killed ? "Harness command timed out" : "Harness command failed; check the native installation and retry"));
23722
+ else
23723
+ resolve((stdout || stderr).trim());
23724
+ });
23725
+ child.stdin?.end();
23726
+ });
23727
+ }
23728
+ function installationVersion(value) {
23729
+ if (typeof value !== "string" || !/^v?\d+(?:\.\d+){1,3}(?:-[\w.-]+)?(?:\+[\w.-]+)?$/.test(value.trim()))
23730
+ throw new Error("Harness returned an invalid version");
23731
+ return value.trim().replace(/^v/, "");
23732
+ }
23733
+ function versionFromOutput(output) {
23734
+ return installationVersion(output.match(/\b\d+(?:\.\d+){1,3}(?:-[\w.-]+)?(?:\+[\w.-]+)?\b/)?.[0]);
23735
+ }
23736
+ function newerInstallationVersion(current, latest) {
23737
+ const a = installationVersion(current).replace(/\+.*/, "");
23738
+ const b = installationVersion(latest).replace(/\+.*/, "");
23739
+ const coreA = a.replace(/-.*/, "").split(".").map(BigInt);
23740
+ const coreB = b.replace(/-.*/, "").split(".").map(BigInt);
23741
+ for (let i = 0; i < Math.max(coreA.length, coreB.length); i++) {
23742
+ if ((coreA[i] ?? 0n) !== (coreB[i] ?? 0n))
23743
+ return (coreB[i] ?? 0n) > (coreA[i] ?? 0n);
23744
+ }
23745
+ const preA = a.includes("-") ? a.slice(a.indexOf("-") + 1).split(".") : [];
23746
+ const preB = b.includes("-") ? b.slice(b.indexOf("-") + 1).split(".") : [];
23747
+ if (!preA.length || !preB.length)
23748
+ return !!preA.length && !preB.length;
23749
+ for (let i = 0; i < Math.max(preA.length, preB.length); i++) {
23750
+ const x = preA[i];
23751
+ const y = preB[i];
23752
+ if (x === y)
23753
+ continue;
23754
+ if (x === void 0 || y === void 0)
23755
+ return x === void 0;
23756
+ const numericX = /^\d+$/.test(x);
23757
+ const numericY = /^\d+$/.test(y);
23758
+ if (numericX && numericY) {
23759
+ if (BigInt(x) === BigInt(y))
23760
+ continue;
23761
+ return BigInt(y) > BigInt(x);
23762
+ }
23763
+ if (numericX !== numericY)
23764
+ return numericX;
23765
+ return y > x;
23766
+ }
23767
+ return false;
23768
+ }
23769
+ async function fetchInstallationText(url2) {
23770
+ const request = async () => {
23771
+ const response = await fetch(url2, { signal: AbortSignal.timeout(15e3) });
23772
+ if (!response.ok)
23773
+ throw new Error("Could not check the latest Harness version");
23774
+ return response.text();
23775
+ };
23776
+ try {
23777
+ return await request();
23778
+ } catch (error51) {
23779
+ if (error51 instanceof DOMException && (error51.name === "AbortError" || error51.name === "TimeoutError"))
23780
+ throw error51;
23781
+ return request();
23782
+ }
23783
+ }
23784
+
23588
23785
  // ../codebuddy/dist/command.js
23589
23786
  var codeBuddyDiscoverySpec = {
23590
23787
  id: "codebuddy",
@@ -23684,7 +23881,7 @@ var CodeBuddyAcpClient = class {
23684
23881
  return { outcome: "cancelled" };
23685
23882
  return options.handlers.question(params);
23686
23883
  }
23687
- }), ndJsonStream2(Writable.toWeb(this.#child.stdin), Readable2.toWeb(this.#copyCleanup?.protocolOutput(this.#child.stdout) ?? this.#child.stdout)));
23884
+ }), 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))));
23688
23885
  void this.#connection.closed.then(() => {
23689
23886
  this.#fault(new CodeBuddyError("processExited", "ACP connection closed"));
23690
23887
  }).catch((error51) => {
@@ -23777,7 +23974,7 @@ var CodeBuddyAcpClient = class {
23777
23974
  }
23778
23975
  const pid = this.#child.pid;
23779
23976
  if (pid && process.platform === "win32") {
23780
- await new Promise((resolve) => execFile2("taskkill", ["/PID", String(pid), "/T", "/F"], { windowsHide: true, timeout: 3e3 }, () => resolve()));
23977
+ await new Promise((resolve) => execFile3("taskkill", ["/PID", String(pid), "/T", "/F"], { windowsHide: true, timeout: 3e3 }, () => resolve()));
23781
23978
  } else if (pid) {
23782
23979
  try {
23783
23980
  process.kill(-pid, "SIGKILL");
@@ -23790,7 +23987,7 @@ var CodeBuddyAcpClient = class {
23790
23987
 
23791
23988
  // ../codebuddy/dist/derivation.js
23792
23989
  import { randomUUID as randomUUID3 } from "node:crypto";
23793
- import { execFile as execFile3, spawn as spawn2 } from "node:child_process";
23990
+ import { execFile as execFile4, spawn as spawn2 } from "node:child_process";
23794
23991
  import { lstat as lstat3, mkdir, readFile as readFile3, realpath as realpath4, unlink, writeFile } from "node:fs/promises";
23795
23992
  import path8 from "node:path";
23796
23993
  import { isDeepStrictEqual as isDeepStrictEqual3 } from "node:util";
@@ -24040,7 +24237,7 @@ async function copyCodeBuddySession(cwd, sourceId, targetId, environment, signal
24040
24237
  child.stderr.destroy();
24041
24238
  } else if (process.platform === "win32" && child.pid) {
24042
24239
  termination = new Promise((done) => {
24043
- execFile3("taskkill", ["/PID", String(child.pid), "/T", "/F"], { windowsHide: true, timeout: 3e3 }, () => {
24240
+ execFile4("taskkill", ["/PID", String(child.pid), "/T", "/F"], { windowsHide: true, timeout: 3e3 }, () => {
24044
24241
  child.kill();
24045
24242
  done();
24046
24243
  });
@@ -25711,6 +25908,8 @@ var CodeBuddySession = class {
25711
25908
  async #execute(command, nativeCommand = false) {
25712
25909
  if (this.#closed || this.#fault)
25713
25910
  return failure("invalidState", "Session is closed or faulted", this.profile);
25911
+ if (command.type === "turn.steer")
25912
+ return unsupportedSteer(this.profile.displayName);
25714
25913
  if (command.type === "interaction.respond")
25715
25914
  return this.#interactions.respond(command);
25716
25915
  if (command.type === "turn.cancel") {
@@ -26069,8 +26268,9 @@ var CodeBuddyAdapter = class {
26069
26268
  };
26070
26269
 
26071
26270
  // dist/command.js
26072
- import { lstatSync } from "node:fs";
26073
- import { homedir as homedir2 } from "node:os";
26271
+ import { lstatSync, statSync } from "node:fs";
26272
+ import { randomBytes as randomBytes2 } from "node:crypto";
26273
+ import { homedir as homedir3 } from "node:os";
26074
26274
 
26075
26275
  // dist/delegation.js
26076
26276
  var DELEGATION_ENVIRONMENT_KEYS = [
@@ -26145,8 +26345,57 @@ var WORKBUDDY_CREDENTIAL_PRELOAD = String.raw`
26145
26345
  socketPath = path.join(directory, "c");
26146
26346
  }
26147
26347
  const cleanup = () => {
26348
+ clearTimeout(readyTimer);
26349
+ readyServer && readyServer.close();
26350
+ for (const connection of readyConnections) connection.destroy();
26148
26351
  if (directory) try { fs.rmSync(directory, {recursive:true,force:true}); } catch {}
26149
26352
  };
26353
+ const needsReady = process.argv.includes("--serve");
26354
+ let credentialReady = false;
26355
+ let runtimeReady = !needsReady;
26356
+ let readyTimer;
26357
+ let readyServer;
26358
+ const readyConnections = new Set();
26359
+ const cleanupWhenReady = () => {
26360
+ if (!credentialReady || !runtimeReady) return;
26361
+ cleanup();
26362
+ process.removeListener("exit", cleanup);
26363
+ };
26364
+ if (needsReady) {
26365
+ readyServer = net.createServer(connection => {
26366
+ readyConnections.add(connection);
26367
+ connection.once("close", () => readyConnections.delete(connection));
26368
+ connection.on("error", () => connection.destroy());
26369
+ let input = "";
26370
+ connection.on("data", chunk => {
26371
+ input += chunk;
26372
+ if (input.length > 4096) return connection.destroy();
26373
+ if (!input.includes("\n")) return;
26374
+ try {
26375
+ const request = JSON.parse(input.slice(0, input.indexOf("\n")));
26376
+ const params = request.params;
26377
+ if (request.jsonrpc !== "2.0" || request.method !== "session.ready" ||
26378
+ typeof request.id !== "string" || params?.protocolVersion !== 1 ||
26379
+ params.token !== token || params.sessionId !== sessionId || params.pid !== process.pid ||
26380
+ !Number.isInteger(params.port) || params.port < 1 || params.port > 65535) {
26381
+ connection.destroy();
26382
+ return;
26383
+ }
26384
+ runtimeReady = true;
26385
+ connection.end(JSON.stringify({jsonrpc:"2.0",id:request.id,result:{ok:true}}) + "\n", cleanupWhenReady);
26386
+ } catch { connection.destroy(); }
26387
+ });
26388
+ });
26389
+ readyServer.once("error", () => {
26390
+ process.stderr.write("WorkBuddy runtime readiness listener failed\n");
26391
+ process.exit(1);
26392
+ });
26393
+ readyServer.listen(socketPath + "-ready");
26394
+ readyTimer = setTimeout(() => {
26395
+ process.stderr.write("WorkBuddy runtime readiness timed out\n");
26396
+ process.exit(1);
26397
+ }, 15000);
26398
+ }
26150
26399
  process.once("exit", cleanup);
26151
26400
  Object.assign(env, {
26152
26401
  WORKBUDDY_AT_REST_ENCRYPTION: "fields",
@@ -26169,8 +26418,8 @@ var WORKBUDDY_CREDENTIAL_PRELOAD = String.raw`
26169
26418
  clearTimeout(timer);
26170
26419
  socket && socket.destroy();
26171
26420
  message = "";
26172
- cleanup();
26173
- process.removeListener("exit", cleanup);
26421
+ credentialReady = success;
26422
+ if (success) cleanupWhenReady();
26174
26423
  if (!success) {
26175
26424
  process.stderr.write("WorkBuddy credential bootstrap failed\n");
26176
26425
  process.exit(1);
@@ -26309,7 +26558,7 @@ function bundledProductConfigPath(environment, platform, dependencies) {
26309
26558
  function workBuddyEnvironment(environment, platform = process.platform) {
26310
26559
  const paths = targetPath(platform);
26311
26560
  const configuredRoot = environment.WORKBUDDY_CONFIG_DIR;
26312
- const root = paths.resolve(configuredRoot?.trim() ? configuredRoot : paths.join(environment.HOME || environment.USERPROFILE || homedir2(), ".workbuddy-ai"));
26561
+ const root = paths.resolve(configuredRoot?.trim() ? configuredRoot : paths.join(environment.HOME || environment.USERPROFILE || homedir3(), ".workbuddy-ai"));
26313
26562
  return {
26314
26563
  ...environment,
26315
26564
  // The bundled core reads CODEBUDDY_CONFIG_DIR. Force both names to one
@@ -26319,9 +26568,7 @@ function workBuddyEnvironment(environment, platform = process.platform) {
26319
26568
  DISABLE_AUTOUPDATER: environment.DISABLE_AUTOUPDATER ?? "1"
26320
26569
  };
26321
26570
  }
26322
- function workBuddyInvocation(environment, ephemeral, dependenciesOrArguments = {}, argumentsOverride) {
26323
- const dependencies = Array.isArray(dependenciesOrArguments) ? {} : dependenciesOrArguments;
26324
- const nativeArguments = Array.isArray(dependenciesOrArguments) ? dependenciesOrArguments : argumentsOverride;
26571
+ function resolveWorkBuddyLaunch(environment, dependencies = {}) {
26325
26572
  const platform = dependencies.platform ?? process.platform;
26326
26573
  const configured = environmentValue(environment, "CODEXHOST_WORKBUDDY_COMMAND")?.trim() || void 0;
26327
26574
  if (!configured && platform !== "darwin" && platform !== "win32")
@@ -26334,6 +26581,29 @@ function workBuddyInvocation(environment, ephemeral, dependenciesOrArguments = {
26334
26581
  const executable = configured && !explicitDesktop && !configuredDirectory ? explicitExecutable : bundle?.executable;
26335
26582
  if (!executable)
26336
26583
  throw new CodeBuddyError("notInstalled", "WorkBuddy AI app or its bundled CLI is unavailable");
26584
+ return { executable, bundle };
26585
+ }
26586
+ function workBuddyInvocation(environment, ephemeral, dependenciesOrArguments = {}, argumentsOverride) {
26587
+ const dependencies = Array.isArray(dependenciesOrArguments) ? {} : dependenciesOrArguments;
26588
+ const nativeArguments = Array.isArray(dependenciesOrArguments) ? dependenciesOrArguments : argumentsOverride;
26589
+ const platform = dependencies.platform ?? process.platform;
26590
+ const { executable, bundle } = resolveWorkBuddyLaunch(environment, dependencies);
26591
+ const paths = targetPath(platform);
26592
+ const cliDist = bundle && paths.join(paths.dirname(paths.dirname(bundle.cli)), "dist");
26593
+ const isFile = dependencies.isFile ?? ((candidate) => {
26594
+ try {
26595
+ return statSync(candidate).isFile();
26596
+ } catch {
26597
+ return false;
26598
+ }
26599
+ });
26600
+ 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")));
26601
+ const acpArguments = nativeArguments ?? [
26602
+ "--acp",
26603
+ ...ephemeral ? ["--no-session-persistence"] : [],
26604
+ ...workBuddyDelegationArguments(environment, ephemeral)
26605
+ ];
26606
+ const serve = liteOnly && acpArguments.includes("--acp") && !acpArguments.includes("--serve");
26337
26607
  const configuredEnvironment = withNodeRuntimeOnPath(workBuddyEnvironment(environment, platform), process.execPath, platform);
26338
26608
  const productConfigPath = bundle ? bundledProductConfigPath(configuredEnvironment, platform, dependencies) : void 0;
26339
26609
  const childEnvironment = bundle ? {
@@ -26342,17 +26612,20 @@ function workBuddyInvocation(environment, ephemeral, dependenciesOrArguments = {
26342
26612
  // waits for its telemetry channel before copying; normal ACP keeps its policy.
26343
26613
  ...nativeArguments?.includes("--print") && nativeArguments.includes("--fork-session") && configuredEnvironment.DISABLE_TELEMETRY === void 0 ? { DISABLE_TELEMETRY: "1" } : {},
26344
26614
  ...productConfigPath ? { [WORKBUDDY_PRODUCT_CONFIG_PATH_ENV]: productConfigPath } : {},
26615
+ ...liteOnly ? { CODEBUDDY_FORCE_LITE_WB_BUNDLE: "1" } : {},
26616
+ ...serve ? {
26617
+ CODEBUDDY_GATEWAY_AUTH: "password",
26618
+ CODEBUDDY_GATEWAY_PASSWORD: randomBytes2(32).toString("base64url"),
26619
+ CODEBUDDY_GATEWAY_BASE_PATH: ""
26620
+ } : {},
26345
26621
  ELECTRON_RUN_AS_NODE: "1"
26346
26622
  } : configuredEnvironment;
26347
26623
  return {
26348
26624
  ...commandInvocation(executable, [
26349
26625
  ...bundle ? ["--eval", `${WORKBUDDY_CREDENTIAL_PRELOAD}
26350
26626
  require(process.argv[1]);`, bundle.cli] : [],
26351
- ...nativeArguments ?? [
26352
- "--acp",
26353
- ...ephemeral ? ["--no-session-persistence"] : [],
26354
- ...workBuddyDelegationArguments(childEnvironment, ephemeral)
26355
- ]
26627
+ ...acpArguments,
26628
+ ...serve ? ["--serve", "--host", "127.0.0.1", "--port", "0", "--auth", "password"] : []
26356
26629
  ], childEnvironment, platform),
26357
26630
  environment: childEnvironment
26358
26631
  };
@@ -26557,10 +26830,90 @@ var WorkBuddyAdapter = class extends CodeBuddyAdapter {
26557
26830
  }
26558
26831
  };
26559
26832
 
26833
+ // dist/installation.js
26834
+ import { readFile as readFile6, stat as stat5 } from "node:fs/promises";
26835
+ var applicationNotice = {
26836
+ 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.",
26837
+ "zh-CN": "此处显示 WorkBuddy 桌面应用版本,内置 CLI 随应用更新。请下载官方安装包并完成安装,再重新打开连接页确认版本。已有会话继续使用运行中的 CLI。"
26838
+ };
26839
+ function appVersion(value) {
26840
+ const version2 = installationVersion(value);
26841
+ return version2.replace(/^(\d+\.\d+\.\d+)\.\d+$/u, "$1");
26842
+ }
26843
+ async function readProduct(file2) {
26844
+ const metadata = await stat5(file2);
26845
+ if (!metadata.isFile() || metadata.size <= 0 || metadata.size > 8 * 1024 * 1024)
26846
+ throw new Error("WorkBuddy product metadata is unavailable");
26847
+ return JSON.parse(await readFile6(file2, "utf8"));
26848
+ }
26849
+ function createWorkBuddyInstallation(environment, dependencies = {}) {
26850
+ const platform = dependencies.platform ?? process.platform;
26851
+ const arch = dependencies.arch ?? process.arch;
26852
+ return async (action) => {
26853
+ if (action === "update")
26854
+ throw new Error("Complete the update with WorkBuddy's official desktop installer");
26855
+ const { executable, bundle } = resolveWorkBuddyLaunch(environment, { platform });
26856
+ if (!bundle)
26857
+ return {
26858
+ currentVersion: versionFromOutput(await runInstallationCommand(executable, ["--version"], environment)),
26859
+ latestVersion: "Unknown",
26860
+ latestVersionKind: "unknown",
26861
+ updateAvailable: false,
26862
+ canUpdate: false,
26863
+ notice: {
26864
+ en: "This is a custom CLI. Use its original installer to update; WorkBuddy desktop releases do not identify this CLI's latest version.",
26865
+ "zh-CN": "当前使用自定义 CLI,请通过原安装方式更新;WorkBuddy 桌面应用版本不代表此 CLI 的最新版本。"
26866
+ }
26867
+ };
26868
+ const paths = targetPath(platform);
26869
+ const product = await (dependencies.readProduct ?? readProduct)(paths.join(paths.dirname(paths.dirname(bundle.cli)), "product.json"));
26870
+ const currentVersion = appVersion(product.genieVersion);
26871
+ const unknown2 = {
26872
+ currentVersion,
26873
+ versionKind: "application",
26874
+ latestVersion: "Unknown",
26875
+ latestVersionKind: "unknown",
26876
+ updateAvailable: false,
26877
+ canUpdate: false,
26878
+ notice: {
26879
+ 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.",
26880
+ "zh-CN": "此处显示已安装的 WorkBuddy 桌面应用版本。当前无法查询此安装的更新渠道,请在 WorkBuddy 应用内检查并安装更新。"
26881
+ }
26882
+ };
26883
+ 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;
26884
+ const target = platform === "darwin" && (arch === "arm64" || arch === "x64") ? `darwin-${arch}` : platform === "win32" && arch === "x64" ? "win32-x64-user" : void 0;
26885
+ if (!root || !target || environment.WORKBUDDY_UPDATE_URL?.trim() && environment.WORKBUDDY_UPDATE_URL.trim() !== root)
26886
+ return unknown2;
26887
+ try {
26888
+ const feed = JSON.parse(await (dependencies.fetchText ?? fetchInstallationText)(`${root}/v2/update?platform=workbuddy-${target}`));
26889
+ const feedVersion = installationVersion(feed.version);
26890
+ const latestVersion = appVersion(feedVersion);
26891
+ const download = new URL(typeof feed.url === "string" ? feed.url : "");
26892
+ const downloadHost = root.endsWith(".ai") ? "download.codebuddy.ai" : "download.codebuddy.cn";
26893
+ 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"))
26894
+ throw new Error("WorkBuddy update feed returned an invalid installer URL");
26895
+ if (platform === "darwin")
26896
+ download.pathname = download.pathname.replace(/\.zip$/u, ".dmg");
26897
+ const updateAvailable = newerInstallationVersion(currentVersion, latestVersion);
26898
+ return {
26899
+ currentVersion,
26900
+ versionKind: "application",
26901
+ latestVersion,
26902
+ updateAvailable,
26903
+ canUpdate: false,
26904
+ ...updateAvailable ? { manualUpdateUrl: download.href } : {},
26905
+ notice: applicationNotice
26906
+ };
26907
+ } catch {
26908
+ return unknown2;
26909
+ }
26910
+ };
26911
+ }
26912
+
26560
26913
  // dist/plugin.js
26561
26914
  function createHarnessAdapter(context) {
26562
26915
  if (context.platform === "darwin" && context.managedRemoteHost) {
26563
- const environment = {
26916
+ const environment2 = {
26564
26917
  ...context.environment,
26565
26918
  ...context.launchCommand ? { CODEXHOST_WORKBUDDY_COMMAND: context.launchCommand } : {}
26566
26919
  };
@@ -26572,7 +26925,7 @@ function createHarnessAdapter(context) {
26572
26925
  environment: { ...context.environment },
26573
26926
  isInstalled: () => {
26574
26927
  try {
26575
- workBuddyInvocation(environment, true);
26928
+ workBuddyInvocation(environment2, true);
26576
26929
  return true;
26577
26930
  } catch (error51) {
26578
26931
  return !(error51 instanceof CodeBuddyError && error51.code === "notInstalled");
@@ -26581,11 +26934,12 @@ function createHarnessAdapter(context) {
26581
26934
  ...context.brokerDescriptorPath ? { descriptorPath: context.brokerDescriptorPath } : {}
26582
26935
  });
26583
26936
  }
26584
- return new WorkBuddyAdapter({
26585
- environment: {
26586
- ...context.environment,
26587
- ...context.launchCommand ? { CODEXHOST_WORKBUDDY_COMMAND: context.launchCommand } : {}
26588
- }
26937
+ const environment = {
26938
+ ...context.environment,
26939
+ ...context.launchCommand ? { CODEXHOST_WORKBUDDY_COMMAND: context.launchCommand } : {}
26940
+ };
26941
+ return Object.assign(new WorkBuddyAdapter({ environment }), {
26942
+ installation: createWorkBuddyInstallation(environment)
26589
26943
  });
26590
26944
  }
26591
26945
  export {