oh-my-opencode 4.0.0 → 4.1.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 (94) hide show
  1. package/README.ja.md +28 -3
  2. package/README.ko.md +28 -3
  3. package/README.md +28 -3
  4. package/README.ru.md +28 -3
  5. package/README.zh-cn.md +28 -3
  6. package/dist/agents/atlas/agent.d.ts +7 -12
  7. package/dist/agents/atlas/default-prompt-sections.d.ts +5 -5
  8. package/dist/agents/atlas/gemini-prompt-sections.d.ts +4 -4
  9. package/dist/agents/atlas/gpt-prompt-sections.d.ts +5 -5
  10. package/dist/agents/atlas/kimi-prompt-sections.d.ts +6 -0
  11. package/dist/agents/atlas/kimi.d.ts +2 -0
  12. package/dist/agents/atlas/opus-4-7-prompt-sections.d.ts +6 -0
  13. package/dist/agents/atlas/opus-4-7.d.ts +2 -0
  14. package/dist/agents/atlas/shared-prompt.d.ts +1 -1
  15. package/dist/agents/prometheus/plan-generation.d.ts +1 -1
  16. package/dist/cli/boulder/boulder.d.ts +2 -0
  17. package/dist/cli/boulder/formatter.d.ts +5 -0
  18. package/dist/cli/boulder/index.d.ts +1 -0
  19. package/dist/cli/boulder/types.d.ts +30 -0
  20. package/dist/cli/doctor/checks/system-binary.d.ts +2 -0
  21. package/dist/cli/index.js +1122 -456
  22. package/dist/config/schema/hooks.d.ts +1 -0
  23. package/dist/config/schema/oh-my-opencode-config.d.ts +1 -0
  24. package/dist/create-hooks.d.ts +1 -0
  25. package/dist/create-managers.d.ts +2 -0
  26. package/dist/features/background-agent/manager.d.ts +3 -0
  27. package/dist/features/background-agent/spawner.d.ts +4 -2
  28. package/dist/features/background-agent/task-poller.d.ts +1 -0
  29. package/dist/features/background-agent/types.d.ts +1 -0
  30. package/dist/features/boulder-state/format-duration.d.ts +1 -0
  31. package/dist/features/boulder-state/index.d.ts +1 -0
  32. package/dist/features/boulder-state/storage.d.ts +39 -1
  33. package/dist/features/boulder-state/types.d.ts +43 -0
  34. package/dist/features/builtin-commands/templates/start-work.d.ts +1 -1
  35. package/dist/features/team-mode/team-runtime/session-cleanup.d.ts +21 -0
  36. package/dist/features/team-mode/team-runtime/session-team-run-registry.d.ts +4 -0
  37. package/dist/features/tmux-subagent/cleanup.d.ts +10 -0
  38. package/dist/features/tmux-subagent/session-created-handler.d.ts +23 -0
  39. package/dist/features/tmux-subagent/session-deleted-handler.d.ts +16 -0
  40. package/dist/hooks/atlas/system-reminder-templates.d.ts +1 -0
  41. package/dist/hooks/atlas/tool-execute-after.d.ts +1 -0
  42. package/dist/hooks/atlas/tool-execute-before.d.ts +1 -0
  43. package/dist/hooks/atlas/types.d.ts +2 -0
  44. package/dist/hooks/compaction-context-injector/recovery.d.ts +1 -1
  45. package/dist/hooks/compaction-context-injector/types.d.ts +1 -0
  46. package/dist/hooks/compaction-todo-preserver/hook.d.ts +11 -0
  47. package/dist/hooks/fsync-skip-warning/index.d.ts +18 -0
  48. package/dist/hooks/index.d.ts +1 -0
  49. package/dist/hooks/ralph-loop/continuation-prompt-injector.d.ts +7 -1
  50. package/dist/hooks/ralph-loop/iteration-continuation.d.ts +9 -1
  51. package/dist/hooks/ralph-loop/loop-state-controller.d.ts +1 -0
  52. package/dist/hooks/ralph-loop/pending-verification-handler.d.ts +3 -0
  53. package/dist/hooks/ralph-loop/ralph-loop-event-handler.d.ts +2 -0
  54. package/dist/hooks/ralph-loop/types.d.ts +1 -0
  55. package/dist/hooks/ralph-loop/verification-failure-handler.d.ts +3 -1
  56. package/dist/hooks/shared/session-idle-settle.d.ts +2 -0
  57. package/dist/hooks/team-session-events/team-idle-wake-hint.d.ts +4 -1
  58. package/dist/hooks/todo-description-override/description.d.ts +1 -1
  59. package/dist/hooks/unstable-agent-babysitter/unstable-agent-babysitter-hook.d.ts +1 -0
  60. package/dist/index.js +5426 -2387
  61. package/dist/oh-my-opencode.schema.json +8 -0
  62. package/dist/plugin/hooks/create-core-hooks.d.ts +1 -0
  63. package/dist/plugin/hooks/create-tool-guard-hooks.d.ts +2 -1
  64. package/dist/plugin/session-compacting.d.ts +31 -0
  65. package/dist/plugin-dispose.d.ts +13 -0
  66. package/dist/plugin-handlers/agent-priority-order.d.ts +6 -6
  67. package/dist/shared/agent-ordering.d.ts +8 -0
  68. package/dist/shared/agent-sort-shim.d.ts +8 -8
  69. package/dist/shared/agent-tool-restrictions.d.ts +5 -1
  70. package/dist/shared/bun-file-shim.d.ts +8 -0
  71. package/dist/shared/bun-hash-shim.d.ts +1 -0
  72. package/dist/shared/bun-which-shim.d.ts +1 -0
  73. package/dist/shared/classify-path-environment.d.ts +3 -0
  74. package/dist/shared/event-session-id.d.ts +2 -0
  75. package/dist/shared/extract-semver.d.ts +1 -0
  76. package/dist/shared/fsync-skip-tracker.d.ts +12 -0
  77. package/dist/shared/fsync-skip-warning-formatter.d.ts +2 -0
  78. package/dist/shared/index.d.ts +3 -0
  79. package/dist/shared/model-capability-heuristics.d.ts +1 -0
  80. package/dist/shared/opencode-version.d.ts +14 -1
  81. package/dist/shared/session-route.d.ts +18 -0
  82. package/dist/shared/tmux/cmux-detect.d.ts +8 -0
  83. package/dist/shared/tmux/index.d.ts +1 -0
  84. package/dist/shared/tolerant-fsync.d.ts +5 -0
  85. package/dist/shared/write-file-atomically.d.ts +4 -1
  86. package/dist/tools/call-omo-agent/agent-resolver.d.ts +5 -12
  87. package/dist/tools/call-omo-agent/constants.d.ts +2 -2
  88. package/dist/tools/delegate-task/model-string-parser.d.ts +9 -0
  89. package/dist/tools/delegate-task/resolve-call-id.d.ts +2 -0
  90. package/dist/tools/delegate-task/sync-prompt-sender.d.ts +1 -0
  91. package/dist/tools/delegate-task/sync-result-fetcher.d.ts +3 -1
  92. package/dist/tools/interactive-bash/tmux-path-resolver.d.ts +1 -0
  93. package/package.json +21 -15
  94. package/dist/hooks/ralph-loop/completion-promise-detector-test-input.d.ts +0 -11
package/dist/cli/index.js CHANGED
@@ -6214,14 +6214,119 @@ var init_model_versions = __esm(() => {
6214
6214
  // src/shared/migration/agent-category.ts
6215
6215
  var init_agent_category = () => {};
6216
6216
 
6217
+ // src/shared/classify-path-environment.ts
6218
+ import { homedir as homedir2 } from "os";
6219
+ import path3 from "path";
6220
+ function normalizeInputPath(absolutePath) {
6221
+ return absolutePath.replaceAll("\\", "/");
6222
+ }
6223
+ function isUnderPath(normalizedPath, normalizedParentPath) {
6224
+ return normalizedPath === normalizedParentPath || normalizedPath.startsWith(`${normalizedParentPath}/`);
6225
+ }
6226
+ function classifyPathEnvironment(absolutePath) {
6227
+ if (absolutePath.length === 0)
6228
+ return "unknown";
6229
+ const normalizedPath = normalizeInputPath(absolutePath);
6230
+ const lowercasePath = normalizedPath.toLowerCase();
6231
+ if (lowercasePath.includes("/onedrive") || lowercasePath.includes("/onedrive/")) {
6232
+ return "onedrive";
6233
+ }
6234
+ if (normalizedPath.includes("/Library/Mobile Documents/")) {
6235
+ return "icloud";
6236
+ }
6237
+ if (isUnderPath(normalizedPath, "/Volumes")) {
6238
+ return "network-drive";
6239
+ }
6240
+ if (normalizedPath.startsWith("/Users/") && (normalizedPath.includes("/Desktop/") || normalizedPath.endsWith("/Desktop") || normalizedPath.includes("/Documents/") || normalizedPath.endsWith("/Documents"))) {
6241
+ return "desktop-sync";
6242
+ }
6243
+ const normalizedHome = normalizeInputPath(homedir2());
6244
+ const desktopPath = normalizeInputPath(path3.join(normalizedHome, "Desktop"));
6245
+ const documentsPath = normalizeInputPath(path3.join(normalizedHome, "Documents"));
6246
+ if (isUnderPath(normalizedPath, desktopPath) || isUnderPath(normalizedPath, documentsPath)) {
6247
+ return "desktop-sync";
6248
+ }
6249
+ return "unknown";
6250
+ }
6251
+ var init_classify_path_environment = () => {};
6252
+
6253
+ // src/shared/fsync-skip-tracker.ts
6254
+ function recordFsyncSkip(entry) {
6255
+ fsyncSkips.push({ ...entry, timestamp: Date.now() });
6256
+ if (fsyncSkips.length > MAX_SKIPS) {
6257
+ fsyncSkips.splice(0, fsyncSkips.length - MAX_SKIPS);
6258
+ }
6259
+ }
6260
+ var MAX_SKIPS = 200, fsyncSkips;
6261
+ var init_fsync_skip_tracker = __esm(() => {
6262
+ fsyncSkips = [];
6263
+ });
6264
+
6265
+ // src/shared/tolerant-fsync.ts
6266
+ import { fsyncSync } from "fs";
6267
+ function isToleratedFsyncError(error) {
6268
+ if (!(error instanceof Error))
6269
+ return false;
6270
+ const code = error.code;
6271
+ return code !== undefined && TOLERATED_FSYNC_CODES.has(code);
6272
+ }
6273
+ function extractPathFromContextLabel(contextLabel) {
6274
+ const separatorIndex = contextLabel.indexOf(":");
6275
+ if (separatorIndex < 0)
6276
+ return contextLabel;
6277
+ return contextLabel.slice(separatorIndex + 1);
6278
+ }
6279
+ function tolerantFsyncSync(fileDescriptor, contextLabel, fsyncImpl = fsyncSync) {
6280
+ try {
6281
+ fsyncImpl(fileDescriptor);
6282
+ } catch (error) {
6283
+ if (!isToleratedFsyncError(error))
6284
+ throw error;
6285
+ const errorCode = error.code ?? "UNKNOWN";
6286
+ const message = error instanceof Error ? error.message : String(error);
6287
+ const filePath = extractPathFromContextLabel(contextLabel);
6288
+ log("fsync skipped due to filesystem limitation", {
6289
+ event: "fsync-skipped",
6290
+ contextLabel,
6291
+ code: errorCode,
6292
+ message
6293
+ });
6294
+ recordFsyncSkip({
6295
+ filePath,
6296
+ contextLabel,
6297
+ errorCode,
6298
+ message,
6299
+ pathClassification: classifyPathEnvironment(filePath)
6300
+ });
6301
+ }
6302
+ }
6303
+ var TOLERATED_FSYNC_CODES;
6304
+ var init_tolerant_fsync = __esm(() => {
6305
+ init_classify_path_environment();
6306
+ init_fsync_skip_tracker();
6307
+ init_logger();
6308
+ TOLERATED_FSYNC_CODES = new Set([
6309
+ "EPERM",
6310
+ "EACCES",
6311
+ "ENOTSUP",
6312
+ "EINVAL"
6313
+ ]);
6314
+ });
6315
+
6217
6316
  // src/shared/write-file-atomically.ts
6218
- import { closeSync, fsyncSync, openSync, renameSync, unlinkSync, writeFileSync } from "fs";
6219
- function writeFileAtomically(filePath, content) {
6317
+ import {
6318
+ closeSync,
6319
+ openSync,
6320
+ renameSync,
6321
+ unlinkSync,
6322
+ writeFileSync
6323
+ } from "fs";
6324
+ function writeFileAtomically(filePath, content, deps = {}) {
6220
6325
  const tempPath = `${filePath}.tmp`;
6221
6326
  writeFileSync(tempPath, content, "utf-8");
6222
- const tempFileDescriptor = openSync(tempPath, "r");
6327
+ const tempFileDescriptor = openSync(tempPath, "r+");
6223
6328
  try {
6224
- fsyncSync(tempFileDescriptor);
6329
+ tolerantFsyncSync(tempFileDescriptor, `writeFileAtomically:${filePath}`, deps.fsyncSync);
6225
6330
  } finally {
6226
6331
  closeSync(tempFileDescriptor);
6227
6332
  }
@@ -6238,11 +6343,18 @@ function writeFileAtomically(filePath, content) {
6238
6343
  }
6239
6344
  }
6240
6345
  }
6241
- var init_write_file_atomically = () => {};
6346
+ var init_write_file_atomically = __esm(() => {
6347
+ init_tolerant_fsync();
6348
+ });
6349
+
6350
+ // src/shared/record-type-guard.ts
6351
+ function isRecord(value) {
6352
+ return typeof value === "object" && value !== null;
6353
+ }
6242
6354
 
6243
6355
  // src/shared/migration/migrations-sidecar.ts
6244
6356
  import * as fs2 from "fs";
6245
- import * as path3 from "path";
6357
+ import * as path4 from "path";
6246
6358
  function getSidecarPath(configPath) {
6247
6359
  return `${configPath}.migrations.json`;
6248
6360
  }
@@ -6254,8 +6366,8 @@ function readAppliedMigrations(configPath) {
6254
6366
  }
6255
6367
  const content = fs2.readFileSync(sidecarPath, "utf-8");
6256
6368
  const parsed = JSON.parse(content);
6257
- if (parsed && typeof parsed === "object" && !Array.isArray(parsed) && Array.isArray(parsed.appliedMigrations)) {
6258
- return new Set(parsed.appliedMigrations.filter((m) => typeof m === "string"));
6369
+ if (isRecord(parsed) && Array.isArray(parsed.appliedMigrations)) {
6370
+ return new Set(parsed.appliedMigrations.filter((migration) => typeof migration === "string"));
6259
6371
  }
6260
6372
  return new Set;
6261
6373
  } catch (err) {
@@ -6269,7 +6381,7 @@ function writeAppliedMigrations(configPath, migrations) {
6269
6381
  appliedMigrations: Array.from(migrations).sort()
6270
6382
  };
6271
6383
  try {
6272
- const parentDir = path3.dirname(sidecarPath);
6384
+ const parentDir = path4.dirname(sidecarPath);
6273
6385
  if (!fs2.existsSync(parentDir)) {
6274
6386
  fs2.mkdirSync(parentDir, { recursive: true });
6275
6387
  }
@@ -6462,7 +6574,7 @@ var init_migration = __esm(() => {
6462
6574
 
6463
6575
  // src/shared/opencode-config-dir.ts
6464
6576
  import { existsSync as existsSync4, realpathSync as realpathSync3 } from "fs";
6465
- import { homedir as homedir2 } from "os";
6577
+ import { homedir as homedir3 } from "os";
6466
6578
  import { join as join5, resolve as resolve2, win32 } from "path";
6467
6579
  function isDevBuild(version) {
6468
6580
  if (!version)
@@ -6473,14 +6585,14 @@ function getTauriConfigDir(identifier) {
6473
6585
  const platform = process.platform;
6474
6586
  switch (platform) {
6475
6587
  case "darwin":
6476
- return join5(homedir2(), "Library", "Application Support", identifier);
6588
+ return join5(homedir3(), "Library", "Application Support", identifier);
6477
6589
  case "win32": {
6478
- const appData = process.env.APPDATA || join5(homedir2(), "AppData", "Roaming");
6590
+ const appData = process.env.APPDATA || join5(homedir3(), "AppData", "Roaming");
6479
6591
  return win32.join(appData, identifier);
6480
6592
  }
6481
6593
  case "linux":
6482
6594
  default: {
6483
- const xdgConfig = process.env.XDG_CONFIG_HOME || join5(homedir2(), ".config");
6595
+ const xdgConfig = process.env.XDG_CONFIG_HOME || join5(homedir3(), ".config");
6484
6596
  return join5(xdgConfig, identifier);
6485
6597
  }
6486
6598
  }
@@ -6500,7 +6612,7 @@ function getCliConfigDir() {
6500
6612
  if (envConfigDir) {
6501
6613
  return resolveConfigPath(envConfigDir);
6502
6614
  }
6503
- const xdgConfig = process.env.XDG_CONFIG_HOME || join5(homedir2(), ".config");
6615
+ const xdgConfig = process.env.XDG_CONFIG_HOME || join5(homedir3(), ".config");
6504
6616
  return resolveConfigPath(join5(xdgConfig, "opencode"));
6505
6617
  }
6506
6618
  function getOpenCodeConfigDir(options) {
@@ -6537,11 +6649,11 @@ var init_opencode_config_dir = __esm(() => {
6537
6649
  });
6538
6650
 
6539
6651
  // src/shared/resolve-agent-definition-paths.ts
6540
- import { homedir as homedir3 } from "os";
6652
+ import { homedir as homedir4 } from "os";
6541
6653
  import { isAbsolute as isAbsolute2, resolve as resolve3 } from "path";
6542
6654
  function resolveAgentDefinitionPaths(paths, baseDir, containmentDir) {
6543
6655
  return paths.flatMap((p) => {
6544
- const expanded = p.startsWith("~/") ? p.replace(/^~\//, `${homedir3()}/`) : p;
6656
+ const expanded = p.startsWith("~/") ? p.replace(/^~\//, `${homedir4()}/`) : p;
6545
6657
  const resolved = isAbsolute2(expanded) ? expanded : resolve3(baseDir, expanded);
6546
6658
  if (containmentDir !== null && !isWithinProject(resolved, containmentDir)) {
6547
6659
  log(`agent_definitions path rejected (outside project boundary): ${p} -> ${resolved}`);
@@ -6557,6 +6669,8 @@ var init_resolve_agent_definition_paths = __esm(() => {
6557
6669
 
6558
6670
  // src/shared/opencode-version.ts
6559
6671
  import { execSync } from "child_process";
6672
+ import { existsSync as existsSync5, readFileSync as readFileSync4, realpathSync as realpathSync4 } from "fs";
6673
+ import { dirname as dirname3, join as join6 } from "path";
6560
6674
  function parseVersion(version) {
6561
6675
  const cleaned = version.replace(/^v/, "").split("-")[0];
6562
6676
  return cleaned.split(".").map((n) => parseInt(n, 10) || 0);
@@ -6575,12 +6689,51 @@ function compareVersions(a, b) {
6575
6689
  }
6576
6690
  return 0;
6577
6691
  }
6578
- function getOpenCodeVersion() {
6692
+ function isRecord2(value) {
6693
+ return typeof value === "object" && value !== null;
6694
+ }
6695
+ function parsePackageVersion(content) {
6696
+ try {
6697
+ const parsed = JSON.parse(content);
6698
+ if (!isRecord2(parsed))
6699
+ return null;
6700
+ const name = parsed.name;
6701
+ const version = parsed.version;
6702
+ if (typeof name !== "string" || !name.includes("opencode"))
6703
+ return null;
6704
+ if (typeof version !== "string" || version.length === 0)
6705
+ return null;
6706
+ return version;
6707
+ } catch {
6708
+ return null;
6709
+ }
6710
+ }
6711
+ function getPackageVersionFromBinary(binaryPath, deps) {
6712
+ try {
6713
+ const realBinaryPath = deps.realpath(binaryPath);
6714
+ const packagePath = join6(dirname3(dirname3(realBinaryPath)), "package.json");
6715
+ if (!deps.exists(packagePath))
6716
+ return null;
6717
+ return parsePackageVersion(deps.readText(packagePath));
6718
+ } catch {
6719
+ return null;
6720
+ }
6721
+ }
6722
+ function getOpenCodeVersion(deps = {}) {
6579
6723
  if (cachedVersion !== NOT_CACHED) {
6580
6724
  return cachedVersion;
6581
6725
  }
6726
+ const resolvedDeps = { ...defaultDeps, ...deps };
6727
+ const binaryPath = resolvedDeps.getBinaryPath();
6728
+ if (binaryPath) {
6729
+ const packageVersion = getPackageVersionFromBinary(binaryPath, resolvedDeps);
6730
+ if (packageVersion) {
6731
+ cachedVersion = packageVersion;
6732
+ return cachedVersion;
6733
+ }
6734
+ }
6582
6735
  try {
6583
- const result = execSync("opencode --version", {
6736
+ const result = resolvedDeps.execCommand("opencode --version", {
6584
6737
  encoding: "utf-8",
6585
6738
  timeout: 5000,
6586
6739
  stdio: ["pipe", "pipe", "pipe"]
@@ -6599,15 +6752,27 @@ function isOpenCodeVersionAtLeast(version) {
6599
6752
  return true;
6600
6753
  return compareVersions(current, version) >= 0;
6601
6754
  }
6602
- var OPENCODE_SQLITE_VERSION = "1.1.53", NOT_CACHED, cachedVersion;
6755
+ var OPENCODE_SQLITE_VERSION = "1.1.53", NOT_CACHED, cachedVersion, defaultDeps;
6603
6756
  var init_opencode_version = __esm(() => {
6604
6757
  NOT_CACHED = Symbol("NOT_CACHED");
6605
6758
  cachedVersion = NOT_CACHED;
6759
+ defaultDeps = {
6760
+ execCommand: (command, options) => execSync(command, options),
6761
+ getBinaryPath: () => {
6762
+ const envPath = process.env.OPENCODE_BIN_PATH;
6763
+ if (envPath)
6764
+ return envPath;
6765
+ return globalThis.Bun?.which("opencode") ?? null;
6766
+ },
6767
+ exists: existsSync5,
6768
+ realpath: realpathSync4,
6769
+ readText: (filePath) => readFileSync4(filePath, "utf-8")
6770
+ };
6606
6771
  });
6607
6772
 
6608
6773
  // src/shared/opencode-storage-detection.ts
6609
- import { existsSync as existsSync5 } from "fs";
6610
- import { join as join6 } from "path";
6774
+ import { existsSync as existsSync6 } from "fs";
6775
+ import { join as join7 } from "path";
6611
6776
  function isSqliteBackend() {
6612
6777
  if (cachedResult === true)
6613
6778
  return true;
@@ -6615,8 +6780,8 @@ function isSqliteBackend() {
6615
6780
  return false;
6616
6781
  const check = () => {
6617
6782
  const versionOk = isOpenCodeVersionAtLeast(OPENCODE_SQLITE_VERSION);
6618
- const dbPath = join6(getDataDir(), "opencode", "opencode.db");
6619
- return versionOk && existsSync5(dbPath);
6783
+ const dbPath = join7(getDataDir(), "opencode", "opencode.db");
6784
+ return versionOk && existsSync6(dbPath);
6620
6785
  };
6621
6786
  if (cachedResult === FALSE_PENDING_RETRY) {
6622
6787
  const result2 = check();
@@ -6794,15 +6959,23 @@ var init_zip_extractor = __esm(() => {
6794
6959
  init_zip_entry_listing();
6795
6960
  });
6796
6961
 
6962
+ // src/shared/bun-file-shim.ts
6963
+ var runtime2, IS_BUN2;
6964
+ var init_bun_file_shim = __esm(() => {
6965
+ runtime2 = globalThis;
6966
+ IS_BUN2 = typeof runtime2.Bun !== "undefined";
6967
+ });
6968
+
6797
6969
  // src/shared/binary-downloader.ts
6798
- import { chmodSync, existsSync as existsSync6, mkdirSync as mkdirSync3, unlinkSync as unlinkSync2 } from "fs";
6799
- import * as path4 from "path";
6970
+ import { chmodSync, existsSync as existsSync7, mkdirSync as mkdirSync3, unlinkSync as unlinkSync2 } from "fs";
6971
+ import * as path5 from "path";
6800
6972
  function getCachedBinaryPath(cacheDir, binaryName) {
6801
- const binaryPath = path4.join(cacheDir, binaryName);
6802
- return existsSync6(binaryPath) ? binaryPath : null;
6973
+ const binaryPath = path5.join(cacheDir, binaryName);
6974
+ return existsSync7(binaryPath) ? binaryPath : null;
6803
6975
  }
6804
6976
  var init_binary_downloader = __esm(() => {
6805
6977
  init_bun_spawn_shim();
6978
+ init_bun_file_shim();
6806
6979
  init_archive_entry_validator();
6807
6980
  init_zip_extractor();
6808
6981
  });
@@ -6985,6 +7158,10 @@ var init_model_requirements = __esm(() => {
6985
7158
  },
6986
7159
  metis: {
6987
7160
  fallbackChain: [
7161
+ {
7162
+ providers: ["anthropic", "github-copilot", "opencode", "vercel"],
7163
+ model: "claude-sonnet-4-6"
7164
+ },
6988
7165
  {
6989
7166
  providers: ["anthropic", "github-copilot", "opencode", "vercel"],
6990
7167
  model: "claude-opus-4-7",
@@ -7099,7 +7276,9 @@ var init_model_requirements = __esm(() => {
7099
7276
  providers: ["google", "github-copilot", "opencode", "vercel"],
7100
7277
  model: "gemini-3.1-pro",
7101
7278
  variant: "high"
7102
- }
7279
+ },
7280
+ { providers: ["opencode-go", "vercel"], model: "kimi-k2.6" },
7281
+ { providers: ["opencode-go", "vercel"], model: "glm-5.1" }
7103
7282
  ]
7104
7283
  },
7105
7284
  artistry: {
@@ -7114,7 +7293,9 @@ var init_model_requirements = __esm(() => {
7114
7293
  model: "claude-opus-4-7",
7115
7294
  variant: "max"
7116
7295
  },
7117
- { providers: ["openai", "github-copilot", "opencode", "vercel"], model: "gpt-5.5" }
7296
+ { providers: ["openai", "github-copilot", "opencode", "vercel"], model: "gpt-5.5" },
7297
+ { providers: ["opencode-go", "vercel"], model: "kimi-k2.6" },
7298
+ { providers: ["opencode-go", "vercel"], model: "glm-5.1" }
7118
7299
  ]
7119
7300
  },
7120
7301
  quick: {
@@ -7245,8 +7426,8 @@ function normalizeModelID(modelID) {
7245
7426
  }
7246
7427
 
7247
7428
  // src/shared/json-file-cache-store.ts
7248
- import { existsSync as existsSync7, mkdirSync as mkdirSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "fs";
7249
- import { join as join8 } from "path";
7429
+ import { existsSync as existsSync8, mkdirSync as mkdirSync4, readFileSync as readFileSync5, writeFileSync as writeFileSync2 } from "fs";
7430
+ import { join as join9 } from "path";
7250
7431
  function toLogLabel(cacheLabel) {
7251
7432
  return cacheLabel.toLowerCase();
7252
7433
  }
@@ -7254,11 +7435,11 @@ function createJsonFileCacheStore(options) {
7254
7435
  let memoryValue;
7255
7436
  let writtenInCurrentProcess = false;
7256
7437
  function getCacheFilePath() {
7257
- return join8(options.getCacheDir(), options.filename);
7438
+ return join9(options.getCacheDir(), options.filename);
7258
7439
  }
7259
7440
  function ensureCacheDir() {
7260
7441
  const cacheDir = options.getCacheDir();
7261
- if (!existsSync7(cacheDir)) {
7442
+ if (!existsSync8(cacheDir)) {
7262
7443
  mkdirSync4(cacheDir, { recursive: true });
7263
7444
  }
7264
7445
  }
@@ -7267,13 +7448,13 @@ function createJsonFileCacheStore(options) {
7267
7448
  return memoryValue;
7268
7449
  }
7269
7450
  const cacheFile = getCacheFilePath();
7270
- if (!existsSync7(cacheFile)) {
7451
+ if (!existsSync8(cacheFile)) {
7271
7452
  memoryValue = null;
7272
7453
  log(`[${options.logPrefix}] ${options.cacheLabel} file not found`, { cacheFile });
7273
7454
  return null;
7274
7455
  }
7275
7456
  try {
7276
- const content = readFileSync4(cacheFile, "utf-8");
7457
+ const content = readFileSync5(cacheFile, "utf-8");
7277
7458
  const value = JSON.parse(content);
7278
7459
  memoryValue = value;
7279
7460
  log(`[${options.logPrefix}] Read ${toLogLabel(options.cacheLabel)}`, options.describe(value));
@@ -7293,7 +7474,7 @@ function createJsonFileCacheStore(options) {
7293
7474
  if (writtenInCurrentProcess) {
7294
7475
  return true;
7295
7476
  }
7296
- return existsSync7(getCacheFilePath());
7477
+ return existsSync8(getCacheFilePath());
7297
7478
  }
7298
7479
  function write(value) {
7299
7480
  ensureCacheDir();
@@ -7325,7 +7506,7 @@ var init_json_file_cache_store = __esm(() => {
7325
7506
  });
7326
7507
 
7327
7508
  // src/shared/connected-providers-cache.ts
7328
- function isRecord(value) {
7509
+ function isRecord3(value) {
7329
7510
  return typeof value === "object" && value !== null;
7330
7511
  }
7331
7512
  function createConnectedProvidersCacheStore(getCacheDir2 = getOmoOpenCodeCacheDir) {
@@ -7392,7 +7573,7 @@ function createConnectedProvidersCacheStore(getCacheDir2 = getOmoOpenCodeCacheDi
7392
7573
  for (const provider of allProviders) {
7393
7574
  if (provider.models) {
7394
7575
  const modelMetadata = Object.entries(provider.models).map(([modelID, rawMetadata]) => {
7395
- if (!isRecord(rawMetadata)) {
7576
+ if (!isRecord3(rawMetadata)) {
7396
7577
  return { id: modelID };
7397
7578
  }
7398
7579
  const normalizedID = typeof rawMetadata.id === "string" ? rawMetadata.id : modelID;
@@ -7469,14 +7650,14 @@ var init_connected_providers_cache = __esm(() => {
7469
7650
  });
7470
7651
 
7471
7652
  // src/shared/model-availability.ts
7472
- import { existsSync as existsSync8, readFileSync as readFileSync5 } from "fs";
7473
- import { join as join9 } from "path";
7653
+ import { existsSync as existsSync9, readFileSync as readFileSync6 } from "fs";
7654
+ import { join as join10 } from "path";
7474
7655
  function isModelCacheAvailable() {
7475
7656
  if (hasProviderModelsCache()) {
7476
7657
  return true;
7477
7658
  }
7478
- const cacheFile = join9(getOpenCodeCacheDir(), "models.json");
7479
- return existsSync8(cacheFile);
7659
+ const cacheFile = join10(getOpenCodeCacheDir(), "models.json");
7660
+ return existsSync9(cacheFile);
7480
7661
  }
7481
7662
  var init_model_availability = __esm(() => {
7482
7663
  init_logger();
@@ -50237,7 +50418,13 @@ var init_model_capability_heuristics = __esm(() => {
50237
50418
  {
50238
50419
  family: "deepseek",
50239
50420
  includes: ["deepseek"],
50240
- variants: ["low", "medium", "high"]
50421
+ variants: ["low", "medium", "high"],
50422
+ reasoningEfforts: ["high", "max"],
50423
+ reasoningEffortAliases: {
50424
+ low: "high",
50425
+ medium: "high",
50426
+ xhigh: "max"
50427
+ }
50241
50428
  },
50242
50429
  {
50243
50430
  family: "mistral",
@@ -50253,7 +50440,7 @@ var init_model_capability_heuristics = __esm(() => {
50253
50440
  });
50254
50441
 
50255
50442
  // src/shared/model-capabilities/runtime-model-readers.ts
50256
- function isRecord2(value) {
50443
+ function isRecord4(value) {
50257
50444
  return typeof value === "object" && value !== null && !Array.isArray(value);
50258
50445
  }
50259
50446
  function readNumber(value) {
@@ -50271,7 +50458,7 @@ function normalizeVariantKeys(value) {
50271
50458
  if (arrayVariants) {
50272
50459
  return arrayVariants.map((variant) => variant.toLowerCase());
50273
50460
  }
50274
- if (!isRecord2(value)) {
50461
+ if (!isRecord4(value)) {
50275
50462
  return;
50276
50463
  }
50277
50464
  const variants = Object.keys(value).map((variant) => variant.toLowerCase());
@@ -50282,14 +50469,14 @@ function readModalityKeys(value) {
50282
50469
  if (stringArray) {
50283
50470
  return stringArray.map((entry) => entry.toLowerCase());
50284
50471
  }
50285
- if (!isRecord2(value)) {
50472
+ if (!isRecord4(value)) {
50286
50473
  return;
50287
50474
  }
50288
50475
  const enabled = Object.entries(value).filter(([, supported]) => supported === true).map(([modality]) => modality.toLowerCase());
50289
50476
  return enabled.length > 0 ? enabled : undefined;
50290
50477
  }
50291
50478
  function normalizeModalities(value) {
50292
- if (!isRecord2(value)) {
50479
+ if (!isRecord4(value)) {
50293
50480
  return;
50294
50481
  }
50295
50482
  const input = readModalityKeys(value.input);
@@ -50303,7 +50490,7 @@ function normalizeModalities(value) {
50303
50490
  };
50304
50491
  }
50305
50492
  function readRuntimeModelCapabilities(runtimeModel) {
50306
- return isRecord2(runtimeModel?.capabilities) ? runtimeModel.capabilities : undefined;
50493
+ return isRecord4(runtimeModel?.capabilities) ? runtimeModel.capabilities : undefined;
50307
50494
  }
50308
50495
  function readRuntimeModelBoolean(runtimeModel, keys) {
50309
50496
  const runtimeCapabilities = readRuntimeModelCapabilities(runtimeModel);
@@ -50320,7 +50507,7 @@ function readRuntimeModelBoolean(runtimeModel, keys) {
50320
50507
  return;
50321
50508
  }
50322
50509
  function readRuntimeModel(runtimeModel) {
50323
- return isRecord2(runtimeModel) ? runtimeModel : undefined;
50510
+ return isRecord4(runtimeModel) ? runtimeModel : undefined;
50324
50511
  }
50325
50512
  function readRuntimeModelVariants(runtimeModel) {
50326
50513
  const rootVariants = normalizeVariantKeys(runtimeModel?.variants);
@@ -50368,8 +50555,8 @@ function readRuntimeModelToolCallSupport(runtimeModel) {
50368
50555
  return readRuntimeModelBoolean(runtimeModel, ["toolCall", "tool_call", "toolcall"]);
50369
50556
  }
50370
50557
  function readRuntimeModelLimitOutput(runtimeModel) {
50371
- const limit = isRecord2(runtimeModel?.limit) ? runtimeModel.limit : readRuntimeModelCapabilities(runtimeModel)?.limit;
50372
- if (!isRecord2(limit)) {
50558
+ const limit = isRecord4(runtimeModel?.limit) ? runtimeModel.limit : readRuntimeModelCapabilities(runtimeModel)?.limit;
50559
+ if (!isRecord4(limit)) {
50373
50560
  return;
50374
50561
  }
50375
50562
  return readNumber(limit.output);
@@ -50459,7 +50646,7 @@ var init_model_capabilities = __esm(() => {
50459
50646
  });
50460
50647
 
50461
50648
  // src/shared/model-capabilities-cache.ts
50462
- function isRecord3(value) {
50649
+ function isRecord5(value) {
50463
50650
  return typeof value === "object" && value !== null && !Array.isArray(value);
50464
50651
  }
50465
50652
  function readBoolean(value) {
@@ -50479,7 +50666,7 @@ function readStringArray2(value) {
50479
50666
  return result.length > 0 ? result : undefined;
50480
50667
  }
50481
50668
  function normalizeSnapshotEntry(rawModelID, rawModel) {
50482
- if (!isRecord3(rawModel)) {
50669
+ if (!isRecord5(rawModel)) {
50483
50670
  return;
50484
50671
  }
50485
50672
  const id = readString(rawModel.id) ?? rawModelID;
@@ -50487,14 +50674,14 @@ function normalizeSnapshotEntry(rawModelID, rawModel) {
50487
50674
  const reasoning = readBoolean(rawModel.reasoning);
50488
50675
  const temperature = readBoolean(rawModel.temperature);
50489
50676
  const toolCall = readBoolean(rawModel.tool_call);
50490
- const rawModalities = isRecord3(rawModel.modalities) ? rawModel.modalities : undefined;
50677
+ const rawModalities = isRecord5(rawModel.modalities) ? rawModel.modalities : undefined;
50491
50678
  const modalitiesInput = readStringArray2(rawModalities?.input);
50492
50679
  const modalitiesOutput = readStringArray2(rawModalities?.output);
50493
50680
  const modalities = modalitiesInput || modalitiesOutput ? {
50494
50681
  ...modalitiesInput ? { input: modalitiesInput } : {},
50495
50682
  ...modalitiesOutput ? { output: modalitiesOutput } : {}
50496
50683
  } : undefined;
50497
- const rawLimit = isRecord3(rawModel.limit) ? rawModel.limit : undefined;
50684
+ const rawLimit = isRecord5(rawModel.limit) ? rawModel.limit : undefined;
50498
50685
  const limitContext = readNumber2(rawLimit?.context);
50499
50686
  const limitInput = readNumber2(rawLimit?.input);
50500
50687
  const limitOutput = readNumber2(rawLimit?.output);
@@ -50534,13 +50721,13 @@ function mergeSnapshotEntries(existing, incoming) {
50534
50721
  }
50535
50722
  function buildModelCapabilitiesSnapshotFromModelsDev(raw) {
50536
50723
  const models = {};
50537
- const providers = isRecord3(raw) ? raw : {};
50724
+ const providers = isRecord5(raw) ? raw : {};
50538
50725
  for (const providerValue of Object.values(providers)) {
50539
- if (!isRecord3(providerValue)) {
50726
+ if (!isRecord5(providerValue)) {
50540
50727
  continue;
50541
50728
  }
50542
50729
  const providerModels = providerValue.models;
50543
- if (!isRecord3(providerModels)) {
50730
+ if (!isRecord5(providerModels)) {
50544
50731
  continue;
50545
50732
  }
50546
50733
  for (const [rawModelID, rawModel] of Object.entries(providerModels)) {
@@ -50636,19 +50823,19 @@ var init_constants = __esm(() => {
50636
50823
  });
50637
50824
 
50638
50825
  // src/shared/opencode-storage-paths.ts
50639
- import { join as join10 } from "path";
50826
+ import { join as join11 } from "path";
50640
50827
  var OPENCODE_STORAGE, MESSAGE_STORAGE, PART_STORAGE, SESSION_STORAGE;
50641
50828
  var init_opencode_storage_paths = __esm(() => {
50642
50829
  init_data_path();
50643
50830
  OPENCODE_STORAGE = getOpenCodeStorageDir();
50644
- MESSAGE_STORAGE = join10(OPENCODE_STORAGE, "message");
50645
- PART_STORAGE = join10(OPENCODE_STORAGE, "part");
50646
- SESSION_STORAGE = join10(OPENCODE_STORAGE, "session");
50831
+ MESSAGE_STORAGE = join11(OPENCODE_STORAGE, "message");
50832
+ PART_STORAGE = join11(OPENCODE_STORAGE, "part");
50833
+ SESSION_STORAGE = join11(OPENCODE_STORAGE, "session");
50647
50834
  });
50648
50835
 
50649
50836
  // src/shared/compaction-marker.ts
50650
- import { existsSync as existsSync9, readdirSync, readFileSync as readFileSync6 } from "fs";
50651
- import { join as join11 } from "path";
50837
+ import { existsSync as existsSync10, readdirSync, readFileSync as readFileSync7 } from "fs";
50838
+ import { join as join12 } from "path";
50652
50839
  function isCompactionPart(part) {
50653
50840
  return typeof part === "object" && part !== null && part.type === "compaction";
50654
50841
  }
@@ -50662,20 +50849,20 @@ function isCompactionMessage(message) {
50662
50849
  return isCompactionAgent(message.info?.agent ?? message.agent) || hasCompactionPart(message.parts);
50663
50850
  }
50664
50851
  function getCompactionPartStorageDir(messageID) {
50665
- return join11(PART_STORAGE, messageID);
50852
+ return join12(PART_STORAGE, messageID);
50666
50853
  }
50667
50854
  function hasCompactionPartInStorage(messageID) {
50668
50855
  if (!messageID) {
50669
50856
  return false;
50670
50857
  }
50671
50858
  const partDir = getCompactionPartStorageDir(messageID);
50672
- if (!existsSync9(partDir)) {
50859
+ if (!existsSync10(partDir)) {
50673
50860
  return false;
50674
50861
  }
50675
50862
  try {
50676
50863
  return readdirSync(partDir).filter((fileName) => fileName.endsWith(".json")).some((fileName) => {
50677
50864
  try {
50678
- const content = readFileSync6(join11(partDir, fileName), "utf-8");
50865
+ const content = readFileSync7(join12(partDir, fileName), "utf-8");
50679
50866
  return isCompactionPart(JSON.parse(content));
50680
50867
  } catch {
50681
50868
  return false;
@@ -50708,23 +50895,23 @@ var init_hook_message_injector = __esm(() => {
50708
50895
  });
50709
50896
 
50710
50897
  // src/shared/opencode-message-dir.ts
50711
- import { existsSync as existsSync10, readdirSync as readdirSync2 } from "fs";
50712
- import { join as join12 } from "path";
50898
+ import { existsSync as existsSync11, readdirSync as readdirSync2 } from "fs";
50899
+ import { join as join13 } from "path";
50713
50900
  function getMessageDir(sessionID) {
50714
50901
  if (!sessionID.startsWith("ses_"))
50715
50902
  return null;
50716
50903
  if (/[/\\]|\.\./.test(sessionID))
50717
50904
  return null;
50718
- if (!existsSync10(MESSAGE_STORAGE))
50905
+ if (!existsSync11(MESSAGE_STORAGE))
50719
50906
  return null;
50720
- const directPath = join12(MESSAGE_STORAGE, sessionID);
50721
- if (existsSync10(directPath)) {
50907
+ const directPath = join13(MESSAGE_STORAGE, sessionID);
50908
+ if (existsSync11(directPath)) {
50722
50909
  return directPath;
50723
50910
  }
50724
50911
  try {
50725
50912
  for (const dir of readdirSync2(MESSAGE_STORAGE)) {
50726
- const sessionPath = join12(MESSAGE_STORAGE, dir, sessionID);
50727
- if (existsSync10(sessionPath)) {
50913
+ const sessionPath = join13(MESSAGE_STORAGE, dir, sessionID);
50914
+ if (existsSync11(sessionPath)) {
50728
50915
  return sessionPath;
50729
50916
  }
50730
50917
  }
@@ -50747,13 +50934,15 @@ var init_session_utils = __esm(() => {
50747
50934
  init_logger();
50748
50935
  init_agent_display_names();
50749
50936
  });
50937
+
50938
+ // src/shared/event-session-id.ts
50939
+ var init_event_session_id = () => {};
50750
50940
  // src/shared/tmux/constants.ts
50751
50941
  var SESSION_TIMEOUT_MS, SESSION_MISSING_GRACE_MS;
50752
50942
  var init_constants2 = __esm(() => {
50753
50943
  SESSION_TIMEOUT_MS = 60 * 60 * 1000;
50754
50944
  SESSION_MISSING_GRACE_MS = 30 * 1000;
50755
50945
  });
50756
-
50757
50946
  // src/shared/tmux/runner.ts
50758
50947
  var init_runner = __esm(() => {
50759
50948
  init_bun_spawn_shim();
@@ -50836,7 +51025,7 @@ function getServerBasicAuthHeader() {
50836
51025
  const token = Buffer.from(`${username}:${password}`, "utf8").toString("base64");
50837
51026
  return `Basic ${token}`;
50838
51027
  }
50839
- function isRecord4(value) {
51028
+ function isRecord6(value) {
50840
51029
  return typeof value === "object" && value !== null;
50841
51030
  }
50842
51031
  function isRequestFetch(value) {
@@ -50850,11 +51039,11 @@ function wrapRequestFetch(baseFetch, auth) {
50850
51039
  };
50851
51040
  }
50852
51041
  function getInternalClient(client) {
50853
- if (!isRecord4(client)) {
51042
+ if (!isRecord6(client)) {
50854
51043
  return null;
50855
51044
  }
50856
51045
  const internal = client["_client"];
50857
- return isRecord4(internal) ? internal : null;
51046
+ return isRecord6(internal) ? internal : null;
50858
51047
  }
50859
51048
  function tryInjectViaSetConfigHeaders(internal, auth) {
50860
51049
  const setConfig = internal["setConfig"];
@@ -50870,11 +51059,11 @@ function tryInjectViaSetConfigHeaders(internal, auth) {
50870
51059
  }
50871
51060
  function tryInjectViaInterceptors(internal, auth) {
50872
51061
  const interceptors = internal["interceptors"];
50873
- if (!isRecord4(interceptors)) {
51062
+ if (!isRecord6(interceptors)) {
50874
51063
  return false;
50875
51064
  }
50876
51065
  const requestInterceptors = interceptors["request"];
50877
- if (!isRecord4(requestInterceptors)) {
51066
+ if (!isRecord6(requestInterceptors)) {
50878
51067
  return false;
50879
51068
  }
50880
51069
  const use = requestInterceptors["use"];
@@ -50896,7 +51085,7 @@ function tryInjectViaFetchWrapper(internal, auth) {
50896
51085
  return false;
50897
51086
  }
50898
51087
  const config = getConfig();
50899
- if (!isRecord4(config)) {
51088
+ if (!isRecord6(config)) {
50900
51089
  return false;
50901
51090
  }
50902
51091
  const fetchValue = config["fetch"];
@@ -50910,7 +51099,7 @@ function tryInjectViaFetchWrapper(internal, auth) {
50910
51099
  }
50911
51100
  function tryInjectViaMutableInternalConfig(internal, auth) {
50912
51101
  const configValue = internal["_config"];
50913
- if (!isRecord4(configValue)) {
51102
+ if (!isRecord6(configValue)) {
50914
51103
  return false;
50915
51104
  }
50916
51105
  const fetchValue = configValue["fetch"];
@@ -50921,7 +51110,7 @@ function tryInjectViaMutableInternalConfig(internal, auth) {
50921
51110
  return true;
50922
51111
  }
50923
51112
  function tryInjectViaTopLevelFetch(client, auth) {
50924
- if (!isRecord4(client)) {
51113
+ if (!isRecord6(client)) {
50925
51114
  return false;
50926
51115
  }
50927
51116
  const fetchValue = client["fetch"];
@@ -50969,6 +51158,7 @@ var init_opencode_provider_auth = __esm(() => {
50969
51158
  init_data_path();
50970
51159
  init_logger();
50971
51160
  });
51161
+
50972
51162
  // src/shared/opencode-http-api.ts
50973
51163
  var init_opencode_http_api = __esm(() => {
50974
51164
  init_opencode_server_auth();
@@ -50976,18 +51166,46 @@ var init_opencode_http_api = __esm(() => {
50976
51166
  });
50977
51167
 
50978
51168
  // src/shared/port-utils.ts
51169
+ import { createServer } from "net";
50979
51170
  async function isPortAvailable(port, hostname = "127.0.0.1") {
50980
- try {
50981
- const server = Bun.serve({
50982
- port,
50983
- hostname,
50984
- fetch: () => new Response
51171
+ return new Promise((resolve4) => {
51172
+ const server = createServer();
51173
+ let timeoutId;
51174
+ let resolved = false;
51175
+ const finish = (isAvailable) => {
51176
+ if (resolved) {
51177
+ return;
51178
+ }
51179
+ resolved = true;
51180
+ if (timeoutId) {
51181
+ clearTimeout(timeoutId);
51182
+ }
51183
+ server.removeAllListeners("error");
51184
+ server.removeAllListeners("listening");
51185
+ resolve4(isAvailable);
51186
+ };
51187
+ const closeThenFinish = (isAvailable) => {
51188
+ try {
51189
+ server.close(() => finish(isAvailable));
51190
+ } catch {
51191
+ finish(isAvailable);
51192
+ }
51193
+ };
51194
+ timeoutId = setTimeout(() => {
51195
+ closeThenFinish(false);
51196
+ }, PORT_CHECK_TIMEOUT_MS);
51197
+ server.once("error", () => {
51198
+ finish(false);
50985
51199
  });
50986
- server.stop(true);
50987
- return true;
50988
- } catch {
50989
- return false;
50990
- }
51200
+ server.once("listening", () => {
51201
+ closeThenFinish(true);
51202
+ });
51203
+ try {
51204
+ server.listen(port, hostname);
51205
+ } catch {
51206
+ finish(false);
51207
+ }
51208
+ });
50991
51209
  }
50992
51210
  async function findAvailablePort(startPort = DEFAULT_SERVER_PORT, hostname = "127.0.0.1") {
50993
51211
  for (let attempt = 0;attempt < MAX_PORT_ATTEMPTS; attempt++) {
@@ -51005,7 +51223,7 @@ async function getAvailableServerPort(preferredPort = DEFAULT_SERVER_PORT, hostn
51005
51223
  const port = await findAvailablePort(preferredPort + 1, hostname);
51006
51224
  return { port, wasAutoSelected: true };
51007
51225
  }
51008
- var DEFAULT_SERVER_PORT = 4096, MAX_PORT_ATTEMPTS = 20;
51226
+ var DEFAULT_SERVER_PORT = 4096, MAX_PORT_ATTEMPTS = 20, PORT_CHECK_TIMEOUT_MS = 2000;
51009
51227
  var init_port_utils = () => {};
51010
51228
  // src/shared/git-worktree/parse-status-porcelain.ts
51011
51229
  var init_parse_status_porcelain = () => {};
@@ -51029,15 +51247,15 @@ var init_opencode_command_dirs = __esm(() => {
51029
51247
  });
51030
51248
 
51031
51249
  // src/shared/project-discovery-dirs.ts
51032
- import { existsSync as existsSync11, realpathSync as realpathSync4 } from "fs";
51033
- import { dirname as dirname3, join as join13, resolve as resolve4 } from "path";
51034
- function normalizePath(path5) {
51035
- const resolvedPath = resolve4(path5);
51036
- if (!existsSync11(resolvedPath)) {
51250
+ import { existsSync as existsSync12, realpathSync as realpathSync5 } from "fs";
51251
+ import { dirname as dirname4, join as join14, resolve as resolve4 } from "path";
51252
+ function normalizePath(path6) {
51253
+ const resolvedPath = resolve4(path6);
51254
+ if (!existsSync12(resolvedPath)) {
51037
51255
  return resolvedPath;
51038
51256
  }
51039
51257
  try {
51040
- return realpathSync4(resolvedPath);
51258
+ return realpathSync5(resolvedPath);
51041
51259
  } catch {
51042
51260
  return resolvedPath;
51043
51261
  }
@@ -51048,8 +51266,8 @@ function findProjectOpencodePluginConfigFiles(startDirectory, stopDirectory) {
51048
51266
  let currentDirectory = normalizePath(startDirectory);
51049
51267
  const resolvedStopDirectory = stopDirectory ? normalizePath(stopDirectory) : undefined;
51050
51268
  while (true) {
51051
- const opencodeDirectory = join13(currentDirectory, ".opencode");
51052
- if (existsSync11(opencodeDirectory)) {
51269
+ const opencodeDirectory = join14(currentDirectory, ".opencode");
51270
+ if (existsSync12(opencodeDirectory)) {
51053
51271
  const detected = detectPluginConfigFile(opencodeDirectory);
51054
51272
  if (detected.format !== "none" && !seen.has(detected.path)) {
51055
51273
  seen.add(detected.path);
@@ -51059,7 +51277,7 @@ function findProjectOpencodePluginConfigFiles(startDirectory, stopDirectory) {
51059
51277
  if (resolvedStopDirectory === currentDirectory) {
51060
51278
  return paths;
51061
51279
  }
51062
- const parentDirectory = dirname3(currentDirectory);
51280
+ const parentDirectory = dirname4(currentDirectory);
51063
51281
  if (parentDirectory === currentDirectory) {
51064
51282
  return paths;
51065
51283
  }
@@ -51075,6 +51293,11 @@ var init_project_discovery_dirs = __esm(() => {
51075
51293
  // src/shared/session-directory-resolver.ts
51076
51294
  var init_session_directory_resolver = () => {};
51077
51295
 
51296
+ // src/shared/session-route.ts
51297
+ var init_session_route = __esm(() => {
51298
+ init_model_suggestion_retry();
51299
+ });
51300
+
51078
51301
  // src/shared/session-tools-store.ts
51079
51302
  var store;
51080
51303
  var init_session_tools_store = __esm(() => {
@@ -51161,6 +51384,7 @@ var init_mcp_server_loader = __esm(() => {
51161
51384
  init_scope_filter2();
51162
51385
  init_transformer();
51163
51386
  init_logger();
51387
+ init_bun_file_shim();
51164
51388
  });
51165
51389
 
51166
51390
  // src/features/claude-code-plugin-loader/hook-loader.ts
@@ -51322,6 +51546,7 @@ var init_shared = __esm(() => {
51322
51546
  init_connected_providers_cache();
51323
51547
  init_context_limit_resolver();
51324
51548
  init_session_utils();
51549
+ init_event_session_id();
51325
51550
  init_tmux();
51326
51551
  init_model_suggestion_retry();
51327
51552
  init_opencode_server_auth();
@@ -51335,6 +51560,7 @@ var init_shared = __esm(() => {
51335
51560
  init_opencode_command_dirs();
51336
51561
  init_project_discovery_dirs();
51337
51562
  init_session_directory_resolver();
51563
+ init_session_route();
51338
51564
  init_prompt_tools();
51339
51565
  init_compaction_marker();
51340
51566
  init_internal_initiator_marker();
@@ -51420,17 +51646,17 @@ var init_plugin_name_with_version = __esm(() => {
51420
51646
  });
51421
51647
 
51422
51648
  // src/cli/config-manager/backup-config.ts
51423
- import { copyFileSync as copyFileSync2, existsSync as existsSync12, mkdirSync as mkdirSync5 } from "fs";
51424
- import { dirname as dirname4 } from "path";
51649
+ import { copyFileSync as copyFileSync2, existsSync as existsSync13, mkdirSync as mkdirSync5 } from "fs";
51650
+ import { dirname as dirname5 } from "path";
51425
51651
  function backupConfigFile(configPath) {
51426
- if (!existsSync12(configPath)) {
51652
+ if (!existsSync13(configPath)) {
51427
51653
  return { success: true };
51428
51654
  }
51429
51655
  const timestamp2 = new Date().toISOString().replace(/[:.]/g, "-");
51430
51656
  const backupPath = `${configPath}.backup-${timestamp2}`;
51431
51657
  try {
51432
- const dir = dirname4(backupPath);
51433
- if (!existsSync12(dir)) {
51658
+ const dir = dirname5(backupPath);
51659
+ if (!existsSync13(dir)) {
51434
51660
  mkdirSync5(dir, { recursive: true });
51435
51661
  }
51436
51662
  copyFileSync2(configPath, backupPath);
@@ -51445,10 +51671,10 @@ function backupConfigFile(configPath) {
51445
51671
  var init_backup_config = () => {};
51446
51672
 
51447
51673
  // src/cli/config-manager/ensure-config-directory-exists.ts
51448
- import { existsSync as existsSync13, mkdirSync as mkdirSync6 } from "fs";
51674
+ import { existsSync as existsSync14, mkdirSync as mkdirSync6 } from "fs";
51449
51675
  function ensureConfigDirectoryExists() {
51450
51676
  const configDir = getConfigDir();
51451
- if (!existsSync13(configDir)) {
51677
+ if (!existsSync14(configDir)) {
51452
51678
  mkdirSync6(configDir, { recursive: true });
51453
51679
  }
51454
51680
  }
@@ -51486,14 +51712,14 @@ function formatErrorWithSuggestion(err, context) {
51486
51712
  }
51487
51713
 
51488
51714
  // src/cli/config-manager/opencode-config-format.ts
51489
- import { existsSync as existsSync14 } from "fs";
51715
+ import { existsSync as existsSync15 } from "fs";
51490
51716
  function detectConfigFormat() {
51491
51717
  const configJsonc = getConfigJsonc();
51492
51718
  const configJson = getConfigJson();
51493
- if (existsSync14(configJsonc)) {
51719
+ if (existsSync15(configJsonc)) {
51494
51720
  return { format: "jsonc", path: configJsonc };
51495
51721
  }
51496
- if (existsSync14(configJson)) {
51722
+ if (existsSync15(configJson)) {
51497
51723
  return { format: "json", path: configJson };
51498
51724
  }
51499
51725
  return { format: "none", path: configJson };
@@ -51503,33 +51729,33 @@ var init_opencode_config_format = __esm(() => {
51503
51729
  });
51504
51730
 
51505
51731
  // src/cli/config-manager/parse-opencode-config-file.ts
51506
- import { readFileSync as readFileSync7, statSync } from "fs";
51732
+ import { readFileSync as readFileSync8, statSync } from "fs";
51507
51733
  function isEmptyOrWhitespace(content) {
51508
51734
  return content.trim().length === 0;
51509
51735
  }
51510
- function parseOpenCodeConfigFileWithError(path5) {
51736
+ function parseOpenCodeConfigFileWithError(path6) {
51511
51737
  try {
51512
- const stat = statSync(path5);
51738
+ const stat = statSync(path6);
51513
51739
  if (stat.size === 0) {
51514
- return { config: null, error: `Config file is empty: ${path5}. Delete it or add valid JSON content.` };
51740
+ return { config: null, error: `Config file is empty: ${path6}. Delete it or add valid JSON content.` };
51515
51741
  }
51516
- const content = readFileSync7(path5, "utf-8");
51742
+ const content = readFileSync8(path6, "utf-8");
51517
51743
  if (isEmptyOrWhitespace(content)) {
51518
- return { config: null, error: `Config file contains only whitespace: ${path5}. Delete it or add valid JSON content.` };
51744
+ return { config: null, error: `Config file contains only whitespace: ${path6}. Delete it or add valid JSON content.` };
51519
51745
  }
51520
51746
  const config = parseJsonc(content);
51521
51747
  if (config == null) {
51522
- return { config: null, error: `Config file parsed to null/undefined: ${path5}. Ensure it contains valid JSON.` };
51748
+ return { config: null, error: `Config file parsed to null/undefined: ${path6}. Ensure it contains valid JSON.` };
51523
51749
  }
51524
51750
  if (typeof config !== "object" || Array.isArray(config)) {
51525
51751
  return {
51526
51752
  config: null,
51527
- error: `Config file must contain a JSON object, not ${Array.isArray(config) ? "an array" : typeof config}: ${path5}`
51753
+ error: `Config file must contain a JSON object, not ${Array.isArray(config) ? "an array" : typeof config}: ${path6}`
51528
51754
  };
51529
51755
  }
51530
51756
  return { config };
51531
51757
  } catch (err) {
51532
- return { config: null, error: formatErrorWithSuggestion(err, `parse config file ${path5}`) };
51758
+ return { config: null, error: formatErrorWithSuggestion(err, `parse config file ${path6}`) };
51533
51759
  }
51534
51760
  }
51535
51761
  var init_parse_opencode_config_file = __esm(() => {
@@ -51619,7 +51845,7 @@ function extractVersionFromPluginEntry(entry) {
51619
51845
  }
51620
51846
 
51621
51847
  // src/cli/config-manager/add-plugin-to-opencode-config.ts
51622
- import { readFileSync as readFileSync8, writeFileSync as writeFileSync3 } from "fs";
51848
+ import { readFileSync as readFileSync9, writeFileSync as writeFileSync3 } from "fs";
51623
51849
  async function addPluginToOpenCodeConfig(currentVersion) {
51624
51850
  try {
51625
51851
  ensureConfigDirectoryExists();
@@ -51630,20 +51856,20 @@ async function addPluginToOpenCodeConfig(currentVersion) {
51630
51856
  error: formatErrorWithSuggestion(err, "create config directory")
51631
51857
  };
51632
51858
  }
51633
- const { format: format2, path: path5 } = detectConfigFormat();
51859
+ const { format: format2, path: path6 } = detectConfigFormat();
51634
51860
  const pluginEntry = await getPluginNameWithVersion(currentVersion, PLUGIN_NAME);
51635
51861
  try {
51636
51862
  if (format2 === "none") {
51637
51863
  const config2 = { plugin: [pluginEntry] };
51638
- writeFileSync3(path5, JSON.stringify(config2, null, 2) + `
51864
+ writeFileSync3(path6, JSON.stringify(config2, null, 2) + `
51639
51865
  `);
51640
- return { success: true, configPath: path5 };
51866
+ return { success: true, configPath: path6 };
51641
51867
  }
51642
- const parseResult = parseOpenCodeConfigFileWithError(path5);
51868
+ const parseResult = parseOpenCodeConfigFileWithError(path6);
51643
51869
  if (!parseResult.config) {
51644
51870
  return {
51645
51871
  success: false,
51646
- configPath: path5,
51872
+ configPath: path6,
51647
51873
  error: parseResult.error ?? "Failed to parse config file"
51648
51874
  };
51649
51875
  }
@@ -51659,15 +51885,15 @@ async function addPluginToOpenCodeConfig(currentVersion) {
51659
51885
  if (!compatibility.canUpgrade) {
51660
51886
  return {
51661
51887
  success: false,
51662
- configPath: path5,
51888
+ configPath: path6,
51663
51889
  error: compatibility.reason ?? "Version compatibility check failed"
51664
51890
  };
51665
51891
  }
51666
- const backupResult = backupConfigFile(path5);
51892
+ const backupResult = backupConfigFile(path6);
51667
51893
  if (!backupResult.success) {
51668
51894
  return {
51669
51895
  success: false,
51670
- configPath: path5,
51896
+ configPath: path6,
51671
51897
  error: `Failed to create backup: ${backupResult.error}`
51672
51898
  };
51673
51899
  }
@@ -51676,7 +51902,7 @@ async function addPluginToOpenCodeConfig(currentVersion) {
51676
51902
  normalizedPlugins.push(pluginEntry);
51677
51903
  config.plugin = normalizedPlugins;
51678
51904
  if (format2 === "jsonc") {
51679
- const content = readFileSync8(path5, "utf-8");
51905
+ const content = readFileSync9(path6, "utf-8");
51680
51906
  const pluginArrayRegex = /((?:"plugin"|plugin)\s*:\s*)\[([\s\S]*?)\]/;
51681
51907
  const match = content.match(pluginArrayRegex);
51682
51908
  if (match) {
@@ -51685,21 +51911,21 @@ async function addPluginToOpenCodeConfig(currentVersion) {
51685
51911
  const newContent = content.replace(pluginArrayRegex, `$1[
51686
51912
  ${formattedPlugins}
51687
51913
  ]`);
51688
- writeFileSync3(path5, newContent);
51914
+ writeFileSync3(path6, newContent);
51689
51915
  } else {
51690
51916
  const newContent = content.replace(/(\{)/, `$1
51691
51917
  "plugin": ["${pluginEntry}"],`);
51692
- writeFileSync3(path5, newContent);
51918
+ writeFileSync3(path6, newContent);
51693
51919
  }
51694
51920
  } else {
51695
- writeFileSync3(path5, JSON.stringify(config, null, 2) + `
51921
+ writeFileSync3(path6, JSON.stringify(config, null, 2) + `
51696
51922
  `);
51697
51923
  }
51698
- return { success: true, configPath: path5 };
51924
+ return { success: true, configPath: path6 };
51699
51925
  } catch (err) {
51700
51926
  return {
51701
51927
  success: false,
51702
- configPath: path5,
51928
+ configPath: path6,
51703
51929
  error: formatErrorWithSuggestion(err, "update opencode config")
51704
51930
  };
51705
51931
  }
@@ -52036,12 +52262,12 @@ var init_generate_omo_config = __esm(() => {
52036
52262
  });
52037
52263
 
52038
52264
  // src/shared/migrate-legacy-config-file.ts
52039
- import { existsSync as existsSync15, readFileSync as readFileSync9, renameSync as renameSync2, rmSync } from "fs";
52040
- import { join as join14, dirname as dirname5, basename as basename2 } from "path";
52265
+ import { existsSync as existsSync16, readFileSync as readFileSync10, renameSync as renameSync2, rmSync } from "fs";
52266
+ import { join as join15, dirname as dirname6, basename as basename2 } from "path";
52041
52267
  function buildCanonicalPath(legacyPath) {
52042
- const dir = dirname5(legacyPath);
52268
+ const dir = dirname6(legacyPath);
52043
52269
  const ext = basename2(legacyPath).includes(".jsonc") ? ".jsonc" : ".json";
52044
- return join14(dir, `${CONFIG_BASENAME}${ext}`);
52270
+ return join15(dir, `${CONFIG_BASENAME}${ext}`);
52045
52271
  }
52046
52272
  function archiveLegacyConfigFile(legacyPath) {
52047
52273
  const backupPath = `${legacyPath}.bak`;
@@ -52074,13 +52300,13 @@ function archiveLegacyConfigFile(legacyPath) {
52074
52300
  }
52075
52301
  function migrateLegacySidecarFile(legacyPath, canonicalPath) {
52076
52302
  const legacySidecarPath = getSidecarPath(legacyPath);
52077
- if (!existsSync15(legacySidecarPath))
52303
+ if (!existsSync16(legacySidecarPath))
52078
52304
  return true;
52079
52305
  const canonicalSidecarPath = getSidecarPath(canonicalPath);
52080
- if (existsSync15(canonicalSidecarPath))
52306
+ if (existsSync16(canonicalSidecarPath))
52081
52307
  return true;
52082
52308
  try {
52083
- const content = readFileSync9(legacySidecarPath, "utf-8");
52309
+ const content = readFileSync10(legacySidecarPath, "utf-8");
52084
52310
  writeFileAtomically(canonicalSidecarPath, content);
52085
52311
  log("[migrateLegacyConfigFile] Migrated legacy migration sidecar to canonical path", {
52086
52312
  from: legacySidecarPath,
@@ -52097,15 +52323,15 @@ function migrateLegacySidecarFile(legacyPath, canonicalPath) {
52097
52323
  }
52098
52324
  }
52099
52325
  function migrateLegacyConfigFile(legacyPath) {
52100
- if (!existsSync15(legacyPath))
52326
+ if (!existsSync16(legacyPath))
52101
52327
  return false;
52102
52328
  if (!basename2(legacyPath).startsWith(LEGACY_CONFIG_BASENAME))
52103
52329
  return false;
52104
52330
  const canonicalPath = buildCanonicalPath(legacyPath);
52105
- if (existsSync15(canonicalPath))
52331
+ if (existsSync16(canonicalPath))
52106
52332
  return false;
52107
52333
  try {
52108
- const content = readFileSync9(legacyPath, "utf-8");
52334
+ const content = readFileSync10(legacyPath, "utf-8");
52109
52335
  writeFileAtomically(canonicalPath, content);
52110
52336
  const migratedSidecar = migrateLegacySidecarFile(legacyPath, canonicalPath);
52111
52337
  const archivedLegacyConfig = archiveLegacyConfigFile(legacyPath);
@@ -52146,8 +52372,8 @@ function deepMergeRecord(target, source) {
52146
52372
  }
52147
52373
 
52148
52374
  // src/cli/config-manager/write-omo-config.ts
52149
- import { existsSync as existsSync16, readFileSync as readFileSync10, statSync as statSync2, writeFileSync as writeFileSync4 } from "fs";
52150
- import { basename as basename3, dirname as dirname6, extname, join as join15 } from "path";
52375
+ import { existsSync as existsSync17, readFileSync as readFileSync11, statSync as statSync2, writeFileSync as writeFileSync4 } from "fs";
52376
+ import { basename as basename3, dirname as dirname7, extname, join as join16 } from "path";
52151
52377
  function isEmptyOrWhitespace2(content) {
52152
52378
  return content.trim().length === 0;
52153
52379
  }
@@ -52162,12 +52388,12 @@ function writeOmoConfig(installConfig) {
52162
52388
  };
52163
52389
  }
52164
52390
  const detectedConfigPath = getOmoConfigPath();
52165
- const canonicalConfigPath = join15(dirname6(detectedConfigPath), `${CONFIG_BASENAME}${extname(detectedConfigPath) || ".json"}`);
52391
+ const canonicalConfigPath = join16(dirname7(detectedConfigPath), `${CONFIG_BASENAME}${extname(detectedConfigPath) || ".json"}`);
52166
52392
  const shouldMigrateLegacyPath = basename3(detectedConfigPath).startsWith(LEGACY_CONFIG_BASENAME);
52167
- const omoConfigPath = shouldMigrateLegacyPath ? migrateLegacyConfigFile(detectedConfigPath) || existsSync16(canonicalConfigPath) ? canonicalConfigPath : detectedConfigPath : detectedConfigPath;
52393
+ const omoConfigPath = shouldMigrateLegacyPath ? migrateLegacyConfigFile(detectedConfigPath) || existsSync17(canonicalConfigPath) ? canonicalConfigPath : detectedConfigPath : detectedConfigPath;
52168
52394
  try {
52169
52395
  const newConfig = generateOmoConfig(installConfig);
52170
- if (existsSync16(omoConfigPath)) {
52396
+ if (existsSync17(omoConfigPath)) {
52171
52397
  const backupResult = backupConfigFile(omoConfigPath);
52172
52398
  if (!backupResult.success) {
52173
52399
  return {
@@ -52178,7 +52404,7 @@ function writeOmoConfig(installConfig) {
52178
52404
  }
52179
52405
  try {
52180
52406
  const stat = statSync2(omoConfigPath);
52181
- const content = readFileSync10(omoConfigPath, "utf-8");
52407
+ const content = readFileSync11(omoConfigPath, "utf-8");
52182
52408
  if (stat.size === 0 || isEmptyOrWhitespace2(content)) {
52183
52409
  writeFileSync4(omoConfigPath, JSON.stringify(newConfig, null, 2) + `
52184
52410
  `);
@@ -52224,6 +52450,16 @@ var init_write_omo_config = __esm(() => {
52224
52450
  init_generate_omo_config();
52225
52451
  });
52226
52452
 
52453
+ // src/shared/extract-semver.ts
52454
+ function extractSemverFromOutput(output) {
52455
+ const trimmed = output.trim();
52456
+ if (!trimmed)
52457
+ return null;
52458
+ const semverPattern = /(?<![\d:])v?(\d+\.\d+\.\d+(?:[-+][\w.]+)*)/;
52459
+ const match = trimmed.match(semverPattern);
52460
+ return match?.[1] ?? null;
52461
+ }
52462
+
52227
52463
  // src/shared/spawn-with-windows-hide.ts
52228
52464
  import { spawn as nodeSpawn2 } from "child_process";
52229
52465
  import { Readable as Readable2 } from "stream";
@@ -52293,10 +52529,52 @@ async function findOpenCodeBinaryWithVersion() {
52293
52529
  stdout: "pipe",
52294
52530
  stderr: "pipe"
52295
52531
  });
52296
- const output = await new Response(proc.stdout).text();
52297
- await proc.exited;
52298
- if (proc.exitCode === 0) {
52299
- const version = output.trim();
52532
+ const outputPromise = new Response(proc.stdout).text();
52533
+ let killTimer = null;
52534
+ let killGraceTimer = null;
52535
+ const timedExitResult = await Promise.race([
52536
+ proc.exited.then((exitCode) => ({ type: "exit", exitCode })),
52537
+ new Promise((resolve5) => {
52538
+ killTimer = setTimeout(() => {
52539
+ proc.kill("SIGTERM");
52540
+ killGraceTimer = setTimeout(() => {
52541
+ proc.kill("SIGKILL");
52542
+ }, OPENCODE_VERSION_KILL_GRACE_MS);
52543
+ resolve5({ type: "timeout" });
52544
+ }, OPENCODE_VERSION_CHECK_TIMEOUT_MS);
52545
+ })
52546
+ ]);
52547
+ if (killTimer) {
52548
+ clearTimeout(killTimer);
52549
+ }
52550
+ if (timedExitResult.type === "timeout") {
52551
+ outputPromise.catch(() => {});
52552
+ continue;
52553
+ }
52554
+ if (killGraceTimer) {
52555
+ clearTimeout(killGraceTimer);
52556
+ }
52557
+ let outputTimer = null;
52558
+ const outputResult = await Promise.race([
52559
+ outputPromise.then((output) => ({ type: "output", output })),
52560
+ new Promise((resolve5) => {
52561
+ outputTimer = setTimeout(() => {
52562
+ resolve5({ type: "timeout" });
52563
+ }, OPENCODE_OUTPUT_WAIT_TIMEOUT_MS);
52564
+ })
52565
+ ]).catch(() => ({ type: "timeout" }));
52566
+ if (outputTimer) {
52567
+ clearTimeout(outputTimer);
52568
+ }
52569
+ if (outputResult.type !== "output") {
52570
+ continue;
52571
+ }
52572
+ if (timedExitResult.exitCode === 0 && proc.exitCode === 0) {
52573
+ const output = outputResult.output;
52574
+ const version = extractSemverFromOutput(output) ?? output.trim();
52575
+ if (version.length === 0) {
52576
+ continue;
52577
+ }
52300
52578
  initConfigContext(binary2, version);
52301
52579
  return { binary: binary2, version };
52302
52580
  }
@@ -52314,7 +52592,7 @@ async function getOpenCodeVersion2() {
52314
52592
  const result = await findOpenCodeBinaryWithVersion();
52315
52593
  return result?.version ?? null;
52316
52594
  }
52317
- var OPENCODE_BINARIES;
52595
+ var OPENCODE_BINARIES, OPENCODE_VERSION_CHECK_TIMEOUT_MS = 1500, OPENCODE_VERSION_KILL_GRACE_MS = 200, OPENCODE_OUTPUT_WAIT_TIMEOUT_MS = 200;
52318
52596
  var init_opencode_binary = __esm(() => {
52319
52597
  init_spawn_with_windows_hide();
52320
52598
  init_config_context();
@@ -52322,10 +52600,10 @@ var init_opencode_binary = __esm(() => {
52322
52600
  });
52323
52601
 
52324
52602
  // src/cli/config-manager/detect-current-config.ts
52325
- import { existsSync as existsSync17, readFileSync as readFileSync11 } from "fs";
52603
+ import { existsSync as existsSync18, readFileSync as readFileSync12 } from "fs";
52326
52604
  function detectProvidersFromOmoConfig() {
52327
52605
  const omoConfigPath = getOmoConfigPath();
52328
- if (!existsSync17(omoConfigPath)) {
52606
+ if (!existsSync18(omoConfigPath)) {
52329
52607
  return {
52330
52608
  hasOpenAI: true,
52331
52609
  hasOpencodeZen: true,
@@ -52336,7 +52614,7 @@ function detectProvidersFromOmoConfig() {
52336
52614
  };
52337
52615
  }
52338
52616
  try {
52339
- const content = readFileSync11(omoConfigPath, "utf-8");
52617
+ const content = readFileSync12(omoConfigPath, "utf-8");
52340
52618
  const omoConfig = parseJsonc(content);
52341
52619
  if (!omoConfig || typeof omoConfig !== "object") {
52342
52620
  return {
@@ -52388,11 +52666,11 @@ function detectCurrentConfig() {
52388
52666
  hasOpencodeGo: false,
52389
52667
  hasVercelAiGateway: false
52390
52668
  };
52391
- const { format: format2, path: path5 } = detectConfigFormat();
52669
+ const { format: format2, path: path6 } = detectConfigFormat();
52392
52670
  if (format2 === "none") {
52393
52671
  return result;
52394
52672
  }
52395
- const parseResult = parseOpenCodeConfigFileWithError(path5);
52673
+ const parseResult = parseOpenCodeConfigFileWithError(path6);
52396
52674
  if (!parseResult.config) {
52397
52675
  return result;
52398
52676
  }
@@ -52425,16 +52703,16 @@ var init_detect_current_config = __esm(() => {
52425
52703
  });
52426
52704
 
52427
52705
  // src/cli/config-manager/bun-install.ts
52428
- import { existsSync as existsSync18 } from "fs";
52429
- import { join as join16 } from "path";
52706
+ import { existsSync as existsSync19 } from "fs";
52707
+ import { join as join17 } from "path";
52430
52708
  function getDefaultWorkspaceDir() {
52431
- return join16(getOpenCodeCacheDir(), "packages");
52709
+ return join17(getOpenCodeCacheDir(), "packages");
52432
52710
  }
52433
52711
  function readProcessOutput(stream) {
52434
52712
  if (!stream) {
52435
52713
  return Promise.resolve("");
52436
52714
  }
52437
- return Bun.readableStreamToText(stream);
52715
+ return new Response(stream).text();
52438
52716
  }
52439
52717
  function logCapturedOutputOnFailure(outputMode, output) {
52440
52718
  if (outputMode !== "pipe") {
@@ -52454,7 +52732,7 @@ async function runBunInstallWithDetails(options) {
52454
52732
  const outputMode = options?.outputMode ?? "pipe";
52455
52733
  const cacheDir = options?.workspaceDir ?? getDefaultWorkspaceDir();
52456
52734
  const packageJsonPath = `${cacheDir}/package.json`;
52457
- if (!existsSync18(packageJsonPath)) {
52735
+ if (!existsSync19(packageJsonPath)) {
52458
52736
  return {
52459
52737
  success: false,
52460
52738
  error: `Workspace not initialized: ${packageJsonPath} not found. OpenCode should create this on first run.`
@@ -52597,7 +52875,7 @@ var require_windows = __commonJS((exports, module) => {
52597
52875
  module.exports = isexe;
52598
52876
  isexe.sync = sync;
52599
52877
  var fs5 = __require("fs");
52600
- function checkPathExt(path6, options) {
52878
+ function checkPathExt(path7, options) {
52601
52879
  var pathext = options.pathExt !== undefined ? options.pathExt : process.env.PATHEXT;
52602
52880
  if (!pathext) {
52603
52881
  return true;
@@ -52608,25 +52886,25 @@ var require_windows = __commonJS((exports, module) => {
52608
52886
  }
52609
52887
  for (var i2 = 0;i2 < pathext.length; i2++) {
52610
52888
  var p2 = pathext[i2].toLowerCase();
52611
- if (p2 && path6.substr(-p2.length).toLowerCase() === p2) {
52889
+ if (p2 && path7.substr(-p2.length).toLowerCase() === p2) {
52612
52890
  return true;
52613
52891
  }
52614
52892
  }
52615
52893
  return false;
52616
52894
  }
52617
- function checkStat(stat, path6, options) {
52895
+ function checkStat(stat, path7, options) {
52618
52896
  if (!stat.isSymbolicLink() && !stat.isFile()) {
52619
52897
  return false;
52620
52898
  }
52621
- return checkPathExt(path6, options);
52899
+ return checkPathExt(path7, options);
52622
52900
  }
52623
- function isexe(path6, options, cb) {
52624
- fs5.stat(path6, function(er, stat) {
52625
- cb(er, er ? false : checkStat(stat, path6, options));
52901
+ function isexe(path7, options, cb) {
52902
+ fs5.stat(path7, function(er, stat) {
52903
+ cb(er, er ? false : checkStat(stat, path7, options));
52626
52904
  });
52627
52905
  }
52628
- function sync(path6, options) {
52629
- return checkStat(fs5.statSync(path6), path6, options);
52906
+ function sync(path7, options) {
52907
+ return checkStat(fs5.statSync(path7), path7, options);
52630
52908
  }
52631
52909
  });
52632
52910
 
@@ -52635,13 +52913,13 @@ var require_mode = __commonJS((exports, module) => {
52635
52913
  module.exports = isexe;
52636
52914
  isexe.sync = sync;
52637
52915
  var fs5 = __require("fs");
52638
- function isexe(path6, options, cb) {
52639
- fs5.stat(path6, function(er, stat) {
52916
+ function isexe(path7, options, cb) {
52917
+ fs5.stat(path7, function(er, stat) {
52640
52918
  cb(er, er ? false : checkStat(stat, options));
52641
52919
  });
52642
52920
  }
52643
- function sync(path6, options) {
52644
- return checkStat(fs5.statSync(path6), options);
52921
+ function sync(path7, options) {
52922
+ return checkStat(fs5.statSync(path7), options);
52645
52923
  }
52646
52924
  function checkStat(stat, options) {
52647
52925
  return stat.isFile() && checkMode(stat, options);
@@ -52672,7 +52950,7 @@ var require_isexe = __commonJS((exports, module) => {
52672
52950
  }
52673
52951
  module.exports = isexe;
52674
52952
  isexe.sync = sync;
52675
- function isexe(path6, options, cb) {
52953
+ function isexe(path7, options, cb) {
52676
52954
  if (typeof options === "function") {
52677
52955
  cb = options;
52678
52956
  options = {};
@@ -52682,7 +52960,7 @@ var require_isexe = __commonJS((exports, module) => {
52682
52960
  throw new TypeError("callback not provided");
52683
52961
  }
52684
52962
  return new Promise(function(resolve5, reject) {
52685
- isexe(path6, options || {}, function(er, is) {
52963
+ isexe(path7, options || {}, function(er, is) {
52686
52964
  if (er) {
52687
52965
  reject(er);
52688
52966
  } else {
@@ -52691,7 +52969,7 @@ var require_isexe = __commonJS((exports, module) => {
52691
52969
  });
52692
52970
  });
52693
52971
  }
52694
- core3(path6, options || {}, function(er, is) {
52972
+ core3(path7, options || {}, function(er, is) {
52695
52973
  if (er) {
52696
52974
  if (er.code === "EACCES" || options && options.ignoreErrors) {
52697
52975
  er = null;
@@ -52701,9 +52979,9 @@ var require_isexe = __commonJS((exports, module) => {
52701
52979
  cb(er, is);
52702
52980
  });
52703
52981
  }
52704
- function sync(path6, options) {
52982
+ function sync(path7, options) {
52705
52983
  try {
52706
- return core3.sync(path6, options || {});
52984
+ return core3.sync(path7, options || {});
52707
52985
  } catch (er) {
52708
52986
  if (options && options.ignoreErrors || er.code === "EACCES") {
52709
52987
  return false;
@@ -52717,7 +52995,7 @@ var require_isexe = __commonJS((exports, module) => {
52717
52995
  // node_modules/which/which.js
52718
52996
  var require_which = __commonJS((exports, module) => {
52719
52997
  var isWindows = process.platform === "win32" || process.env.OSTYPE === "cygwin" || process.env.OSTYPE === "msys";
52720
- var path6 = __require("path");
52998
+ var path7 = __require("path");
52721
52999
  var COLON = isWindows ? ";" : ":";
52722
53000
  var isexe = require_isexe();
52723
53001
  var getNotFoundError = (cmd) => Object.assign(new Error(`not found: ${cmd}`), { code: "ENOENT" });
@@ -52753,7 +53031,7 @@ var require_which = __commonJS((exports, module) => {
52753
53031
  return opt.all && found.length ? resolve5(found) : reject(getNotFoundError(cmd));
52754
53032
  const ppRaw = pathEnv[i2];
52755
53033
  const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
52756
- const pCmd = path6.join(pathPart, cmd);
53034
+ const pCmd = path7.join(pathPart, cmd);
52757
53035
  const p2 = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
52758
53036
  resolve5(subStep(p2, i2, 0));
52759
53037
  });
@@ -52780,7 +53058,7 @@ var require_which = __commonJS((exports, module) => {
52780
53058
  for (let i2 = 0;i2 < pathEnv.length; i2++) {
52781
53059
  const ppRaw = pathEnv[i2];
52782
53060
  const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
52783
- const pCmd = path6.join(pathPart, cmd);
53061
+ const pCmd = path7.join(pathPart, cmd);
52784
53062
  const p2 = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
52785
53063
  for (let j2 = 0;j2 < pathExt.length; j2++) {
52786
53064
  const cur = p2 + pathExt[j2];
@@ -52821,7 +53099,7 @@ var require_path_key = __commonJS((exports, module) => {
52821
53099
 
52822
53100
  // node_modules/cross-spawn/lib/util/resolveCommand.js
52823
53101
  var require_resolveCommand = __commonJS((exports, module) => {
52824
- var path6 = __require("path");
53102
+ var path7 = __require("path");
52825
53103
  var which = require_which();
52826
53104
  var getPathKey = require_path_key();
52827
53105
  function resolveCommandAttempt(parsed, withoutPathExt) {
@@ -52838,7 +53116,7 @@ var require_resolveCommand = __commonJS((exports, module) => {
52838
53116
  try {
52839
53117
  resolved = which.sync(parsed.command, {
52840
53118
  path: env[getPathKey({ env })],
52841
- pathExt: withoutPathExt ? path6.delimiter : undefined
53119
+ pathExt: withoutPathExt ? path7.delimiter : undefined
52842
53120
  });
52843
53121
  } catch (e2) {} finally {
52844
53122
  if (shouldSwitchCwd) {
@@ -52846,7 +53124,7 @@ var require_resolveCommand = __commonJS((exports, module) => {
52846
53124
  }
52847
53125
  }
52848
53126
  if (resolved) {
52849
- resolved = path6.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
53127
+ resolved = path7.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
52850
53128
  }
52851
53129
  return resolved;
52852
53130
  }
@@ -52891,8 +53169,8 @@ var require_shebang_command = __commonJS((exports, module) => {
52891
53169
  if (!match) {
52892
53170
  return null;
52893
53171
  }
52894
- const [path6, argument] = match[0].replace(/#! ?/, "").split(" ");
52895
- const binary2 = path6.split("/").pop();
53172
+ const [path7, argument] = match[0].replace(/#! ?/, "").split(" ");
53173
+ const binary2 = path7.split("/").pop();
52896
53174
  if (binary2 === "env") {
52897
53175
  return argument;
52898
53176
  }
@@ -52920,7 +53198,7 @@ var require_readShebang = __commonJS((exports, module) => {
52920
53198
 
52921
53199
  // node_modules/cross-spawn/lib/parse.js
52922
53200
  var require_parse = __commonJS((exports, module) => {
52923
- var path6 = __require("path");
53201
+ var path7 = __require("path");
52924
53202
  var resolveCommand2 = require_resolveCommand();
52925
53203
  var escape = require_escape();
52926
53204
  var readShebang = require_readShebang();
@@ -52945,7 +53223,7 @@ var require_parse = __commonJS((exports, module) => {
52945
53223
  const needsShell = !isExecutableRegExp.test(commandFile);
52946
53224
  if (parsed.options.forceShell || needsShell) {
52947
53225
  const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile);
52948
- parsed.command = path6.normalize(parsed.command);
53226
+ parsed.command = path7.normalize(parsed.command);
52949
53227
  parsed.command = escape.command(parsed.command);
52950
53228
  parsed.args = parsed.args.map((arg) => escape.argument(arg, needsDoubleEscapeMetaChars));
52951
53229
  const shellCommand = [parsed.command].concat(parsed.args).join(" ");
@@ -53049,21 +53327,21 @@ var require_cross_spawn = __commonJS((exports, module) => {
53049
53327
  });
53050
53328
 
53051
53329
  // src/hooks/auto-update-checker/constants.ts
53052
- import * as path6 from "path";
53330
+ import * as path7 from "path";
53053
53331
  import * as os4 from "os";
53054
53332
  function getWindowsAppdataDir() {
53055
53333
  if (process.platform !== "win32")
53056
53334
  return null;
53057
- return process.env.APPDATA ?? path6.join(os4.homedir(), "AppData", "Roaming");
53335
+ return process.env.APPDATA ?? path7.join(os4.homedir(), "AppData", "Roaming");
53058
53336
  }
53059
53337
  function getUserConfigDir() {
53060
53338
  return getOpenCodeConfigDir({ binary: "opencode" });
53061
53339
  }
53062
53340
  function getUserOpencodeConfig() {
53063
- return path6.join(getUserConfigDir(), "opencode.json");
53341
+ return path7.join(getUserConfigDir(), "opencode.json");
53064
53342
  }
53065
53343
  function getUserOpencodeConfigJsonc() {
53066
- return path6.join(getUserConfigDir(), "opencode.jsonc");
53344
+ return path7.join(getUserConfigDir(), "opencode.jsonc");
53067
53345
  }
53068
53346
  var PACKAGE_NAME2, ACCEPTED_PACKAGE_NAMES2, NPM_REGISTRY_URL, NPM_FETCH_TIMEOUT = 5000, CACHE_ROOT_DIR, CACHE_DIR, VERSION_FILE, INSTALLED_PACKAGE_JSON, INSTALLED_PACKAGE_JSON_CANDIDATES;
53069
53347
  var init_constants3 = __esm(() => {
@@ -53074,30 +53352,30 @@ var init_constants3 = __esm(() => {
53074
53352
  ACCEPTED_PACKAGE_NAMES2 = ACCEPTED_PACKAGE_NAMES;
53075
53353
  NPM_REGISTRY_URL = `https://registry.npmjs.org/-/package/${PACKAGE_NAME2}/dist-tags`;
53076
53354
  CACHE_ROOT_DIR = getOpenCodeCacheDir();
53077
- CACHE_DIR = path6.join(CACHE_ROOT_DIR, "packages");
53078
- VERSION_FILE = path6.join(CACHE_ROOT_DIR, "version");
53079
- INSTALLED_PACKAGE_JSON = path6.join(CACHE_DIR, "node_modules", PACKAGE_NAME2, "package.json");
53080
- INSTALLED_PACKAGE_JSON_CANDIDATES = ACCEPTED_PACKAGE_NAMES2.map((name) => path6.join(CACHE_DIR, "node_modules", name, "package.json"));
53355
+ CACHE_DIR = path7.join(CACHE_ROOT_DIR, "packages");
53356
+ VERSION_FILE = path7.join(CACHE_ROOT_DIR, "version");
53357
+ INSTALLED_PACKAGE_JSON = path7.join(CACHE_DIR, "node_modules", PACKAGE_NAME2, "package.json");
53358
+ INSTALLED_PACKAGE_JSON_CANDIDATES = ACCEPTED_PACKAGE_NAMES2.map((name) => path7.join(CACHE_DIR, "node_modules", name, "package.json"));
53081
53359
  });
53082
53360
 
53083
53361
  // src/hooks/auto-update-checker/checker/config-paths.ts
53084
53362
  import * as os5 from "os";
53085
- import * as path7 from "path";
53363
+ import * as path8 from "path";
53086
53364
  function getConfigPaths(directory) {
53087
53365
  const userConfigDir = getUserConfigDir();
53088
53366
  const paths = [
53089
- path7.join(directory, ".opencode", "opencode.json"),
53090
- path7.join(directory, ".opencode", "opencode.jsonc"),
53367
+ path8.join(directory, ".opencode", "opencode.json"),
53368
+ path8.join(directory, ".opencode", "opencode.jsonc"),
53091
53369
  getUserOpencodeConfig(),
53092
53370
  getUserOpencodeConfigJsonc()
53093
53371
  ];
53094
53372
  if (process.platform === "win32") {
53095
- const crossPlatformDir = path7.join(os5.homedir(), ".config");
53373
+ const crossPlatformDir = path8.join(os5.homedir(), ".config");
53096
53374
  const appdataDir = getWindowsAppdataDir();
53097
53375
  if (appdataDir) {
53098
53376
  const alternateDir = userConfigDir === crossPlatformDir ? appdataDir : crossPlatformDir;
53099
- const alternateConfig = path7.join(alternateDir, "opencode", "opencode.json");
53100
- const alternateConfigJsonc = path7.join(alternateDir, "opencode", "opencode.jsonc");
53377
+ const alternateConfig = path8.join(alternateDir, "opencode", "opencode.json");
53378
+ const alternateConfigJsonc = path8.join(alternateDir, "opencode", "opencode.jsonc");
53101
53379
  if (!paths.includes(alternateConfig)) {
53102
53380
  paths.push(alternateConfig);
53103
53381
  }
@@ -53155,13 +53433,13 @@ var init_local_dev_path = __esm(() => {
53155
53433
 
53156
53434
  // src/hooks/auto-update-checker/checker/package-json-locator.ts
53157
53435
  import * as fs6 from "fs";
53158
- import * as path8 from "path";
53436
+ import * as path9 from "path";
53159
53437
  function findPackageJsonUp(startPath) {
53160
53438
  try {
53161
53439
  const stat = fs6.statSync(startPath);
53162
- let dir = stat.isDirectory() ? startPath : path8.dirname(startPath);
53440
+ let dir = stat.isDirectory() ? startPath : path9.dirname(startPath);
53163
53441
  for (let i2 = 0;i2 < 10; i2++) {
53164
- const pkgPath = path8.join(dir, "package.json");
53442
+ const pkgPath = path9.join(dir, "package.json");
53165
53443
  if (fs6.existsSync(pkgPath)) {
53166
53444
  try {
53167
53445
  const content = fs6.readFileSync(pkgPath, "utf-8");
@@ -53170,7 +53448,7 @@ function findPackageJsonUp(startPath) {
53170
53448
  return pkgPath;
53171
53449
  } catch {}
53172
53450
  }
53173
- const parent = path8.dirname(dir);
53451
+ const parent = path9.dirname(dir);
53174
53452
  if (parent === dir)
53175
53453
  break;
53176
53454
  dir = parent;
@@ -53245,7 +53523,7 @@ var init_plugin_entry = __esm(() => {
53245
53523
 
53246
53524
  // src/hooks/auto-update-checker/checker/cached-version.ts
53247
53525
  import * as fs9 from "fs";
53248
- import * as path9 from "path";
53526
+ import * as path10 from "path";
53249
53527
  import { fileURLToPath as fileURLToPath2 } from "url";
53250
53528
  function readPackageVersion(packageJsonPath) {
53251
53529
  const content = fs9.readFileSync(packageJsonPath, "utf-8");
@@ -53254,7 +53532,7 @@ function readPackageVersion(packageJsonPath) {
53254
53532
  }
53255
53533
  function getCachedVersion() {
53256
53534
  try {
53257
- const currentDir = path9.dirname(fileURLToPath2(import.meta.url));
53535
+ const currentDir = path10.dirname(fileURLToPath2(import.meta.url));
53258
53536
  const pkgPath = findPackageJsonUp(currentDir);
53259
53537
  if (pkgPath) {
53260
53538
  return readPackageVersion(pkgPath);
@@ -53270,7 +53548,7 @@ function getCachedVersion() {
53270
53548
  } catch {}
53271
53549
  }
53272
53550
  try {
53273
- const execDir = path9.dirname(fs9.realpathSync(process.execPath));
53551
+ const execDir = path10.dirname(fs9.realpathSync(process.execPath));
53274
53552
  const pkgPath = findPackageJsonUp(execDir);
53275
53553
  if (pkgPath) {
53276
53554
  return readPackageVersion(pkgPath);
@@ -53414,7 +53692,7 @@ var init_check_for_update = __esm(() => {
53414
53692
  // src/hooks/auto-update-checker/checker/sync-package-json.ts
53415
53693
  import * as crypto from "crypto";
53416
53694
  import * as fs10 from "fs";
53417
- import * as path10 from "path";
53695
+ import * as path11 from "path";
53418
53696
  function safeUnlink(filePath) {
53419
53697
  try {
53420
53698
  fs10.unlinkSync(filePath);
@@ -53431,7 +53709,7 @@ function getIntentVersion(pluginInfo) {
53431
53709
  function writeCachePackageJson(cachePackageJsonPath, pkgJson) {
53432
53710
  const tmpPath = `${cachePackageJsonPath}.${crypto.randomUUID()}`;
53433
53711
  try {
53434
- fs10.mkdirSync(path10.dirname(cachePackageJsonPath), { recursive: true });
53712
+ fs10.mkdirSync(path11.dirname(cachePackageJsonPath), { recursive: true });
53435
53713
  fs10.writeFileSync(tmpPath, JSON.stringify(pkgJson, null, 2));
53436
53714
  fs10.renameSync(tmpPath, cachePackageJsonPath);
53437
53715
  return { synced: true, error: null };
@@ -53442,7 +53720,7 @@ function writeCachePackageJson(cachePackageJsonPath, pkgJson) {
53442
53720
  }
53443
53721
  }
53444
53722
  function syncCachePackageJsonToIntent(pluginInfo) {
53445
- const cachePackageJsonPath = path10.join(CACHE_DIR, "package.json");
53723
+ const cachePackageJsonPath = path11.join(CACHE_DIR, "package.json");
53446
53724
  const intentVersion = getIntentVersion(pluginInfo);
53447
53725
  if (!fs10.existsSync(cachePackageJsonPath)) {
53448
53726
  log("[auto-update-checker] Cache package.json missing, creating workspace package.json", { intentVersion });
@@ -53518,7 +53796,7 @@ var init_checker = __esm(() => {
53518
53796
 
53519
53797
  // src/hooks/auto-update-checker/cache.ts
53520
53798
  import * as fs11 from "fs";
53521
- import * as path11 from "path";
53799
+ import * as path12 from "path";
53522
53800
  function stripTrailingCommas(json3) {
53523
53801
  return json3.replace(/,(\s*[}\]])/g, "$1");
53524
53802
  }
@@ -53547,8 +53825,8 @@ function deleteBinaryBunLock(lockPath) {
53547
53825
  }
53548
53826
  }
53549
53827
  function removeFromBunLock(packageName) {
53550
- const textLockPath = path11.join(CACHE_DIR, "bun.lock");
53551
- const binaryLockPath = path11.join(CACHE_DIR, "bun.lockb");
53828
+ const textLockPath = path12.join(CACHE_DIR, "bun.lock");
53829
+ const binaryLockPath = path12.join(CACHE_DIR, "bun.lockb");
53552
53830
  if (fs11.existsSync(textLockPath)) {
53553
53831
  return removeFromTextBunLock(textLockPath, packageName);
53554
53832
  }
@@ -53561,8 +53839,8 @@ function invalidatePackage(packageName = PACKAGE_NAME2) {
53561
53839
  try {
53562
53840
  const userConfigDir = getUserConfigDir();
53563
53841
  const pkgDirs = [
53564
- path11.join(userConfigDir, "node_modules", packageName),
53565
- path11.join(CACHE_DIR, "node_modules", packageName)
53842
+ path12.join(userConfigDir, "node_modules", packageName),
53843
+ path12.join(CACHE_DIR, "node_modules", packageName)
53566
53844
  ];
53567
53845
  let packageRemoved = false;
53568
53846
  let lockRemoved = false;
@@ -53622,8 +53900,8 @@ var init_update_toasts = __esm(() => {
53622
53900
  });
53623
53901
 
53624
53902
  // src/hooks/auto-update-checker/hook/background-update-check.ts
53625
- import { existsSync as existsSync30 } from "fs";
53626
- import { join as join29 } from "path";
53903
+ import { existsSync as existsSync32 } from "fs";
53904
+ import { join as join30 } from "path";
53627
53905
  function getCacheWorkspaceDir(deps) {
53628
53906
  return deps.join(deps.getOpenCodeCacheDir(), "packages");
53629
53907
  }
@@ -53673,7 +53951,7 @@ async function primeCacheWorkspace(activeWorkspace, deps) {
53673
53951
  return runBunInstallSafe(cacheWorkspace, deps);
53674
53952
  }
53675
53953
  function createBackgroundUpdateCheckRunner(overrides = {}) {
53676
- const deps = { ...defaultDeps, ...overrides };
53954
+ const deps = { ...defaultDeps2, ...overrides };
53677
53955
  return async function runBackgroundUpdateCheck(ctx, autoUpdate, getToastMessage) {
53678
53956
  const pluginInfo = deps.findPluginEntry(ctx.directory);
53679
53957
  if (!pluginInfo) {
@@ -53731,7 +54009,7 @@ function createBackgroundUpdateCheckRunner(overrides = {}) {
53731
54009
  deps.log("[auto-update-checker] bun install failed; update not installed (falling back to notification-only)");
53732
54010
  };
53733
54011
  }
53734
- var defaultDeps, runBackgroundUpdateCheck;
54012
+ var defaultDeps2, runBackgroundUpdateCheck;
53735
54013
  var init_background_update_check = __esm(() => {
53736
54014
  init_config_manager();
53737
54015
  init_logger();
@@ -53740,9 +54018,9 @@ var init_background_update_check = __esm(() => {
53740
54018
  init_constants3();
53741
54019
  init_checker();
53742
54020
  init_update_toasts();
53743
- defaultDeps = {
53744
- existsSync: existsSync30,
53745
- join: join29,
54021
+ defaultDeps2 = {
54022
+ existsSync: existsSync32,
54023
+ join: join30,
53746
54024
  runBunInstallWithDetails,
53747
54025
  log,
53748
54026
  getOpenCodeCacheDir,
@@ -53927,7 +54205,7 @@ var init_startup_toasts = __esm(() => {
53927
54205
  });
53928
54206
 
53929
54207
  // src/hooks/auto-update-checker/hook.ts
53930
- function createAutoUpdateCheckerHook(ctx, options = {}, deps = defaultDeps2) {
54208
+ function createAutoUpdateCheckerHook(ctx, options = {}, deps = defaultDeps3) {
53931
54209
  const {
53932
54210
  showStartupToast = true,
53933
54211
  isSisyphusEnabled = false,
@@ -53984,13 +54262,13 @@ v${latestVersion} available. Restart OpenCode to apply.` : "OpenCode is now on S
53984
54262
  }
53985
54263
  };
53986
54264
  }
53987
- var defaultDeps2, isRecord6 = (value) => {
54265
+ var defaultDeps3, isRecord7 = (value) => {
53988
54266
  return typeof value === "object" && value !== null;
53989
54267
  }, getParentID = (properties) => {
53990
- if (!isRecord6(properties))
54268
+ if (!isRecord7(properties))
53991
54269
  return;
53992
54270
  const { info } = properties;
53993
- if (!isRecord6(info))
54271
+ if (!isRecord7(info))
53994
54272
  return;
53995
54273
  const { parentID } = info;
53996
54274
  return typeof parentID === "string" && parentID.length > 0 ? parentID : undefined;
@@ -54004,7 +54282,7 @@ var init_hook = __esm(() => {
54004
54282
  init_model_capabilities_status();
54005
54283
  init_model_cache_warning();
54006
54284
  init_startup_toasts();
54007
- defaultDeps2 = {
54285
+ defaultDeps3 = {
54008
54286
  getCachedVersion,
54009
54287
  getLocalDevVersion,
54010
54288
  showConfigErrorsIfAny,
@@ -54054,7 +54332,7 @@ var {
54054
54332
  // package.json
54055
54333
  var package_default = {
54056
54334
  name: "oh-my-opencode",
54057
- version: "4.0.0",
54335
+ version: "4.1.0",
54058
54336
  description: "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
54059
54337
  main: "./dist/index.js",
54060
54338
  types: "dist/index.d.ts",
@@ -54088,7 +54366,7 @@ var package_default = {
54088
54366
  prepublishOnly: "bun run clean && bun run build",
54089
54367
  "test:model-capabilities": "bun test src/shared/model-capability-aliases.test.ts src/shared/model-capability-guardrails.test.ts src/shared/model-capabilities.test.ts src/cli/doctor/checks/model-resolution.test.ts --bail",
54090
54368
  typecheck: "tsc --noEmit",
54091
- test: "bun test"
54369
+ test: "bun run script/run-ci-tests.ts"
54092
54370
  },
54093
54371
  keywords: [
54094
54372
  "opencode",
@@ -54114,7 +54392,7 @@ var package_default = {
54114
54392
  "@ast-grep/napi": "^0.41.1",
54115
54393
  "@clack/prompts": "^0.11.0",
54116
54394
  "@code-yeongyu/comment-checker": "^0.7.0",
54117
- "@modelcontextprotocol/sdk": "^1.25.2",
54395
+ "@modelcontextprotocol/sdk": "^1.29.0",
54118
54396
  "@opencode-ai/plugin": "^1.4.0",
54119
54397
  "@opencode-ai/sdk": "^1.4.0",
54120
54398
  commander: "^14.0.2",
@@ -54135,19 +54413,25 @@ var package_default = {
54135
54413
  zod: "^4.3.0"
54136
54414
  },
54137
54415
  optionalDependencies: {
54138
- "oh-my-opencode-darwin-arm64": "4.0.0",
54139
- "oh-my-opencode-darwin-x64": "4.0.0",
54140
- "oh-my-opencode-darwin-x64-baseline": "4.0.0",
54141
- "oh-my-opencode-linux-arm64": "4.0.0",
54142
- "oh-my-opencode-linux-arm64-musl": "4.0.0",
54143
- "oh-my-opencode-linux-x64": "4.0.0",
54144
- "oh-my-opencode-linux-x64-baseline": "4.0.0",
54145
- "oh-my-opencode-linux-x64-musl": "4.0.0",
54146
- "oh-my-opencode-linux-x64-musl-baseline": "4.0.0",
54147
- "oh-my-opencode-windows-x64": "4.0.0",
54148
- "oh-my-opencode-windows-x64-baseline": "4.0.0"
54416
+ "oh-my-opencode-darwin-arm64": "4.1.0",
54417
+ "oh-my-opencode-darwin-x64": "4.1.0",
54418
+ "oh-my-opencode-darwin-x64-baseline": "4.1.0",
54419
+ "oh-my-opencode-linux-arm64": "4.1.0",
54420
+ "oh-my-opencode-linux-arm64-musl": "4.1.0",
54421
+ "oh-my-opencode-linux-x64": "4.1.0",
54422
+ "oh-my-opencode-linux-x64-baseline": "4.1.0",
54423
+ "oh-my-opencode-linux-x64-musl": "4.1.0",
54424
+ "oh-my-opencode-linux-x64-musl-baseline": "4.1.0",
54425
+ "oh-my-opencode-windows-x64": "4.1.0",
54426
+ "oh-my-opencode-windows-x64-baseline": "4.1.0"
54427
+ },
54428
+ overrides: {
54429
+ hono: "^4.12.18",
54430
+ "@hono/node-server": "^1.19.13",
54431
+ "express-rate-limit": "^8.5.1",
54432
+ "fast-uri": "^3.1.2",
54433
+ "path-to-regexp": "^8.4.2"
54149
54434
  },
54150
- overrides: {},
54151
54435
  trustedDependencies: [
54152
54436
  "@ast-grep/cli",
54153
54437
  "@ast-grep/napi",
@@ -55434,10 +55718,10 @@ function formatToolHeader(toolName, input) {
55434
55718
  };
55435
55719
  }
55436
55720
  if (toolName === "list") {
55437
- const path5 = str2(input.path);
55721
+ const path6 = str2(input.path);
55438
55722
  return {
55439
55723
  icon: "\u2192",
55440
- title: path5 ? `List ${path5}` : "List"
55724
+ title: path6 ? `List ${path6}` : "List"
55441
55725
  };
55442
55726
  }
55443
55727
  if (toolName === "read") {
@@ -55946,8 +56230,8 @@ async function processEvents(ctx, stream, state) {
55946
56230
  }
55947
56231
  // src/plugin-config.ts
55948
56232
  import * as fs4 from "fs";
55949
- import { homedir as homedir4 } from "os";
55950
- import * as path5 from "path";
56233
+ import { homedir as homedir5 } from "os";
56234
+ import * as path6 from "path";
55951
56235
 
55952
56236
  // node_modules/zod/v4/classic/external.js
55953
56237
  var exports_external = {};
@@ -56714,10 +56998,10 @@ function mergeDefs(...defs) {
56714
56998
  function cloneDef(schema2) {
56715
56999
  return mergeDefs(schema2._zod.def);
56716
57000
  }
56717
- function getElementAtPath(obj, path5) {
56718
- if (!path5)
57001
+ function getElementAtPath(obj, path6) {
57002
+ if (!path6)
56719
57003
  return obj;
56720
- return path5.reduce((acc, key) => acc?.[key], obj);
57004
+ return path6.reduce((acc, key) => acc?.[key], obj);
56721
57005
  }
56722
57006
  function promiseAllObject(promisesObj) {
56723
57007
  const keys = Object.keys(promisesObj);
@@ -57098,11 +57382,11 @@ function aborted(x2, startIndex = 0) {
57098
57382
  }
57099
57383
  return false;
57100
57384
  }
57101
- function prefixIssues(path5, issues) {
57385
+ function prefixIssues(path6, issues) {
57102
57386
  return issues.map((iss) => {
57103
57387
  var _a;
57104
57388
  (_a = iss).path ?? (_a.path = []);
57105
- iss.path.unshift(path5);
57389
+ iss.path.unshift(path6);
57106
57390
  return iss;
57107
57391
  });
57108
57392
  }
@@ -57285,7 +57569,7 @@ function formatError2(error, mapper = (issue2) => issue2.message) {
57285
57569
  }
57286
57570
  function treeifyError(error, mapper = (issue2) => issue2.message) {
57287
57571
  const result = { errors: [] };
57288
- const processError = (error2, path5 = []) => {
57572
+ const processError = (error2, path6 = []) => {
57289
57573
  var _a, _b;
57290
57574
  for (const issue2 of error2.issues) {
57291
57575
  if (issue2.code === "invalid_union" && issue2.errors.length) {
@@ -57295,7 +57579,7 @@ function treeifyError(error, mapper = (issue2) => issue2.message) {
57295
57579
  } else if (issue2.code === "invalid_element") {
57296
57580
  processError({ issues: issue2.issues }, issue2.path);
57297
57581
  } else {
57298
- const fullpath = [...path5, ...issue2.path];
57582
+ const fullpath = [...path6, ...issue2.path];
57299
57583
  if (fullpath.length === 0) {
57300
57584
  result.errors.push(mapper(issue2));
57301
57585
  continue;
@@ -57327,8 +57611,8 @@ function treeifyError(error, mapper = (issue2) => issue2.message) {
57327
57611
  }
57328
57612
  function toDotPath(_path) {
57329
57613
  const segs = [];
57330
- const path5 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
57331
- for (const seg of path5) {
57614
+ const path6 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
57615
+ for (const seg of path6) {
57332
57616
  if (typeof seg === "number")
57333
57617
  segs.push(`[${seg}]`);
57334
57618
  else if (typeof seg === "symbol")
@@ -69075,13 +69359,13 @@ function resolveRef(ref, ctx) {
69075
69359
  if (!ref.startsWith("#")) {
69076
69360
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
69077
69361
  }
69078
- const path5 = ref.slice(1).split("/").filter(Boolean);
69079
- if (path5.length === 0) {
69362
+ const path6 = ref.slice(1).split("/").filter(Boolean);
69363
+ if (path6.length === 0) {
69080
69364
  return ctx.rootSchema;
69081
69365
  }
69082
69366
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
69083
- if (path5[0] === defsKey) {
69084
- const key = path5[1];
69367
+ if (path6[0] === defsKey) {
69368
+ const key = path6[1];
69085
69369
  if (!key || !ctx.defs[key]) {
69086
69370
  throw new Error(`Reference not found: ${ref}`);
69087
69371
  }
@@ -69818,6 +70102,7 @@ var HookNameSchema = exports_external.enum([
69818
70102
  "read-image-resizer",
69819
70103
  "todo-description-override",
69820
70104
  "webfetch-redirect-guard",
70105
+ "fsync-skip-warning",
69821
70106
  "legacy-plugin-toast"
69822
70107
  ]);
69823
70108
  // src/config/schema/keyword-detector.ts
@@ -70000,6 +70285,7 @@ var OhMyOpenCodeConfigSchema = exports_external.object({
70000
70285
  $schema: exports_external.string().optional(),
70001
70286
  new_task_system_enabled: exports_external.boolean().optional(),
70002
70287
  default_run_agent: exports_external.string().optional(),
70288
+ agent_order: exports_external.array(exports_external.string().max(128)).max(64).optional(),
70003
70289
  agent_definitions: AgentDefinitionsConfigSchema,
70004
70290
  disabled_mcps: exports_external.array(AnyMcpNameSchema).optional(),
70005
70291
  disabled_agents: exports_external.array(exports_external.string()).optional(),
@@ -70043,15 +70329,93 @@ var OhMyOpenCodeConfigSchema = exports_external.object({
70043
70329
  init_shared();
70044
70330
  init_migrate_legacy_config_file();
70045
70331
  init_plugin_identity();
70332
+
70333
+ // src/shared/agent-ordering.ts
70334
+ init_agent_display_names();
70335
+ var DEFAULT_AGENT_ORDER = [
70336
+ "sisyphus",
70337
+ "hephaestus",
70338
+ "prometheus",
70339
+ "atlas"
70340
+ ];
70341
+ var KNOWN_AGENT_KEYS = new Set(Object.keys(AGENT_DISPLAY_NAMES));
70342
+ function appendUnique(target, value) {
70343
+ if (!target.includes(value)) {
70344
+ target.push(value);
70345
+ }
70346
+ }
70347
+ function validateAgentOrder(agentOrder) {
70348
+ const order = [];
70349
+ const invalid = [];
70350
+ const duplicates = [];
70351
+ const seen = new Set;
70352
+ for (const rawName of agentOrder ?? []) {
70353
+ const trimmed = rawName.trim();
70354
+ if (trimmed.length === 0) {
70355
+ invalid.push(rawName);
70356
+ continue;
70357
+ }
70358
+ const configKey = getAgentConfigKey(trimmed);
70359
+ if (!KNOWN_AGENT_KEYS.has(configKey)) {
70360
+ invalid.push(rawName);
70361
+ continue;
70362
+ }
70363
+ if (seen.has(configKey)) {
70364
+ duplicates.push(rawName);
70365
+ continue;
70366
+ }
70367
+ seen.add(configKey);
70368
+ order.push(configKey);
70369
+ }
70370
+ for (const configKey of DEFAULT_AGENT_ORDER) {
70371
+ appendUnique(order, configKey);
70372
+ }
70373
+ return { order, invalid, duplicates };
70374
+ }
70375
+
70376
+ // src/plugin-config.ts
70377
+ var CONTROL_CHARACTERS_REGEX = /[\u0000-\u001F\u007F-\u009F\u202A-\u202E\u2066-\u2069]/g;
70378
+ var MAX_AGENT_ORDER_WARNING_VALUES = 10;
70379
+ var MAX_AGENT_ORDER_WARNING_VALUE_LENGTH = 80;
70380
+ function formatAgentOrderWarningValues(values) {
70381
+ const displayedValues = values.slice(0, MAX_AGENT_ORDER_WARNING_VALUES).map((value) => {
70382
+ const sanitized = value.replace(CONTROL_CHARACTERS_REGEX, "");
70383
+ const truncated = sanitized.length > MAX_AGENT_ORDER_WARNING_VALUE_LENGTH ? `${sanitized.slice(0, MAX_AGENT_ORDER_WARNING_VALUE_LENGTH)}...` : sanitized;
70384
+ return JSON.stringify(truncated);
70385
+ });
70386
+ const remaining = values.length - displayedValues.length;
70387
+ if (remaining > 0) {
70388
+ displayedValues.push(`(+${remaining} more)`);
70389
+ }
70390
+ return displayedValues.join(", ");
70391
+ }
70392
+ function addAgentOrderWarnings(configPath, agentOrder) {
70393
+ if (!agentOrder)
70394
+ return;
70395
+ const validation = validateAgentOrder(agentOrder);
70396
+ const messages = [];
70397
+ if (validation.invalid.length > 0) {
70398
+ messages.push(`unknown agent names ignored: ${formatAgentOrderWarningValues(validation.invalid)}`);
70399
+ }
70400
+ if (validation.duplicates.length > 0) {
70401
+ messages.push(`duplicate agent names ignored: ${formatAgentOrderWarningValues(validation.duplicates)}`);
70402
+ }
70403
+ if (messages.length === 0)
70404
+ return;
70405
+ addConfigLoadError({
70406
+ path: configPath,
70407
+ error: `agent_order warning - ${messages.join("; ")}`
70408
+ });
70409
+ }
70046
70410
  function resolveHomeDirectory() {
70047
- return process.env.HOME ?? process.env.USERPROFILE ?? homedir4();
70411
+ return process.env.HOME ?? process.env.USERPROFILE ?? homedir5();
70048
70412
  }
70049
70413
  function resolveConfigPathAfterLegacyMigration(detectedPath) {
70050
- if (!path5.basename(detectedPath).startsWith(LEGACY_CONFIG_BASENAME)) {
70414
+ if (!path6.basename(detectedPath).startsWith(LEGACY_CONFIG_BASENAME)) {
70051
70415
  return detectedPath;
70052
70416
  }
70053
70417
  const migrated = migrateLegacyConfigFile(detectedPath);
70054
- const canonicalPath = path5.join(path5.dirname(detectedPath), `${CONFIG_BASENAME}${path5.extname(detectedPath)}`);
70418
+ const canonicalPath = path6.join(path6.dirname(detectedPath), `${CONFIG_BASENAME}${path6.extname(detectedPath)}`);
70055
70419
  if (migrated || fs4.existsSync(canonicalPath)) {
70056
70420
  return canonicalPath;
70057
70421
  }
@@ -70124,6 +70488,7 @@ function loadConfigFromPath(configPath, _ctx) {
70124
70488
  migrateConfigFile(configPath, rawConfig);
70125
70489
  const result = OhMyOpenCodeConfigSchema.safeParse(rawConfig);
70126
70490
  if (result.success) {
70491
+ addAgentOrderWarnings(configPath, result.data.agent_order);
70127
70492
  log(`Config loaded from ${configPath}`, { agents: result.data.agents });
70128
70493
  return result.data;
70129
70494
  }
@@ -70135,6 +70500,7 @@ function loadConfigFromPath(configPath, _ctx) {
70135
70500
  });
70136
70501
  const partialResult = parseConfigPartially(rawConfig);
70137
70502
  if (partialResult) {
70503
+ addAgentOrderWarnings(configPath, partialResult.agent_order);
70138
70504
  log(`Partial config loaded from ${configPath}`, { agents: partialResult.agents });
70139
70505
  return partialResult;
70140
70506
  }
@@ -70208,7 +70574,7 @@ function mergeConfigs(base, override) {
70208
70574
  function loadPluginConfig(directory, ctx) {
70209
70575
  const configDir = getOpenCodeConfigDir({ binary: "opencode" });
70210
70576
  const userDetected = detectPluginConfigFile(configDir);
70211
- let userConfigPath = userDetected.format !== "none" ? userDetected.path : path5.join(configDir, `${CONFIG_BASENAME}.json`);
70577
+ let userConfigPath = userDetected.format !== "none" ? userDetected.path : path6.join(configDir, `${CONFIG_BASENAME}.json`);
70212
70578
  if (userDetected.legacyPath) {
70213
70579
  log("Canonical plugin config detected alongside legacy config. Remove the legacy file to avoid confusion.", {
70214
70580
  canonicalPath: userDetected.path,
@@ -70227,7 +70593,7 @@ function loadPluginConfig(directory, ctx) {
70227
70593
  stopDirectory
70228
70594
  });
70229
70595
  const canonicalAncestorPathsNearestFirst = ancestorConfigPathsNearestFirst.map((ancestorPath) => {
70230
- const opencodeDir = path5.dirname(ancestorPath);
70596
+ const opencodeDir = path6.dirname(ancestorPath);
70231
70597
  const ancestorDetected = detectPluginConfigFile(opencodeDir);
70232
70598
  if (ancestorDetected.legacyPath) {
70233
70599
  log("Canonical plugin config detected alongside legacy config. Remove the legacy file to avoid confusion.", {
@@ -70250,8 +70616,8 @@ function loadPluginConfig(directory, ctx) {
70250
70616
  const ancestorConfig = loadConfigFromPath(ancestorPath, ctx);
70251
70617
  const ancestorOverrides = loadExplicitGitMasterOverrides(ancestorPath);
70252
70618
  if (ancestorConfig?.agent_definitions) {
70253
- const ancestorBasePath = path5.dirname(ancestorPath);
70254
- const ancestorDir = path5.dirname(ancestorBasePath);
70619
+ const ancestorBasePath = path6.dirname(ancestorPath);
70620
+ const ancestorDir = path6.dirname(ancestorBasePath);
70255
70621
  ancestorConfig.agent_definitions = resolveAgentDefinitionPaths(ancestorConfig.agent_definitions, ancestorBasePath, ancestorDir);
70256
70622
  }
70257
70623
  if (ancestorConfig) {
@@ -70522,7 +70888,7 @@ var serializeObjectParam = ({ allowReserved, explode, name, style, value, valueO
70522
70888
 
70523
70889
  // node_modules/@opencode-ai/sdk/dist/gen/core/utils.gen.js
70524
70890
  var PATH_PARAM_RE = /\{[^{}]+\}/g;
70525
- var defaultPathSerializer = ({ path: path6, url: _url2 }) => {
70891
+ var defaultPathSerializer = ({ path: path7, url: _url2 }) => {
70526
70892
  let url2 = _url2;
70527
70893
  const matches = _url2.match(PATH_PARAM_RE);
70528
70894
  if (matches) {
@@ -70541,7 +70907,7 @@ var defaultPathSerializer = ({ path: path6, url: _url2 }) => {
70541
70907
  name = name.substring(1);
70542
70908
  style = "matrix";
70543
70909
  }
70544
- const value = path6[name];
70910
+ const value = path7[name];
70545
70911
  if (value === undefined || value === null) {
70546
70912
  continue;
70547
70913
  }
@@ -70572,11 +70938,11 @@ var defaultPathSerializer = ({ path: path6, url: _url2 }) => {
70572
70938
  }
70573
70939
  return url2;
70574
70940
  };
70575
- var getUrl = ({ baseUrl, path: path6, query, querySerializer, url: _url2 }) => {
70941
+ var getUrl = ({ baseUrl, path: path7, query, querySerializer, url: _url2 }) => {
70576
70942
  const pathUrl = _url2.startsWith("/") ? _url2 : `/${_url2}`;
70577
70943
  let url2 = (baseUrl ?? "") + pathUrl;
70578
- if (path6) {
70579
- url2 = defaultPathSerializer({ path: path6, url: url2 });
70944
+ if (path7) {
70945
+ url2 = defaultPathSerializer({ path: path7, url: url2 });
70580
70946
  }
70581
70947
  let search = query ? querySerializer(query) : "";
70582
70948
  if (search.startsWith("?")) {
@@ -71807,7 +72173,7 @@ var import_picocolors10 = __toESM(require_picocolors(), 1);
71807
72173
 
71808
72174
  // src/cli/run/opencode-binary-resolver.ts
71809
72175
  init_spawn_with_windows_hide();
71810
- import { delimiter, dirname as dirname8, join as join18 } from "path";
72176
+ import { delimiter, dirname as dirname9, join as join19 } from "path";
71811
72177
  var OPENCODE_COMMANDS = ["opencode", "opencode-desktop"];
71812
72178
  var WINDOWS_SUFFIXES = ["", ".exe", ".cmd", ".bat", ".ps1"];
71813
72179
  function getCommandCandidates(platform) {
@@ -71830,7 +72196,7 @@ function collectCandidateBinaryPaths(pathEnv, which = Bun.which, platform = proc
71830
72196
  }
71831
72197
  for (const entry of (pathEnv ?? "").split(delimiter).filter(Boolean)) {
71832
72198
  for (const command of commandCandidates) {
71833
- addCandidate(join18(entry, command));
72199
+ addCandidate(join19(entry, command));
71834
72200
  }
71835
72201
  }
71836
72202
  return candidates;
@@ -71857,7 +72223,7 @@ async function findWorkingOpencodeBinary(pathEnv = process.env.PATH, probe = can
71857
72223
  return null;
71858
72224
  }
71859
72225
  function buildPathWithBinaryFirst(pathEnv, binaryPath) {
71860
- const preferredDir = dirname8(binaryPath);
72226
+ const preferredDir = dirname9(binaryPath);
71861
72227
  const existing = (pathEnv ?? "").split(delimiter).filter((entry) => entry.length > 0 && entry !== preferredDir);
71862
72228
  return [preferredDir, ...existing].join(delimiter);
71863
72229
  }
@@ -72232,11 +72598,69 @@ var BOULDER_STATE_PATH = `${BOULDER_DIR}/${BOULDER_FILE}`;
72232
72598
  var NOTEPAD_DIR = "notepads";
72233
72599
  var NOTEPAD_BASE_PATH = `${BOULDER_DIR}/${NOTEPAD_DIR}`;
72234
72600
  // src/features/boulder-state/storage.ts
72235
- import { existsSync as existsSync20, readFileSync as readFileSync13, writeFileSync as writeFileSync5, mkdirSync as mkdirSync7, readdirSync as readdirSync3 } from "fs";
72236
- import { basename as basename5, dirname as dirname9, isAbsolute as isAbsolute3, join as join19, relative as relative2, resolve as resolve5 } from "path";
72601
+ import { existsSync as existsSync21, readFileSync as readFileSync14, writeFileSync as writeFileSync5, mkdirSync as mkdirSync7, readdirSync as readdirSync3 } from "fs";
72602
+ import { basename as basename5, dirname as dirname10, isAbsolute as isAbsolute3, join as join20, relative as relative2, resolve as resolve5 } from "path";
72237
72603
  var RESERVED_KEYS = new Set(["__proto__", "prototype", "constructor"]);
72604
+ function parseIsoToMs(value) {
72605
+ if (!value) {
72606
+ return null;
72607
+ }
72608
+ const parsed = Date.parse(value);
72609
+ return Number.isNaN(parsed) ? null : parsed;
72610
+ }
72611
+ function buildWorkFromMirror(state) {
72612
+ const planName = state.plan_name ?? getPlanName(state.active_plan);
72613
+ const workId = `${planName}-legacy`;
72614
+ return {
72615
+ work_id: workId,
72616
+ active_plan: state.active_plan,
72617
+ plan_name: planName,
72618
+ status: state.status,
72619
+ started_at: state.started_at,
72620
+ ended_at: state.ended_at,
72621
+ elapsed_ms: state.elapsed_ms,
72622
+ updated_at: state.updated_at,
72623
+ session_ids: Array.isArray(state.session_ids) ? [...state.session_ids] : [],
72624
+ session_origins: state.session_origins,
72625
+ agent: state.agent,
72626
+ worktree_path: state.worktree_path,
72627
+ task_sessions: state.task_sessions
72628
+ };
72629
+ }
72630
+ function projectWorkToMirror(state, work) {
72631
+ state.active_plan = work.active_plan;
72632
+ state.plan_name = work.plan_name;
72633
+ state.status = work.status;
72634
+ state.started_at = work.started_at;
72635
+ state.ended_at = work.ended_at;
72636
+ state.elapsed_ms = work.elapsed_ms;
72637
+ state.updated_at = work.updated_at;
72638
+ state.session_ids = [...work.session_ids];
72639
+ state.session_origins = work.session_origins ? { ...work.session_origins } : {};
72640
+ state.agent = work.agent;
72641
+ state.worktree_path = work.worktree_path;
72642
+ state.task_sessions = work.task_sessions ? { ...work.task_sessions } : {};
72643
+ }
72644
+ function selectMirrorWork(state) {
72645
+ const works = getBoulderWorks(state);
72646
+ if (works.length === 0) {
72647
+ return null;
72648
+ }
72649
+ if (state.active_work_id) {
72650
+ const matched = works.find((work) => work.work_id === state.active_work_id);
72651
+ if (matched) {
72652
+ return matched;
72653
+ }
72654
+ }
72655
+ const sorted = [...works].sort((left, right) => {
72656
+ const leftMs = parseIsoToMs(left.updated_at ?? left.started_at) ?? 0;
72657
+ const rightMs = parseIsoToMs(right.updated_at ?? right.started_at) ?? 0;
72658
+ return rightMs - leftMs;
72659
+ });
72660
+ return sorted[0] ?? null;
72661
+ }
72238
72662
  function getBoulderFilePath(directory) {
72239
- return join19(directory, BOULDER_DIR, BOULDER_FILE);
72663
+ return join20(directory, BOULDER_DIR, BOULDER_FILE);
72240
72664
  }
72241
72665
  function resolveTrackedPath(baseDirectory, trackedPath) {
72242
72666
  return isAbsolute3(trackedPath) ? resolve5(trackedPath) : resolve5(baseDirectory, trackedPath);
@@ -72254,15 +72678,15 @@ function resolveBoulderPlanPath(directory, state) {
72254
72678
  }
72255
72679
  const absoluteWorktreePath = resolveTrackedPath(directory, worktreePath);
72256
72680
  const worktreePlanPath = resolve5(absoluteWorktreePath, relativePlanPath);
72257
- return existsSync20(worktreePlanPath) ? worktreePlanPath : absolutePlanPath;
72681
+ return existsSync21(worktreePlanPath) ? worktreePlanPath : absolutePlanPath;
72258
72682
  }
72259
72683
  function readBoulderState(directory) {
72260
72684
  const filePath = getBoulderFilePath(directory);
72261
- if (!existsSync20(filePath)) {
72685
+ if (!existsSync21(filePath)) {
72262
72686
  return null;
72263
72687
  }
72264
72688
  try {
72265
- const content = readFileSync13(filePath, "utf-8");
72689
+ const content = readFileSync14(filePath, "utf-8");
72266
72690
  const parsed = JSON.parse(content);
72267
72691
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
72268
72692
  return null;
@@ -72282,7 +72706,13 @@ function readBoulderState(directory) {
72282
72706
  if (!parsed.task_sessions || typeof parsed.task_sessions !== "object" || Array.isArray(parsed.task_sessions)) {
72283
72707
  parsed.task_sessions = {};
72284
72708
  }
72285
- return parsed;
72709
+ const state = parsed;
72710
+ const mirrorWork = selectMirrorWork(state);
72711
+ if (mirrorWork) {
72712
+ state.active_work_id = mirrorWork.work_id;
72713
+ projectWorkToMirror(state, mirrorWork);
72714
+ }
72715
+ return state;
72286
72716
  } catch {
72287
72717
  return null;
72288
72718
  }
@@ -72295,11 +72725,11 @@ var CHECKED_CHECKBOX_PATTERN = /^(\s*)[-*]\s*\[[xX]\]\s*(.+)$/;
72295
72725
  var TODO_TASK_PATTERN = /^\d+\.\s+/;
72296
72726
  var FINAL_WAVE_TASK_PATTERN = /^F\d+\.\s+/i;
72297
72727
  function getPlanProgress(planPath) {
72298
- if (!existsSync20(planPath)) {
72299
- return { total: 0, completed: 0, isComplete: true };
72728
+ if (!existsSync21(planPath)) {
72729
+ return { total: 0, completed: 0, isComplete: false };
72300
72730
  }
72301
72731
  try {
72302
- const content = readFileSync13(planPath, "utf-8");
72732
+ const content = readFileSync14(planPath, "utf-8");
72303
72733
  const lines = content.split(/\r?\n/);
72304
72734
  const hasStructuredSections = lines.some((line) => TODO_HEADING_PATTERN.test(line) || FINAL_VERIFICATION_HEADING_PATTERN.test(line));
72305
72735
  if (hasStructuredSections) {
@@ -72307,7 +72737,7 @@ function getPlanProgress(planPath) {
72307
72737
  }
72308
72738
  return getSimplePlanProgress(content);
72309
72739
  } catch {
72310
- return { total: 0, completed: 0, isComplete: true };
72740
+ return { total: 0, completed: 0, isComplete: false };
72311
72741
  }
72312
72742
  }
72313
72743
  function getStructuredPlanProgress(lines) {
@@ -72358,6 +72788,76 @@ function getSimplePlanProgress(content) {
72358
72788
  isComplete: total > 0 && completed === total
72359
72789
  };
72360
72790
  }
72791
+ function getPlanName(planPath) {
72792
+ return basename5(planPath, ".md");
72793
+ }
72794
+ function getBoulderWorks(state) {
72795
+ if (state.works && typeof state.works === "object") {
72796
+ return Object.values(state.works);
72797
+ }
72798
+ if (!state.active_plan || !state.plan_name || !state.started_at) {
72799
+ return [];
72800
+ }
72801
+ return [buildWorkFromMirror(state)];
72802
+ }
72803
+ function resolveBoulderPlanPathForWork(directory, work) {
72804
+ return resolveBoulderPlanPath(directory, work);
72805
+ }
72806
+ // src/features/boulder-state/top-level-task.ts
72807
+ import { existsSync as existsSync22, readFileSync as readFileSync15 } from "fs";
72808
+ var TODO_HEADING_PATTERN2 = /^##\s+TODOs\b/i;
72809
+ var FINAL_VERIFICATION_HEADING_PATTERN2 = /^##\s+Final Verification Wave\b/i;
72810
+ var SECOND_LEVEL_HEADING_PATTERN2 = /^##\s+/;
72811
+ var UNCHECKED_CHECKBOX_PATTERN2 = /^(\s*)[-*]\s*\[\s*\]\s*(.+)$/;
72812
+ var TODO_TASK_PATTERN2 = /^(\d+)\.\s+(.+)$/;
72813
+ var FINAL_WAVE_TASK_PATTERN2 = /^(F\d+)\.\s+(.+)$/i;
72814
+ function buildTaskRef(section, taskLabel) {
72815
+ const pattern = section === "todo" ? TODO_TASK_PATTERN2 : FINAL_WAVE_TASK_PATTERN2;
72816
+ const match = taskLabel.match(pattern);
72817
+ if (!match) {
72818
+ return null;
72819
+ }
72820
+ const rawLabel = match[1];
72821
+ const title = match[2].trim();
72822
+ return {
72823
+ key: `${section}:${rawLabel.toLowerCase()}`,
72824
+ section,
72825
+ label: rawLabel,
72826
+ title
72827
+ };
72828
+ }
72829
+ function readCurrentTopLevelTask(planPath) {
72830
+ if (!existsSync22(planPath)) {
72831
+ return null;
72832
+ }
72833
+ try {
72834
+ const content = readFileSync15(planPath, "utf-8");
72835
+ const lines = content.split(/\r?\n/);
72836
+ let section = "other";
72837
+ for (const line of lines) {
72838
+ if (SECOND_LEVEL_HEADING_PATTERN2.test(line)) {
72839
+ section = TODO_HEADING_PATTERN2.test(line) ? "todo" : FINAL_VERIFICATION_HEADING_PATTERN2.test(line) ? "final-wave" : "other";
72840
+ }
72841
+ const uncheckedTaskMatch = line.match(UNCHECKED_CHECKBOX_PATTERN2);
72842
+ if (!uncheckedTaskMatch) {
72843
+ continue;
72844
+ }
72845
+ if (uncheckedTaskMatch[1].length > 0) {
72846
+ continue;
72847
+ }
72848
+ if (section !== "todo" && section !== "final-wave") {
72849
+ continue;
72850
+ }
72851
+ const taskRef = buildTaskRef(section, uncheckedTaskMatch[2].trim());
72852
+ if (taskRef) {
72853
+ return taskRef;
72854
+ }
72855
+ }
72856
+ return null;
72857
+ } catch {
72858
+ return null;
72859
+ }
72860
+ }
72361
72861
  // src/features/claude-code-session-state/state.ts
72362
72862
  init_agent_display_names();
72363
72863
  var subagentSessions = new Set;
@@ -72371,17 +72871,17 @@ function getSessionAgent(sessionID) {
72371
72871
  // src/features/run-continuation-state/constants.ts
72372
72872
  var CONTINUATION_MARKER_DIR = ".sisyphus/run-continuation";
72373
72873
  // src/features/run-continuation-state/storage.ts
72374
- import { existsSync as existsSync21, mkdirSync as mkdirSync8, readFileSync as readFileSync14, rmSync as rmSync2, writeFileSync as writeFileSync6 } from "fs";
72375
- import { join as join20 } from "path";
72874
+ import { existsSync as existsSync23, mkdirSync as mkdirSync8, readFileSync as readFileSync16, rmSync as rmSync2, writeFileSync as writeFileSync6 } from "fs";
72875
+ import { join as join21 } from "path";
72376
72876
  function getMarkerPath(directory, sessionID) {
72377
- return join20(directory, CONTINUATION_MARKER_DIR, `${sessionID}.json`);
72877
+ return join21(directory, CONTINUATION_MARKER_DIR, `${sessionID}.json`);
72378
72878
  }
72379
72879
  function readContinuationMarker(directory, sessionID) {
72380
72880
  const markerPath = getMarkerPath(directory, sessionID);
72381
- if (!existsSync21(markerPath))
72881
+ if (!existsSync23(markerPath))
72382
72882
  return null;
72383
72883
  try {
72384
- const raw = readFileSync14(markerPath, "utf-8");
72884
+ const raw = readFileSync16(markerPath, "utf-8");
72385
72885
  const parsed = JSON.parse(raw);
72386
72886
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
72387
72887
  return null;
@@ -72442,8 +72942,8 @@ async function isSessionInBoulderLineage(input) {
72442
72942
  // src/hooks/atlas/session-last-agent.ts
72443
72943
  init_shared();
72444
72944
  init_compaction_marker();
72445
- import { readFileSync as readFileSync15, readdirSync as readdirSync4 } from "fs";
72446
- import { join as join21 } from "path";
72945
+ import { readFileSync as readFileSync17, readdirSync as readdirSync4 } from "fs";
72946
+ import { join as join22 } from "path";
72447
72947
  var defaultSessionLastAgentDeps = {
72448
72948
  getMessageDir,
72449
72949
  isSqliteBackend,
@@ -72491,7 +72991,7 @@ async function getLastAgentFromSession(sessionID, client3, deps = {}) {
72491
72991
  try {
72492
72992
  const messages = readdirSync4(messageDir).filter((fileName) => fileName.endsWith(".json")).map((fileName) => {
72493
72993
  try {
72494
- const content = readFileSync15(join21(messageDir, fileName), "utf-8");
72994
+ const content = readFileSync17(join22(messageDir, fileName), "utf-8");
72495
72995
  const parsed = JSON.parse(content);
72496
72996
  return {
72497
72997
  fileName,
@@ -72524,8 +73024,8 @@ init_agent_display_names();
72524
73024
 
72525
73025
  // src/hooks/ralph-loop/storage.ts
72526
73026
  init_frontmatter();
72527
- import { existsSync as existsSync22, readFileSync as readFileSync16, writeFileSync as writeFileSync7, unlinkSync as unlinkSync3, mkdirSync as mkdirSync9 } from "fs";
72528
- import { dirname as dirname10, join as join22 } from "path";
73027
+ import { existsSync as existsSync24, readFileSync as readFileSync18, writeFileSync as writeFileSync7, unlinkSync as unlinkSync3, mkdirSync as mkdirSync9 } from "fs";
73028
+ import { dirname as dirname11, join as join23 } from "path";
72529
73029
 
72530
73030
  // src/hooks/ralph-loop/constants.ts
72531
73031
  var DEFAULT_STATE_FILE = ".sisyphus/ralph-loop.local.md";
@@ -72534,15 +73034,15 @@ var DEFAULT_COMPLETION_PROMISE = "DONE";
72534
73034
 
72535
73035
  // src/hooks/ralph-loop/storage.ts
72536
73036
  function getStateFilePath(directory, customPath) {
72537
- return customPath ? join22(directory, customPath) : join22(directory, DEFAULT_STATE_FILE);
73037
+ return customPath ? join23(directory, customPath) : join23(directory, DEFAULT_STATE_FILE);
72538
73038
  }
72539
73039
  function readState(directory, customPath) {
72540
73040
  const filePath = getStateFilePath(directory, customPath);
72541
- if (!existsSync22(filePath)) {
73041
+ if (!existsSync24(filePath)) {
72542
73042
  return null;
72543
73043
  }
72544
73044
  try {
72545
- const content = readFileSync16(filePath, "utf-8");
73045
+ const content = readFileSync18(filePath, "utf-8");
72546
73046
  const { data, body } = parseFrontmatter(content);
72547
73047
  const active = data.active;
72548
73048
  const iteration = data.iteration;
@@ -72987,7 +73487,7 @@ import os3 from "os";
72987
73487
  import { createHash } from "crypto";
72988
73488
 
72989
73489
  // node_modules/posthog-node/dist/extensions/error-tracking/modifiers/module.node.mjs
72990
- import { dirname as dirname11, posix, sep } from "path";
73490
+ import { dirname as dirname12, posix, sep } from "path";
72991
73491
  function createModulerModifier() {
72992
73492
  const getModuleFromFileName = createGetModuleFromFilename();
72993
73493
  return async (frames) => {
@@ -72996,7 +73496,7 @@ function createModulerModifier() {
72996
73496
  return frames;
72997
73497
  };
72998
73498
  }
72999
- function createGetModuleFromFilename(basePath = process.argv[1] ? dirname11(process.argv[1]) : process.cwd(), isWindows = sep === "\\") {
73499
+ function createGetModuleFromFilename(basePath = process.argv[1] ? dirname12(process.argv[1]) : process.cwd(), isWindows = sep === "\\") {
73000
73500
  const normalizedBase = isWindows ? normalizeWindowsPath(basePath) : basePath;
73001
73501
  return (filename) => {
73002
73502
  if (!filename)
@@ -73018,8 +73518,8 @@ function createGetModuleFromFilename(basePath = process.argv[1] ? dirname11(proc
73018
73518
  return decodedFile;
73019
73519
  };
73020
73520
  }
73021
- function normalizeWindowsPath(path6) {
73022
- return path6.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
73521
+ function normalizeWindowsPath(path7) {
73522
+ return path7.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
73023
73523
  }
73024
73524
 
73025
73525
  // node_modules/@posthog/core/dist/featureFlagUtils.mjs
@@ -75334,9 +75834,9 @@ async function addSourceContext(frames) {
75334
75834
  LRU_FILE_CONTENTS_CACHE.reduce();
75335
75835
  return frames;
75336
75836
  }
75337
- function getContextLinesFromFile(path6, ranges, output) {
75837
+ function getContextLinesFromFile(path7, ranges, output) {
75338
75838
  return new Promise((resolve6) => {
75339
- const stream = createReadStream(path6);
75839
+ const stream = createReadStream(path7);
75340
75840
  const lineReaded = createInterface2({
75341
75841
  input: stream
75342
75842
  });
@@ -75352,7 +75852,7 @@ function getContextLinesFromFile(path6, ranges, output) {
75352
75852
  let rangeStart = range[0];
75353
75853
  let rangeEnd = range[1];
75354
75854
  function onStreamError() {
75355
- LRU_FILE_CONTENTS_FS_READ_FAILED.set(path6, 1);
75855
+ LRU_FILE_CONTENTS_FS_READ_FAILED.set(path7, 1);
75356
75856
  lineReaded.close();
75357
75857
  lineReaded.removeAllListeners();
75358
75858
  destroyStreamAndResolve();
@@ -75420,8 +75920,8 @@ function clearLineContext(frame) {
75420
75920
  delete frame.context_line;
75421
75921
  delete frame.post_context;
75422
75922
  }
75423
- function shouldSkipContextLinesForFile(path6) {
75424
- return path6.startsWith("node:") || path6.endsWith(".min.js") || path6.endsWith(".min.cjs") || path6.endsWith(".min.mjs") || path6.startsWith("data:");
75923
+ function shouldSkipContextLinesForFile(path7) {
75924
+ return path7.startsWith("node:") || path7.endsWith(".min.js") || path7.endsWith(".min.cjs") || path7.endsWith(".min.mjs") || path7.startsWith("data:");
75425
75925
  }
75426
75926
  function shouldSkipContextLinesForFrame(frame) {
75427
75927
  if (frame.lineno !== undefined && frame.lineno > MAX_CONTEXTLINES_LINENO)
@@ -77434,11 +77934,11 @@ init_data_path();
77434
77934
  init_logger();
77435
77935
  init_plugin_identity();
77436
77936
  init_write_file_atomically();
77437
- import { existsSync as existsSync23, mkdirSync as mkdirSync10, readFileSync as readFileSync17 } from "fs";
77438
- import { join as join23 } from "path";
77937
+ import { existsSync as existsSync25, mkdirSync as mkdirSync10, readFileSync as readFileSync19 } from "fs";
77938
+ import { join as join24 } from "path";
77439
77939
  var POSTHOG_ACTIVITY_STATE_FILE = "posthog-activity.json";
77440
77940
  function getPostHogActivityStateFilePath() {
77441
- return join23(getDataDir(), CACHE_DIR_NAME, POSTHOG_ACTIVITY_STATE_FILE);
77941
+ return join24(getDataDir(), CACHE_DIR_NAME, POSTHOG_ACTIVITY_STATE_FILE);
77442
77942
  }
77443
77943
  function getUtcDayString(date5) {
77444
77944
  return date5.toISOString().slice(0, 10);
@@ -77448,11 +77948,11 @@ function isPostHogActivityState(value) {
77448
77948
  }
77449
77949
  function readPostHogActivityState() {
77450
77950
  const stateFilePath = getPostHogActivityStateFilePath();
77451
- if (!existsSync23(stateFilePath)) {
77951
+ if (!existsSync25(stateFilePath)) {
77452
77952
  return {};
77453
77953
  }
77454
77954
  try {
77455
- const content = readFileSync17(stateFilePath, "utf-8");
77955
+ const content = readFileSync19(stateFilePath, "utf-8");
77456
77956
  const parsed = JSON.parse(content);
77457
77957
  if (!isPostHogActivityState(parsed)) {
77458
77958
  return {};
@@ -77469,7 +77969,7 @@ function readPostHogActivityState() {
77469
77969
  function writePostHogActivityState(nextState) {
77470
77970
  const stateFilePath = getPostHogActivityStateFilePath();
77471
77971
  try {
77472
- mkdirSync10(join23(getDataDir(), CACHE_DIR_NAME), { recursive: true });
77972
+ mkdirSync10(join24(getDataDir(), CACHE_DIR_NAME), { recursive: true });
77473
77973
  writeFileAtomically(stateFilePath, `${JSON.stringify(nextState, null, 2)}
77474
77974
  `);
77475
77975
  } catch (error48) {
@@ -77892,12 +78392,12 @@ async function getLocalVersion(options = {}) {
77892
78392
  }
77893
78393
  }
77894
78394
  // src/cli/doctor/checks/system.ts
77895
- import { existsSync as existsSync34, readFileSync as readFileSync27 } from "fs";
78395
+ import { existsSync as existsSync36, readFileSync as readFileSync29 } from "fs";
77896
78396
 
77897
78397
  // src/cli/doctor/checks/system-binary.ts
77898
- import { existsSync as existsSync31 } from "fs";
77899
- import { homedir as homedir7 } from "os";
77900
- import { join as join30 } from "path";
78398
+ import { existsSync as existsSync33 } from "fs";
78399
+ import { homedir as homedir8 } from "os";
78400
+ import { join as join31 } from "path";
77901
78401
 
77902
78402
  // src/cli/doctor/spawn-with-timeout.ts
77903
78403
  init_spawn_with_windows_hide();
@@ -77931,22 +78431,22 @@ async function spawnWithTimeout(command, options, timeoutMs = DEFAULT_SPAWN_TIME
77931
78431
 
77932
78432
  // src/cli/doctor/checks/system-binary.ts
77933
78433
  function getDesktopAppPaths(platform) {
77934
- const home = homedir7();
78434
+ const home = homedir8();
77935
78435
  switch (platform) {
77936
78436
  case "darwin":
77937
78437
  return [
77938
78438
  "/Applications/OpenCode.app/Contents/MacOS/OpenCode",
77939
- join30(home, "Applications", "OpenCode.app", "Contents", "MacOS", "OpenCode")
78439
+ join31(home, "Applications", "OpenCode.app", "Contents", "MacOS", "OpenCode")
77940
78440
  ];
77941
78441
  case "win32": {
77942
78442
  const programFiles = process.env.ProgramFiles;
77943
78443
  const localAppData = process.env.LOCALAPPDATA;
77944
78444
  const paths = [];
77945
78445
  if (programFiles) {
77946
- paths.push(join30(programFiles, "OpenCode", "OpenCode.exe"));
78446
+ paths.push(join31(programFiles, "OpenCode", "OpenCode.exe"));
77947
78447
  }
77948
78448
  if (localAppData) {
77949
- paths.push(join30(localAppData, "OpenCode", "OpenCode.exe"));
78449
+ paths.push(join31(localAppData, "OpenCode", "OpenCode.exe"));
77950
78450
  }
77951
78451
  return paths;
77952
78452
  }
@@ -77954,8 +78454,8 @@ function getDesktopAppPaths(platform) {
77954
78454
  return [
77955
78455
  "/usr/bin/opencode",
77956
78456
  "/usr/lib/opencode/opencode",
77957
- join30(home, "Applications", "opencode-desktop-linux-x86_64.AppImage"),
77958
- join30(home, "Applications", "opencode-desktop-linux-aarch64.AppImage")
78457
+ join31(home, "Applications", "opencode-desktop-linux-x86_64.AppImage"),
78458
+ join31(home, "Applications", "opencode-desktop-linux-aarch64.AppImage")
77959
78459
  ];
77960
78460
  default:
77961
78461
  return [];
@@ -77967,7 +78467,7 @@ function buildVersionCommand(binaryPath, platform) {
77967
78467
  }
77968
78468
  return [binaryPath, "--version"];
77969
78469
  }
77970
- function findDesktopBinary(platform = process.platform, checkExists = existsSync31) {
78470
+ function findDesktopBinary(platform = process.platform, checkExists = existsSync33) {
77971
78471
  for (const desktopPath of getDesktopAppPaths(platform)) {
77972
78472
  if (checkExists(desktopPath)) {
77973
78473
  return { binary: "opencode", path: desktopPath };
@@ -77977,9 +78477,9 @@ function findDesktopBinary(platform = process.platform, checkExists = existsSync
77977
78477
  }
77978
78478
  async function findOpenCodeBinary() {
77979
78479
  for (const binary2 of OPENCODE_BINARIES2) {
77980
- const path12 = Bun.which(binary2);
77981
- if (path12) {
77982
- return { binary: binary2, path: path12 };
78480
+ const path13 = Bun.which(binary2);
78481
+ if (path13) {
78482
+ return { binary: binary2, path: path13 };
77983
78483
  }
77984
78484
  }
77985
78485
  return findDesktopBinary();
@@ -77990,7 +78490,7 @@ async function getOpenCodeVersion3(binaryPath, platform = process.platform) {
77990
78490
  const result = await spawnWithTimeout(command, { stdout: "pipe", stderr: "pipe" });
77991
78491
  if (result.timedOut || result.exitCode !== 0)
77992
78492
  return null;
77993
- return result.stdout.trim() || null;
78493
+ return extractSemverFromOutput(result.stdout);
77994
78494
  } catch {
77995
78495
  return null;
77996
78496
  }
@@ -78013,12 +78513,12 @@ function compareVersions3(current, minimum) {
78013
78513
 
78014
78514
  // src/cli/doctor/checks/system-plugin.ts
78015
78515
  init_shared();
78016
- import { existsSync as existsSync32, readFileSync as readFileSync25 } from "fs";
78516
+ import { existsSync as existsSync34, readFileSync as readFileSync27 } from "fs";
78017
78517
  function detectConfigPath() {
78018
78518
  const paths = getOpenCodeConfigPaths({ binary: "opencode", version: null });
78019
- if (existsSync32(paths.configJsonc))
78519
+ if (existsSync34(paths.configJsonc))
78020
78520
  return paths.configJsonc;
78021
- if (existsSync32(paths.configJson))
78521
+ if (existsSync34(paths.configJson))
78022
78522
  return paths.configJson;
78023
78523
  return null;
78024
78524
  }
@@ -78064,7 +78564,7 @@ function getPluginInfo() {
78064
78564
  };
78065
78565
  }
78066
78566
  try {
78067
- const content = readFileSync25(configPath, "utf-8");
78567
+ const content = readFileSync27(configPath, "utf-8");
78068
78568
  const parsedConfig = parseJsonc(content);
78069
78569
  const pluginEntry = findPluginEntry2(parsedConfig.plugin ?? []);
78070
78570
  if (!pluginEntry) {
@@ -78102,37 +78602,37 @@ function getPluginInfo() {
78102
78602
  init_file_utils();
78103
78603
  init_checker();
78104
78604
  init_auto_update_checker();
78105
- import { existsSync as existsSync33, readFileSync as readFileSync26 } from "fs";
78106
- import { homedir as homedir8 } from "os";
78107
- import { join as join31 } from "path";
78605
+ import { existsSync as existsSync35, readFileSync as readFileSync28 } from "fs";
78606
+ import { homedir as homedir9 } from "os";
78607
+ import { join as join32 } from "path";
78108
78608
  init_shared();
78109
78609
  function getPlatformDefaultCacheDir(platform = process.platform) {
78110
78610
  if (platform === "darwin")
78111
- return join31(homedir8(), "Library", "Caches");
78611
+ return join32(homedir9(), "Library", "Caches");
78112
78612
  if (platform === "win32")
78113
- return process.env.LOCALAPPDATA ?? join31(homedir8(), "AppData", "Local");
78114
- return join31(homedir8(), ".cache");
78613
+ return process.env.LOCALAPPDATA ?? join32(homedir9(), "AppData", "Local");
78614
+ return join32(homedir9(), ".cache");
78115
78615
  }
78116
78616
  function resolveOpenCodeCacheDir() {
78117
78617
  const xdgCacheHome = process.env.XDG_CACHE_HOME;
78118
78618
  if (xdgCacheHome)
78119
- return join31(xdgCacheHome, "opencode");
78619
+ return join32(xdgCacheHome, "opencode");
78120
78620
  const fromShared = getOpenCodeCacheDir();
78121
- const platformDefault = join31(getPlatformDefaultCacheDir(), "opencode");
78122
- if (existsSync33(fromShared) || !existsSync33(platformDefault))
78621
+ const platformDefault = join32(getPlatformDefaultCacheDir(), "opencode");
78622
+ if (existsSync35(fromShared) || !existsSync35(platformDefault))
78123
78623
  return fromShared;
78124
78624
  return platformDefault;
78125
78625
  }
78126
78626
  function resolveExistingDir(dirPath) {
78127
- if (!existsSync33(dirPath))
78627
+ if (!existsSync35(dirPath))
78128
78628
  return dirPath;
78129
78629
  return resolveSymlink(dirPath);
78130
78630
  }
78131
78631
  function readPackageJson(filePath) {
78132
- if (!existsSync33(filePath))
78632
+ if (!existsSync35(filePath))
78133
78633
  return null;
78134
78634
  try {
78135
- const content = readFileSync26(filePath, "utf-8");
78635
+ const content = readFileSync28(filePath, "utf-8");
78136
78636
  return parseJsonc(content);
78137
78637
  } catch {
78138
78638
  return null;
@@ -78147,11 +78647,11 @@ function normalizeVersion(value) {
78147
78647
  function createPackageCandidates(rootDir) {
78148
78648
  return ACCEPTED_PACKAGE_NAMES.map((packageName) => ({
78149
78649
  packageName,
78150
- installedPackagePath: join31(rootDir, "node_modules", packageName, "package.json")
78650
+ installedPackagePath: join32(rootDir, "node_modules", packageName, "package.json")
78151
78651
  }));
78152
78652
  }
78153
78653
  function selectInstalledPackage(candidate) {
78154
- return candidate.packageCandidates.find((packageCandidate) => existsSync33(packageCandidate.installedPackagePath)) ?? candidate.packageCandidates[0];
78654
+ return candidate.packageCandidates.find((packageCandidate) => existsSync35(packageCandidate.installedPackagePath)) ?? candidate.packageCandidates[0];
78155
78655
  }
78156
78656
  function getExpectedVersion(cachePackage, packageName) {
78157
78657
  return normalizeVersion(cachePackage?.dependencies?.[packageName]) ?? normalizeVersion(cachePackage?.dependencies?.[PACKAGE_NAME]);
@@ -78163,16 +78663,16 @@ function getLoadedPluginVersion() {
78163
78663
  const candidates = [
78164
78664
  {
78165
78665
  cacheDir: configDir,
78166
- cachePackagePath: join31(configDir, "package.json"),
78666
+ cachePackagePath: join32(configDir, "package.json"),
78167
78667
  packageCandidates: createPackageCandidates(configDir)
78168
78668
  },
78169
78669
  {
78170
78670
  cacheDir,
78171
- cachePackagePath: join31(cacheDir, "package.json"),
78671
+ cachePackagePath: join32(cacheDir, "package.json"),
78172
78672
  packageCandidates: createPackageCandidates(cacheDir)
78173
78673
  }
78174
78674
  ];
78175
- const selectedCandidate = candidates.find((candidate) => candidate.packageCandidates.some((packageCandidate) => existsSync33(packageCandidate.installedPackagePath))) ?? candidates[0];
78675
+ const selectedCandidate = candidates.find((candidate) => candidate.packageCandidates.some((packageCandidate) => existsSync35(packageCandidate.installedPackagePath))) ?? candidates[0];
78176
78676
  const { cacheDir: selectedDir, cachePackagePath } = selectedCandidate;
78177
78677
  const selectedPackage = selectInstalledPackage(selectedCandidate);
78178
78678
  const installedPackagePath = selectedPackage.installedPackagePath;
@@ -78199,7 +78699,7 @@ function getSuggestedInstallTag(currentVersion) {
78199
78699
  // src/cli/doctor/checks/system.ts
78200
78700
  init_shared();
78201
78701
  init_plugin_identity();
78202
- var defaultDeps3 = {
78702
+ var defaultDeps4 = {
78203
78703
  findOpenCodeBinary,
78204
78704
  getOpenCodeVersion: getOpenCodeVersion3,
78205
78705
  compareVersions: compareVersions3,
@@ -78211,10 +78711,10 @@ var defaultDeps3 = {
78211
78711
  function isConfigValid(configPath) {
78212
78712
  if (!configPath)
78213
78713
  return true;
78214
- if (!existsSync34(configPath))
78714
+ if (!existsSync36(configPath))
78215
78715
  return false;
78216
78716
  try {
78217
- parseJsonc(readFileSync27(configPath, "utf-8"));
78717
+ parseJsonc(readFileSync29(configPath, "utf-8"));
78218
78718
  return true;
78219
78719
  } catch {
78220
78720
  return false;
@@ -78234,7 +78734,7 @@ function buildMessage(status, issues) {
78234
78734
  return `${issues.length} system issue(s) detected`;
78235
78735
  return `${issues.length} system warning(s) detected`;
78236
78736
  }
78237
- async function gatherSystemInfo(deps = defaultDeps3) {
78737
+ async function gatherSystemInfo(deps = defaultDeps4) {
78238
78738
  const [binaryInfo, pluginInfo] = await Promise.all([
78239
78739
  deps.findOpenCodeBinary(),
78240
78740
  Promise.resolve(deps.getPluginInfo())
@@ -78253,7 +78753,7 @@ async function gatherSystemInfo(deps = defaultDeps3) {
78253
78753
  isLocalDev: pluginInfo.isLocalDev
78254
78754
  };
78255
78755
  }
78256
- async function checkSystem(deps = defaultDeps3) {
78756
+ async function checkSystem(deps = defaultDeps4) {
78257
78757
  const [systemInfo, pluginInfo] = await Promise.all([
78258
78758
  gatherSystemInfo(deps),
78259
78759
  Promise.resolve(deps.getPluginInfo())
@@ -78336,32 +78836,32 @@ async function checkSystem(deps = defaultDeps3) {
78336
78836
  }
78337
78837
 
78338
78838
  // src/cli/doctor/checks/config.ts
78339
- import { readFileSync as readFileSync30 } from "fs";
78340
- import { join as join35 } from "path";
78839
+ import { readFileSync as readFileSync32 } from "fs";
78840
+ import { join as join36 } from "path";
78341
78841
  init_shared();
78342
78842
 
78343
78843
  // src/cli/doctor/checks/model-resolution-cache.ts
78344
78844
  init_shared();
78345
- import { existsSync as existsSync35, readFileSync as readFileSync28 } from "fs";
78346
- import { homedir as homedir9 } from "os";
78347
- import { join as join32 } from "path";
78845
+ import { existsSync as existsSync37, readFileSync as readFileSync30 } from "fs";
78846
+ import { homedir as homedir10 } from "os";
78847
+ import { join as join33 } from "path";
78348
78848
  function getUserConfigDir2() {
78349
78849
  const xdgConfig = process.env.XDG_CONFIG_HOME;
78350
78850
  if (xdgConfig)
78351
- return join32(xdgConfig, "opencode");
78352
- return join32(homedir9(), ".config", "opencode");
78851
+ return join33(xdgConfig, "opencode");
78852
+ return join33(homedir10(), ".config", "opencode");
78353
78853
  }
78354
78854
  function loadCustomProviderNames() {
78355
78855
  const configDir = getUserConfigDir2();
78356
78856
  const candidatePaths = [
78357
- join32(configDir, "opencode.json"),
78358
- join32(configDir, "opencode.jsonc")
78857
+ join33(configDir, "opencode.json"),
78858
+ join33(configDir, "opencode.jsonc")
78359
78859
  ];
78360
78860
  for (const configPath of candidatePaths) {
78361
- if (!existsSync35(configPath))
78861
+ if (!existsSync37(configPath))
78362
78862
  continue;
78363
78863
  try {
78364
- const content = readFileSync28(configPath, "utf-8");
78864
+ const content = readFileSync30(configPath, "utf-8");
78365
78865
  const data = parseJsonc(content);
78366
78866
  if (data?.provider && typeof data.provider === "object") {
78367
78867
  return Object.keys(data.provider);
@@ -78371,16 +78871,16 @@ function loadCustomProviderNames() {
78371
78871
  return [];
78372
78872
  }
78373
78873
  function loadAvailableModelsFromCache() {
78374
- const cacheFile = join32(getOpenCodeCacheDir(), "models.json");
78874
+ const cacheFile = join33(getOpenCodeCacheDir(), "models.json");
78375
78875
  const customProviders = loadCustomProviderNames();
78376
- if (!existsSync35(cacheFile)) {
78876
+ if (!existsSync37(cacheFile)) {
78377
78877
  if (customProviders.length > 0) {
78378
78878
  return { providers: customProviders, modelCount: 0, cacheExists: true };
78379
78879
  }
78380
78880
  return { providers: [], modelCount: 0, cacheExists: false };
78381
78881
  }
78382
78882
  try {
78383
- const content = readFileSync28(cacheFile, "utf-8");
78883
+ const content = readFileSync30(cacheFile, "utf-8");
78384
78884
  const data = parseJsonc(content);
78385
78885
  const cacheProviders = Object.keys(data);
78386
78886
  let modelCount = 0;
@@ -78403,14 +78903,14 @@ init_model_capabilities();
78403
78903
 
78404
78904
  // src/cli/doctor/checks/model-resolution-config.ts
78405
78905
  init_shared();
78406
- import { readFileSync as readFileSync29 } from "fs";
78407
- import { join as join33 } from "path";
78408
- var PROJECT_CONFIG_DIR = join33(process.cwd(), ".opencode");
78906
+ import { readFileSync as readFileSync31 } from "fs";
78907
+ import { join as join34 } from "path";
78908
+ var PROJECT_CONFIG_DIR = join34(process.cwd(), ".opencode");
78409
78909
  function loadOmoConfig() {
78410
78910
  const projectDetected = detectPluginConfigFile(PROJECT_CONFIG_DIR);
78411
78911
  if (projectDetected.format !== "none") {
78412
78912
  try {
78413
- const content = readFileSync29(projectDetected.path, "utf-8");
78913
+ const content = readFileSync31(projectDetected.path, "utf-8");
78414
78914
  return parseJsonc(content);
78415
78915
  } catch {
78416
78916
  return null;
@@ -78420,7 +78920,7 @@ function loadOmoConfig() {
78420
78920
  const userDetected = detectPluginConfigFile(userConfigDir);
78421
78921
  if (userDetected.format !== "none") {
78422
78922
  try {
78423
- const content = readFileSync29(userDetected.path, "utf-8");
78923
+ const content = readFileSync31(userDetected.path, "utf-8");
78424
78924
  return parseJsonc(content);
78425
78925
  } catch {
78426
78926
  return null;
@@ -78431,7 +78931,7 @@ function loadOmoConfig() {
78431
78931
 
78432
78932
  // src/cli/doctor/checks/model-resolution-details.ts
78433
78933
  init_shared();
78434
- import { join as join34 } from "path";
78934
+ import { join as join35 } from "path";
78435
78935
 
78436
78936
  // src/cli/doctor/checks/model-resolution-variant.ts
78437
78937
  function formatModelWithVariant(model, variant) {
@@ -78473,7 +78973,7 @@ function formatCapabilityResolutionLabel(mode) {
78473
78973
  }
78474
78974
  function buildModelResolutionDetails(options) {
78475
78975
  const details = [];
78476
- const cacheFile = join34(getOpenCodeCacheDir(), "models.json");
78976
+ const cacheFile = join35(getOpenCodeCacheDir(), "models.json");
78477
78977
  details.push("\u2550\u2550\u2550 Available Models (from cache) \u2550\u2550\u2550");
78478
78978
  details.push("");
78479
78979
  if (options.available.cacheExists) {
@@ -78628,7 +79128,7 @@ async function checkModels() {
78628
79128
  }
78629
79129
 
78630
79130
  // src/cli/doctor/checks/config.ts
78631
- var PROJECT_CONFIG_DIR2 = join35(process.cwd(), ".opencode");
79131
+ var PROJECT_CONFIG_DIR2 = join36(process.cwd(), ".opencode");
78632
79132
  function findConfigPath() {
78633
79133
  const projectConfig = detectPluginConfigFile(PROJECT_CONFIG_DIR2);
78634
79134
  if (projectConfig.format !== "none")
@@ -78645,7 +79145,7 @@ function validateConfig() {
78645
79145
  return { exists: false, path: null, valid: true, config: null, errors: [] };
78646
79146
  }
78647
79147
  try {
78648
- const content = readFileSync30(configPath, "utf-8");
79148
+ const content = readFileSync32(configPath, "utf-8");
78649
79149
  const rawConfig = parseJsonc(content);
78650
79150
  const schemaResult = OhMyOpenCodeConfigSchema.safeParse(rawConfig);
78651
79151
  if (!schemaResult.success) {
@@ -78748,27 +79248,27 @@ async function checkConfig() {
78748
79248
  }
78749
79249
 
78750
79250
  // src/cli/doctor/checks/dependencies.ts
78751
- import { existsSync as existsSync36 } from "fs";
79251
+ import { existsSync as existsSync38 } from "fs";
78752
79252
  import { createRequire } from "module";
78753
- import { dirname as dirname15, join as join37 } from "path";
79253
+ import { dirname as dirname16, join as join38 } from "path";
78754
79254
 
78755
79255
  // src/hooks/comment-checker/downloader.ts
78756
- import { join as join36 } from "path";
78757
- import { homedir as homedir10, tmpdir as tmpdir3 } from "os";
79256
+ import { join as join37 } from "path";
79257
+ import { homedir as homedir11, tmpdir as tmpdir3 } from "os";
78758
79258
  init_binary_downloader();
78759
79259
  init_logger();
78760
79260
  init_plugin_identity();
78761
79261
  var DEBUG = process.env.COMMENT_CHECKER_DEBUG === "1";
78762
- var DEBUG_FILE = join36(tmpdir3(), "comment-checker-debug.log");
79262
+ var DEBUG_FILE = join37(tmpdir3(), "comment-checker-debug.log");
78763
79263
  function getCacheDir2() {
78764
79264
  if (process.platform === "win32") {
78765
79265
  const localAppData = process.env.LOCALAPPDATA || process.env.APPDATA;
78766
- const base2 = localAppData || join36(homedir10(), "AppData", "Local");
78767
- return join36(base2, CACHE_DIR_NAME, "bin");
79266
+ const base2 = localAppData || join37(homedir11(), "AppData", "Local");
79267
+ return join37(base2, CACHE_DIR_NAME, "bin");
78768
79268
  }
78769
79269
  const xdgCache = process.env.XDG_CACHE_HOME;
78770
- const base = xdgCache || join36(homedir10(), ".cache");
78771
- return join36(base, CACHE_DIR_NAME, "bin");
79270
+ const base = xdgCache || join37(homedir11(), ".cache");
79271
+ return join37(base, CACHE_DIR_NAME, "bin");
78772
79272
  }
78773
79273
  function getBinaryName() {
78774
79274
  return process.platform === "win32" ? "comment-checker.exe" : "comment-checker";
@@ -78780,9 +79280,9 @@ function getCachedBinaryPath2() {
78780
79280
  // src/cli/doctor/checks/dependencies.ts
78781
79281
  async function checkBinaryExists(binary2) {
78782
79282
  try {
78783
- const path12 = Bun.which(binary2);
78784
- if (path12) {
78785
- return { exists: true, path: path12 };
79283
+ const path13 = Bun.which(binary2);
79284
+ if (path13) {
79285
+ return { exists: true, path: path13 };
78786
79286
  }
78787
79287
  } catch {}
78788
79288
  return { exists: false, path: null };
@@ -78832,15 +79332,15 @@ async function checkAstGrepNapi() {
78832
79332
  path: null
78833
79333
  };
78834
79334
  } catch {
78835
- const { existsSync: existsSync37 } = await import("fs");
78836
- const { join: join38 } = await import("path");
78837
- const { homedir: homedir11 } = await import("os");
79335
+ const { existsSync: existsSync39 } = await import("fs");
79336
+ const { join: join39 } = await import("path");
79337
+ const { homedir: homedir12 } = await import("os");
78838
79338
  const pathsToCheck = [
78839
- join38(homedir11(), ".config", "opencode", "node_modules", "@ast-grep", "napi"),
78840
- join38(process.cwd(), "node_modules", "@ast-grep", "napi")
79339
+ join39(homedir12(), ".config", "opencode", "node_modules", "@ast-grep", "napi"),
79340
+ join39(process.cwd(), "node_modules", "@ast-grep", "napi")
78841
79341
  ];
78842
79342
  for (const napiPath of pathsToCheck) {
78843
- if (existsSync37(napiPath)) {
79343
+ if (existsSync39(napiPath)) {
78844
79344
  return {
78845
79345
  name: "AST-Grep NAPI",
78846
79346
  required: false,
@@ -78865,8 +79365,8 @@ function findCommentCheckerPackageBinary() {
78865
79365
  try {
78866
79366
  const require2 = createRequire(import.meta.url);
78867
79367
  const pkgPath = require2.resolve("@code-yeongyu/comment-checker/package.json");
78868
- const binaryPath = join37(dirname15(pkgPath), "bin", binaryName);
78869
- if (existsSync36(binaryPath))
79368
+ const binaryPath = join38(dirname16(pkgPath), "bin", binaryName);
79369
+ if (existsSync38(binaryPath))
78870
79370
  return binaryPath;
78871
79371
  } catch {}
78872
79372
  return null;
@@ -79040,15 +79540,15 @@ var BUILTIN_SERVERS = {
79040
79540
  "kotlin-ls": { command: ["kotlin-lsp"], extensions: [".kt", ".kts"] }
79041
79541
  };
79042
79542
  // src/tools/lsp/server-config-loader.ts
79043
- import { existsSync as existsSync37, readFileSync as readFileSync31 } from "fs";
79044
- import { join as join38 } from "path";
79543
+ import { existsSync as existsSync39, readFileSync as readFileSync33 } from "fs";
79544
+ import { join as join39 } from "path";
79045
79545
  init_shared();
79046
79546
  init_jsonc_parser();
79047
- function loadJsonFile(path12) {
79048
- if (!existsSync37(path12))
79547
+ function loadJsonFile(path13) {
79548
+ if (!existsSync39(path13))
79049
79549
  return null;
79050
79550
  try {
79051
- return parseJsonc(readFileSync31(path12, "utf-8"));
79551
+ return parseJsonc(readFileSync33(path13, "utf-8"));
79052
79552
  } catch {
79053
79553
  return null;
79054
79554
  }
@@ -79057,9 +79557,9 @@ function getConfigPaths2() {
79057
79557
  const cwd = process.cwd();
79058
79558
  const configDir = getOpenCodeConfigDir({ binary: "opencode" });
79059
79559
  return {
79060
- project: detectPluginConfigFile(join38(cwd, ".opencode")).path,
79560
+ project: detectPluginConfigFile(join39(cwd, ".opencode")).path,
79061
79561
  user: detectPluginConfigFile(configDir).path,
79062
- opencode: detectConfigFile(join38(configDir, "opencode")).path
79562
+ opencode: detectConfigFile(join39(configDir, "opencode")).path
79063
79563
  };
79064
79564
  }
79065
79565
  function loadAllConfigs() {
@@ -79128,21 +79628,21 @@ function getMergedServers() {
79128
79628
  }
79129
79629
 
79130
79630
  // src/tools/lsp/server-installation.ts
79131
- import { existsSync as existsSync38 } from "fs";
79132
- import { delimiter as delimiter2, join as join40 } from "path";
79631
+ import { existsSync as existsSync40 } from "fs";
79632
+ import { delimiter as delimiter2, join as join41 } from "path";
79133
79633
 
79134
79634
  // src/tools/lsp/server-path-bases.ts
79135
79635
  init_shared();
79136
- import { join as join39 } from "path";
79636
+ import { join as join40 } from "path";
79137
79637
  function getLspServerAdditionalPathBases(workingDirectory) {
79138
79638
  const configDir = getOpenCodeConfigDir({ binary: "opencode" });
79139
- const dataDir = join39(getDataDir(), "opencode");
79639
+ const dataDir = join40(getDataDir(), "opencode");
79140
79640
  return [
79141
- join39(workingDirectory, "node_modules", ".bin"),
79142
- join39(configDir, "bin"),
79143
- join39(configDir, "node_modules", ".bin"),
79144
- join39(dataDir, "bin"),
79145
- join39(dataDir, "bin", "node_modules", ".bin")
79641
+ join40(workingDirectory, "node_modules", ".bin"),
79642
+ join40(configDir, "bin"),
79643
+ join40(configDir, "node_modules", ".bin"),
79644
+ join40(dataDir, "bin"),
79645
+ join40(dataDir, "bin", "node_modules", ".bin")
79146
79646
  ];
79147
79647
  }
79148
79648
 
@@ -79152,7 +79652,7 @@ function isServerInstalled(command) {
79152
79652
  return false;
79153
79653
  const cmd = command[0];
79154
79654
  if (cmd.includes("/") || cmd.includes("\\")) {
79155
- if (existsSync38(cmd))
79655
+ if (existsSync40(cmd))
79156
79656
  return true;
79157
79657
  }
79158
79658
  const isWindows = process.platform === "win32";
@@ -79173,14 +79673,14 @@ function isServerInstalled(command) {
79173
79673
  const paths = pathEnv.split(delimiter2);
79174
79674
  for (const p2 of paths) {
79175
79675
  for (const suffix of exts) {
79176
- if (existsSync38(join40(p2, cmd + suffix))) {
79676
+ if (existsSync40(join41(p2, cmd + suffix))) {
79177
79677
  return true;
79178
79678
  }
79179
79679
  }
79180
79680
  }
79181
79681
  for (const base of getLspServerAdditionalPathBases(process.cwd())) {
79182
79682
  for (const suffix of exts) {
79183
- if (existsSync38(join40(base, cmd + suffix))) {
79683
+ if (existsSync40(join41(base, cmd + suffix))) {
79184
79684
  return true;
79185
79685
  }
79186
79686
  }
@@ -79242,24 +79742,24 @@ function getInstalledLspServers() {
79242
79742
 
79243
79743
  // src/cli/doctor/checks/tools-mcp.ts
79244
79744
  init_shared();
79245
- import { existsSync as existsSync39, readFileSync as readFileSync32 } from "fs";
79246
- import { homedir as homedir11 } from "os";
79247
- import { join as join41 } from "path";
79745
+ import { existsSync as existsSync41, readFileSync as readFileSync34 } from "fs";
79746
+ import { homedir as homedir12 } from "os";
79747
+ import { join as join42 } from "path";
79248
79748
  var BUILTIN_MCP_SERVERS = ["context7", "grep_app"];
79249
79749
  function getMcpConfigPaths() {
79250
79750
  return [
79251
- join41(homedir11(), ".claude", ".mcp.json"),
79252
- join41(process.cwd(), ".mcp.json"),
79253
- join41(process.cwd(), ".claude", ".mcp.json")
79751
+ join42(homedir12(), ".claude", ".mcp.json"),
79752
+ join42(process.cwd(), ".mcp.json"),
79753
+ join42(process.cwd(), ".claude", ".mcp.json")
79254
79754
  ];
79255
79755
  }
79256
79756
  function loadUserMcpConfig() {
79257
79757
  const servers = {};
79258
79758
  for (const configPath of getMcpConfigPaths()) {
79259
- if (!existsSync39(configPath))
79759
+ if (!existsSync41(configPath))
79260
79760
  continue;
79261
79761
  try {
79262
- const content = readFileSync32(configPath, "utf-8");
79762
+ const content = readFileSync34(configPath, "utf-8");
79263
79763
  const config2 = parseJsonc(content);
79264
79764
  if (config2.mcpServers) {
79265
79765
  Object.assign(servers, config2.mcpServers);
@@ -79392,6 +79892,7 @@ async function checkTools() {
79392
79892
  }
79393
79893
 
79394
79894
  // src/features/team-mode/deps.ts
79895
+ init_bun_spawn_shim();
79395
79896
  async function checkTeamModeDependencies(config2) {
79396
79897
  const tmuxAvailable = Boolean(process.env["TMUX"]) || await probeBinary("tmux", ["-V"]);
79397
79898
  const gitAvailable = await probeBinary("git", ["--version"]);
@@ -79402,7 +79903,7 @@ async function checkTeamModeDependencies(config2) {
79402
79903
  }
79403
79904
  async function probeBinary(cmd, args) {
79404
79905
  try {
79405
- const proc = Bun.spawn({ cmd: [cmd, ...args], stdout: "pipe", stderr: "pipe" });
79906
+ const proc = spawn({ cmd: [cmd, ...args], stdout: "pipe", stderr: "pipe" });
79406
79907
  const code = await proc.exited;
79407
79908
  return code === 0;
79408
79909
  } catch {
@@ -79412,16 +79913,16 @@ async function probeBinary(cmd, args) {
79412
79913
 
79413
79914
  // src/features/team-mode/team-registry/paths.ts
79414
79915
  init_logger();
79415
- import { homedir as homedir12 } from "os";
79416
- import path12 from "path";
79916
+ import { homedir as homedir13 } from "os";
79917
+ import path13 from "path";
79417
79918
  function resolveBaseDir(config2) {
79418
- return config2.base_dir ?? path12.join(homedir12(), ".omo");
79919
+ return config2.base_dir ?? path13.join(homedir13(), ".omo");
79419
79920
  }
79420
79921
 
79421
79922
  // src/cli/doctor/checks/team-mode.ts
79422
79923
  init_shared();
79423
- import { readFileSync as readFileSync33, promises as fs12 } from "fs";
79424
- import path13 from "path";
79924
+ import { readFileSync as readFileSync35, promises as fs12 } from "fs";
79925
+ import path14 from "path";
79425
79926
  async function checkTeamMode() {
79426
79927
  const config2 = loadTeamModeConfig();
79427
79928
  const teamModeConfig = TeamModeConfigSchema.parse(config2.team_mode ?? {});
@@ -79432,8 +79933,8 @@ async function checkTeamMode() {
79432
79933
  const baseDir = resolveBaseDir(teamModeConfig);
79433
79934
  const [baseDirExists, teamCount, runtimeCount] = await Promise.all([
79434
79935
  pathExists(baseDir),
79435
- safeCount(path13.join(baseDir, "teams")),
79436
- safeCount(path13.join(baseDir, "runtime"))
79936
+ safeCount(path14.join(baseDir, "teams")),
79937
+ safeCount(path14.join(baseDir, "runtime"))
79437
79938
  ]);
79438
79939
  const baseDirMessage = baseDirExists ? `base dir: ok` : `base dir: missing (plugin init will create it on first use)`;
79439
79940
  return {
@@ -79445,13 +79946,13 @@ async function checkTeamMode() {
79445
79946
  };
79446
79947
  }
79447
79948
  function loadTeamModeConfig() {
79448
- const projectConfig = detectPluginConfigFile(path13.join(process.cwd(), ".opencode"));
79949
+ const projectConfig = detectPluginConfigFile(path14.join(process.cwd(), ".opencode"));
79449
79950
  const userConfig = detectPluginConfigFile(getOpenCodeConfigDir({ binary: "opencode" }));
79450
79951
  const configPath = projectConfig.format !== "none" ? projectConfig.path : userConfig.path;
79451
79952
  if (!configPath)
79452
79953
  return { team_mode: undefined };
79453
79954
  try {
79454
- return parseJsonc(readFileSync33(configPath, "utf-8"));
79955
+ return parseJsonc(readFileSync35(configPath, "utf-8"));
79455
79956
  } catch {
79456
79957
  return { team_mode: undefined };
79457
79958
  }
@@ -79854,11 +80355,11 @@ async function refreshModelCapabilities(options, deps = {}) {
79854
80355
 
79855
80356
  // src/features/mcp-oauth/storage.ts
79856
80357
  init_shared();
79857
- import { chmodSync as chmodSync2, existsSync as existsSync40, mkdirSync as mkdirSync12, readFileSync as readFileSync34, renameSync as renameSync4, unlinkSync as unlinkSync6, writeFileSync as writeFileSync10 } from "fs";
79858
- import { dirname as dirname16, join as join42 } from "path";
80358
+ import { chmodSync as chmodSync2, existsSync as existsSync42, mkdirSync as mkdirSync12, readFileSync as readFileSync36, renameSync as renameSync4, unlinkSync as unlinkSync6, writeFileSync as writeFileSync10 } from "fs";
80359
+ import { dirname as dirname17, join as join43 } from "path";
79859
80360
  var STORAGE_FILE_NAME = "mcp-oauth.json";
79860
80361
  function getMcpOauthStoragePath() {
79861
- return join42(getOpenCodeConfigDir({ binary: "opencode" }), STORAGE_FILE_NAME);
80362
+ return join43(getOpenCodeConfigDir({ binary: "opencode" }), STORAGE_FILE_NAME);
79862
80363
  }
79863
80364
  function normalizeHost(serverHost) {
79864
80365
  let host = serverHost.trim();
@@ -79895,11 +80396,11 @@ function buildKey(serverHost, resource) {
79895
80396
  }
79896
80397
  function readStore() {
79897
80398
  const filePath = getMcpOauthStoragePath();
79898
- if (!existsSync40(filePath)) {
80399
+ if (!existsSync42(filePath)) {
79899
80400
  return null;
79900
80401
  }
79901
80402
  try {
79902
- const content = readFileSync34(filePath, "utf-8");
80403
+ const content = readFileSync36(filePath, "utf-8");
79903
80404
  return JSON.parse(content);
79904
80405
  } catch {
79905
80406
  return null;
@@ -79908,8 +80409,8 @@ function readStore() {
79908
80409
  function writeStore(store2) {
79909
80410
  const filePath = getMcpOauthStoragePath();
79910
80411
  try {
79911
- const dir = dirname16(filePath);
79912
- if (!existsSync40(dir)) {
80412
+ const dir = dirname17(filePath);
80413
+ if (!existsSync42(dir)) {
79913
80414
  mkdirSync12(dir, { recursive: true });
79914
80415
  }
79915
80416
  const tempPath = `${filePath}.tmp.${Date.now()}`;
@@ -79946,7 +80447,7 @@ function deleteToken(serverHost, resource) {
79946
80447
  if (Object.keys(store2).length === 0) {
79947
80448
  try {
79948
80449
  const filePath = getMcpOauthStoragePath();
79949
- if (existsSync40(filePath)) {
80450
+ if (existsSync42(filePath)) {
79950
80451
  unlinkSync6(filePath);
79951
80452
  }
79952
80453
  return true;
@@ -80115,7 +80616,7 @@ async function getOrRegisterClient(options) {
80115
80616
  }
80116
80617
  }
80117
80618
  function parseRegistrationResponse(data) {
80118
- if (!isRecord7(data))
80619
+ if (!isRecord8(data))
80119
80620
  return null;
80120
80621
  const clientId = data.client_id;
80121
80622
  if (typeof clientId !== "string" || clientId.length === 0)
@@ -80126,7 +80627,7 @@ function parseRegistrationResponse(data) {
80126
80627
  }
80127
80628
  return { clientId };
80128
80629
  }
80129
- function isRecord7(value) {
80630
+ function isRecord8(value) {
80130
80631
  return typeof value === "object" && value !== null;
80131
80632
  }
80132
80633
 
@@ -80141,7 +80642,7 @@ async function findAvailablePort2(startPort = DEFAULT_PORT) {
80141
80642
  // src/features/mcp-oauth/oauth-authorization-flow.ts
80142
80643
  import { spawn as spawn2 } from "child_process";
80143
80644
  import { createHash as createHash2, randomBytes as randomBytes2 } from "crypto";
80144
- import { createServer } from "http";
80645
+ import { createServer as createServer2 } from "http";
80145
80646
  function generateCodeVerifier() {
80146
80647
  return randomBytes2(32).toString("base64url");
80147
80648
  }
@@ -80168,7 +80669,7 @@ var CALLBACK_TIMEOUT_MS = 5 * 60 * 1000;
80168
80669
  function startCallbackServer(port) {
80169
80670
  return new Promise((resolve6, reject) => {
80170
80671
  let timeoutId;
80171
- const server2 = createServer((request, response) => {
80672
+ const server2 = createServer2((request, response) => {
80172
80673
  clearTimeout(timeoutId);
80173
80674
  const requestUrl = new URL(request.url ?? "/", `http://localhost:${port}`);
80174
80675
  const code = requestUrl.searchParams.get("code");
@@ -80525,6 +81026,163 @@ function createMcpOAuthCommand() {
80525
81026
  return mcp;
80526
81027
  }
80527
81028
 
81029
+ // src/cli/boulder/boulder.ts
81030
+ import { existsSync as existsSync43 } from "fs";
81031
+
81032
+ // src/cli/boulder/formatter.ts
81033
+ var import_picocolors21 = __toESM(require_picocolors(), 1);
81034
+ function colorizeStatus(status2) {
81035
+ if (status2 === "active") {
81036
+ return import_picocolors21.default.cyan(status2);
81037
+ }
81038
+ if (status2 === "completed") {
81039
+ return import_picocolors21.default.green(status2);
81040
+ }
81041
+ if (status2 === "paused") {
81042
+ return import_picocolors21.default.yellow(status2);
81043
+ }
81044
+ return import_picocolors21.default.red(status2);
81045
+ }
81046
+ function formatCurrentTask(work) {
81047
+ if (!work.current_task) {
81048
+ return "-";
81049
+ }
81050
+ const elapsed = work.current_task.elapsed_human ? ` (${work.current_task.elapsed_human})` : "";
81051
+ return `${work.current_task.task_title}${elapsed}`;
81052
+ }
81053
+ function formatWorkBlock(work) {
81054
+ const elapsed = work.elapsed_human ?? "-";
81055
+ const progress = `${work.percentage}% (${work.completed_tasks}/${work.total_tasks})`;
81056
+ return [
81057
+ `plan: ${work.plan_name}`,
81058
+ `status: ${colorizeStatus(work.status)}`,
81059
+ `progress: ${progress}`,
81060
+ `elapsed: ${elapsed}`,
81061
+ `sessions: ${work.session_count}`,
81062
+ `current task: ${formatCurrentTask(work)}`
81063
+ ].join(`
81064
+ `);
81065
+ }
81066
+ function formatTextOutput(result) {
81067
+ const separator = import_picocolors21.default.dim("----------------------------------------");
81068
+ const blocks = result.works.map((work) => formatWorkBlock(work));
81069
+ return ["boulder progress", ...blocks].join(`
81070
+ ${separator}
81071
+ `);
81072
+ }
81073
+ function formatJsonOutput3(result) {
81074
+ return JSON.stringify(result, null, 2);
81075
+ }
81076
+ function formatNoBoulderMessage(isJson) {
81077
+ if (isJson) {
81078
+ return JSON.stringify({
81079
+ error: "No boulder state found."
81080
+ });
81081
+ }
81082
+ return "No boulder state found.";
81083
+ }
81084
+ function formatReadErrorMessage(isJson) {
81085
+ if (isJson) {
81086
+ return JSON.stringify({
81087
+ error: "Failed to read boulder state."
81088
+ });
81089
+ }
81090
+ return "Failed to read boulder state.";
81091
+ }
81092
+
81093
+ // src/cli/boulder/boulder.ts
81094
+ function formatDurationHuman(durationMs) {
81095
+ if (durationMs < 1000) {
81096
+ return `${durationMs}ms`;
81097
+ }
81098
+ const totalSeconds = Math.floor(durationMs / 1000);
81099
+ const seconds = totalSeconds % 60;
81100
+ const totalMinutes = Math.floor(totalSeconds / 60);
81101
+ const minutes = totalMinutes % 60;
81102
+ const hours = Math.floor(totalMinutes / 60);
81103
+ if (hours > 0) {
81104
+ return `${hours}h ${minutes}m ${seconds}s`;
81105
+ }
81106
+ if (minutes > 0) {
81107
+ return `${minutes}m ${seconds}s`;
81108
+ }
81109
+ return `${seconds}s`;
81110
+ }
81111
+ function getElapsedMs(work) {
81112
+ if (work.elapsed_ms !== undefined) {
81113
+ return work.elapsed_ms;
81114
+ }
81115
+ const startedAtMs = Date.parse(work.started_at);
81116
+ if (Number.isNaN(startedAtMs)) {
81117
+ return;
81118
+ }
81119
+ const endedAtMs = work.ended_at ? Date.parse(work.ended_at) : Date.now();
81120
+ if (Number.isNaN(endedAtMs)) {
81121
+ return;
81122
+ }
81123
+ return Math.max(0, endedAtMs - startedAtMs);
81124
+ }
81125
+ function buildCliWork(directory, work) {
81126
+ const planPath = resolveBoulderPlanPathForWork(directory, work);
81127
+ const progress = getPlanProgress(planPath);
81128
+ const elapsedMs = getElapsedMs(work);
81129
+ const currentTask = readCurrentTopLevelTask(planPath);
81130
+ const taskSession = currentTask ? work.task_sessions?.[currentTask.key] : undefined;
81131
+ let currentTaskElapsedHuman;
81132
+ if (taskSession?.elapsed_ms !== undefined) {
81133
+ currentTaskElapsedHuman = formatDurationHuman(taskSession.elapsed_ms);
81134
+ } else if (taskSession?.started_at) {
81135
+ const startedAtMs = Date.parse(taskSession.started_at);
81136
+ if (!Number.isNaN(startedAtMs)) {
81137
+ currentTaskElapsedHuman = formatDurationHuman(Math.max(0, Date.now() - startedAtMs));
81138
+ }
81139
+ }
81140
+ return {
81141
+ work_id: work.work_id,
81142
+ plan_name: work.plan_name,
81143
+ active_plan: work.active_plan,
81144
+ worktree_path: work.worktree_path,
81145
+ status: work.status ?? "active",
81146
+ started_at: work.started_at,
81147
+ ended_at: work.ended_at,
81148
+ elapsed_ms: elapsedMs,
81149
+ elapsed_human: elapsedMs !== undefined ? formatDurationHuman(elapsedMs) : undefined,
81150
+ total_tasks: progress.total,
81151
+ completed_tasks: progress.completed,
81152
+ remaining_tasks: Math.max(0, progress.total - progress.completed),
81153
+ percentage: progress.total > 0 ? Math.round(progress.completed / progress.total * 100) : 0,
81154
+ session_count: work.session_ids.length,
81155
+ current_task: currentTask ? {
81156
+ task_key: currentTask.key,
81157
+ task_title: currentTask.title,
81158
+ elapsed_human: currentTaskElapsedHuman
81159
+ } : undefined
81160
+ };
81161
+ }
81162
+ async function boulder(options) {
81163
+ const directory = options.directory ?? process.cwd();
81164
+ const boulderFilePath = getBoulderFilePath(directory);
81165
+ const state2 = readBoulderState(directory);
81166
+ if (!state2) {
81167
+ const message = existsSync43(boulderFilePath) ? formatReadErrorMessage(options.json) : formatNoBoulderMessage(options.json);
81168
+ process.stderr.write(`${message}
81169
+ `);
81170
+ return existsSync43(boulderFilePath) ? 2 : 1;
81171
+ }
81172
+ const works = getBoulderWorks(state2);
81173
+ const filteredWorks = options.workId ? works.filter((work) => work.work_id === options.workId) : works;
81174
+ if (filteredWorks.length === 0) {
81175
+ process.stderr.write(`${formatNoBoulderMessage(options.json)}
81176
+ `);
81177
+ return 1;
81178
+ }
81179
+ const cliWorks = filteredWorks.map((work) => buildCliWork(directory, work));
81180
+ const result = { works: cliWorks };
81181
+ const output = options.json ? formatJsonOutput3(result) : formatTextOutput(result);
81182
+ process.stdout.write(`${output}
81183
+ `);
81184
+ return 0;
81185
+ }
80528
81186
  // src/cli/cli-program.ts
80529
81187
  var VERSION2 = package_default.version;
80530
81188
  var program2 = new Command;
@@ -80651,6 +81309,14 @@ program2.command("refresh-model-capabilities").description("Refresh the cached m
80651
81309
  program2.command("version").description("Show version information").action(() => {
80652
81310
  console.log(`oh-my-opencode v${VERSION2}`);
80653
81311
  });
81312
+ program2.command("boulder").description("Show boulder progress, elapsed time, and per-task statistics").option("-d, --directory <path>", "Working directory").option("-w, --work-id <id>", "Filter to a specific work").option("--json", "Output as JSON").action(async (options) => {
81313
+ const exitCode = await boulder({
81314
+ directory: options.directory,
81315
+ workId: options.workId,
81316
+ json: options.json ?? false
81317
+ });
81318
+ process.exit(exitCode);
81319
+ });
80654
81320
  program2.addCommand(createMcpOAuthCommand());
80655
81321
  function runCli() {
80656
81322
  program2.parse();