evil-omo 3.17.0 → 3.17.4

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 (55) hide show
  1. package/README.ja.md +4 -0
  2. package/README.ko.md +4 -0
  3. package/README.ru.md +4 -0
  4. package/README.zh-cn.md +4 -0
  5. package/dist/cli/doctor/spawn-with-timeout.d.ts +8 -0
  6. package/dist/cli/index.js +1009 -643
  7. package/dist/cli/install-validators.d.ts +1 -0
  8. package/dist/cli/model-fallback-types.d.ts +1 -0
  9. package/dist/cli/provider-model-id-transform.d.ts +1 -1
  10. package/dist/cli/types.d.ts +3 -0
  11. package/dist/config/schema/agent-definitions.d.ts +3 -0
  12. package/dist/config/schema/evil-omo-config.d.ts +11 -2
  13. package/dist/create-tools.d.ts +2 -1
  14. package/dist/evil-omo.schema.json +24 -1
  15. package/dist/features/background-agent/index.d.ts +2 -0
  16. package/dist/features/background-agent/session-existence.d.ts +1 -1
  17. package/dist/features/background-agent/subagent-spawn-limits.d.ts +1 -1
  18. package/dist/features/background-agent/task-poller.d.ts +1 -0
  19. package/dist/features/background-agent/wait-for-task-session.d.ts +17 -0
  20. package/dist/features/builtin-commands/commands.d.ts +2 -1
  21. package/dist/features/claude-code-agent-loader/agent-definitions-loader.d.ts +3 -0
  22. package/dist/features/claude-code-agent-loader/index.d.ts +3 -0
  23. package/dist/features/claude-code-agent-loader/json-agent-loader.d.ts +2 -0
  24. package/dist/features/claude-code-agent-loader/loader.d.ts +2 -0
  25. package/dist/features/claude-code-agent-loader/opencode-config-agents-reader.d.ts +2 -0
  26. package/dist/features/claude-code-agent-loader/types.d.ts +9 -1
  27. package/dist/features/tool-metadata-store/index.d.ts +7 -0
  28. package/dist/features/tool-metadata-store/publish-tool-metadata.d.ts +9 -0
  29. package/dist/features/tool-metadata-store/recover-tool-metadata.d.ts +3 -0
  30. package/dist/features/tool-metadata-store/resolve-tool-call-id.d.ts +6 -0
  31. package/dist/features/tool-metadata-store/task-metadata-contract.d.ts +10 -0
  32. package/dist/hooks/atlas/system-reminder-templates.d.ts +2 -2
  33. package/dist/hooks/directory-agents-injector/hook.d.ts +7 -7
  34. package/dist/hooks/directory-readme-injector/hook.d.ts +7 -7
  35. package/dist/hooks/keyword-detector/ultrawork/planner.d.ts +1 -1
  36. package/dist/hooks/model-fallback/next-fallback.d.ts +8 -0
  37. package/dist/index.js +17457 -16688
  38. package/dist/openclaw/config.d.ts +1 -1
  39. package/dist/openclaw/dispatcher.d.ts +0 -1
  40. package/dist/openclaw/gateway-url-validation.d.ts +1 -0
  41. package/dist/shared/agent-tool-restrictions.d.ts +0 -5
  42. package/dist/shared/index.d.ts +3 -0
  43. package/dist/shared/opencode-provider-auth.d.ts +3 -0
  44. package/dist/shared/parse-tools-config.d.ts +6 -0
  45. package/dist/shared/resolve-agent-definition-paths.d.ts +1 -0
  46. package/dist/tools/call-omo-agent/agent-resolver.d.ts +17 -0
  47. package/dist/tools/call-omo-agent/constants.d.ts +1 -1
  48. package/dist/tools/delegate-task/delegated-model-config.d.ts +3 -0
  49. package/dist/tools/delegate-task/fallback-entry-resolution.d.ts +12 -0
  50. package/dist/tools/delegate-task/fallback-entry-settings.d.ts +7 -0
  51. package/dist/tools/delegate-task/subagent-discovery.d.ts +15 -0
  52. package/dist/tools/delegate-task/sync-task-fallback.d.ts +12 -0
  53. package/dist/tools/skill/constants.d.ts +1 -1
  54. package/package.json +12 -12
  55. package/dist/tools/delegate-task/resolve-call-id.d.ts +0 -2
package/dist/cli/index.js CHANGED
@@ -4915,6 +4915,42 @@ var init_command_executor = __esm(() => {
4915
4915
  });
4916
4916
 
4917
4917
  // src/shared/contains-path.ts
4918
+ import { existsSync, realpathSync } from "fs";
4919
+ import { basename, dirname, isAbsolute, join, normalize, relative, resolve } from "path";
4920
+ function findNearestExistingAncestor(resolvedPath) {
4921
+ let candidatePath = resolvedPath;
4922
+ while (!existsSync(candidatePath)) {
4923
+ const parentPath = dirname(candidatePath);
4924
+ if (parentPath === candidatePath) {
4925
+ return candidatePath;
4926
+ }
4927
+ candidatePath = parentPath;
4928
+ }
4929
+ return candidatePath;
4930
+ }
4931
+ function toCanonicalPath(pathToNormalize) {
4932
+ const resolvedPath = resolve(pathToNormalize);
4933
+ if (existsSync(resolvedPath)) {
4934
+ try {
4935
+ return normalize(realpathSync.native(resolvedPath));
4936
+ } catch {
4937
+ return normalize(resolvedPath);
4938
+ }
4939
+ }
4940
+ const nearestExistingAncestor = findNearestExistingAncestor(resolvedPath);
4941
+ const canonicalAncestor = existsSync(nearestExistingAncestor) ? realpathSync.native(nearestExistingAncestor) : nearestExistingAncestor;
4942
+ const relativePathFromAncestor = relative(nearestExistingAncestor, resolvedPath);
4943
+ return normalize(join(canonicalAncestor, relativePathFromAncestor || basename(resolvedPath)));
4944
+ }
4945
+ function containsPath(rootPath, candidatePath) {
4946
+ const canonicalRootPath = toCanonicalPath(rootPath);
4947
+ const canonicalCandidatePath = toCanonicalPath(candidatePath);
4948
+ const relativePath = relative(canonicalRootPath, canonicalCandidatePath);
4949
+ return relativePath === "" || !relativePath.startsWith("..") && !isAbsolute(relativePath);
4950
+ }
4951
+ function isWithinProject(candidatePath, projectRoot) {
4952
+ return containsPath(projectRoot, candidatePath);
4953
+ }
4918
4954
  var init_contains_path = () => {};
4919
4955
 
4920
4956
  // node_modules/jsonc-parser/lib/esm/impl/scanner.js
@@ -5782,8 +5818,8 @@ var init_main = __esm(() => {
5782
5818
  });
5783
5819
 
5784
5820
  // src/shared/jsonc-parser.ts
5785
- import { existsSync, readFileSync } from "fs";
5786
- import { join } from "path";
5821
+ import { existsSync as existsSync2, readFileSync } from "fs";
5822
+ import { join as join2 } from "path";
5787
5823
  function stripBom(content) {
5788
5824
  return content.charCodeAt(0) === 65279 ? content.slice(1) : content;
5789
5825
  }
@@ -5803,17 +5839,17 @@ function parseJsonc(content) {
5803
5839
  function detectConfigFile(basePath) {
5804
5840
  const jsoncPath = `${basePath}.jsonc`;
5805
5841
  const jsonPath = `${basePath}.json`;
5806
- if (existsSync(jsoncPath)) {
5842
+ if (existsSync2(jsoncPath)) {
5807
5843
  return { format: "jsonc", path: jsoncPath };
5808
5844
  }
5809
- if (existsSync(jsonPath)) {
5845
+ if (existsSync2(jsonPath)) {
5810
5846
  return { format: "json", path: jsonPath };
5811
5847
  }
5812
5848
  return { format: "none", path: jsonPath };
5813
5849
  }
5814
5850
  function detectPluginConfigFile(dir) {
5815
- const canonicalResult = detectConfigFile(join(dir, CONFIG_BASENAME));
5816
- const legacyResult = detectConfigFile(join(dir, LEGACY_CONFIG_BASENAME));
5851
+ const canonicalResult = detectConfigFile(join2(dir, CONFIG_BASENAME));
5852
+ const legacyResult = detectConfigFile(join2(dir, LEGACY_CONFIG_BASENAME));
5817
5853
  if (canonicalResult.format !== "none") {
5818
5854
  return {
5819
5855
  ...canonicalResult,
@@ -5823,7 +5859,7 @@ function detectPluginConfigFile(dir) {
5823
5859
  if (legacyResult.format !== "none") {
5824
5860
  return legacyResult;
5825
5861
  }
5826
- return { format: "none", path: join(dir, `${CONFIG_BASENAME}.json`) };
5862
+ return { format: "none", path: join2(dir, `${CONFIG_BASENAME}.json`) };
5827
5863
  }
5828
5864
  var init_jsonc_parser = __esm(() => {
5829
5865
  init_main();
@@ -5932,13 +5968,13 @@ var init_pattern_matcher = __esm(() => {
5932
5968
  regexCache = new Map;
5933
5969
  });
5934
5970
  // src/shared/file-utils.ts
5935
- import { lstatSync, realpathSync } from "fs";
5971
+ import { lstatSync, realpathSync as realpathSync2 } from "fs";
5936
5972
  function normalizeDarwinRealpath(filePath) {
5937
5973
  return filePath.startsWith("/private/var/") ? filePath.slice("/private".length) : filePath;
5938
5974
  }
5939
5975
  function resolveSymlink(filePath) {
5940
5976
  try {
5941
- return normalizeDarwinRealpath(realpathSync(filePath));
5977
+ return normalizeDarwinRealpath(realpathSync2(filePath));
5942
5978
  } catch {
5943
5979
  return filePath;
5944
5980
  }
@@ -5950,7 +5986,7 @@ var init_context_limit_resolver = () => {};
5950
5986
 
5951
5987
  // src/shared/normalize-sdk-response.ts
5952
5988
  function normalizeSDKResponse(response, fallback, options) {
5953
- if (response === null || response === undefined) {
5989
+ if (response == null) {
5954
5990
  return fallback;
5955
5991
  }
5956
5992
  if (Array.isArray(response)) {
@@ -5958,7 +5994,7 @@ function normalizeSDKResponse(response, fallback, options) {
5958
5994
  }
5959
5995
  if (typeof response === "object" && "data" in response) {
5960
5996
  const data = response.data;
5961
- if (data !== null && data !== undefined) {
5997
+ if (data != null) {
5962
5998
  return data;
5963
5999
  }
5964
6000
  if (options?.preferResponseOnMissingData === true) {
@@ -6050,20 +6086,26 @@ var init_agent_names = __esm(() => {
6050
6086
  omo: "sisyphus",
6051
6087
  OmO: "sisyphus",
6052
6088
  Sisyphus: "sisyphus",
6089
+ "Sisyphus (Ultraworker)": "sisyphus",
6053
6090
  sisyphus: "sisyphus",
6091
+ "Hephaestus (Deep Agent)": "hephaestus",
6054
6092
  "OmO-Plan": "prometheus",
6055
6093
  "omo-plan": "prometheus",
6056
6094
  "Planner-Sisyphus": "prometheus",
6057
6095
  "planner-sisyphus": "prometheus",
6058
6096
  "Prometheus - Plan Builder": "prometheus",
6097
+ "Prometheus (Plan Builder)": "prometheus",
6059
6098
  prometheus: "prometheus",
6060
6099
  "orchestrator-sisyphus": "atlas",
6061
6100
  Atlas: "atlas",
6101
+ "Atlas (Plan Executor)": "atlas",
6062
6102
  atlas: "atlas",
6063
6103
  "plan-consultant": "metis",
6064
6104
  "Metis - Plan Consultant": "metis",
6105
+ "Metis (Plan Consultant)": "metis",
6065
6106
  metis: "metis",
6066
6107
  "Momus - Plan Critic": "momus",
6108
+ "Momus (Plan Critic)": "momus",
6067
6109
  momus: "momus",
6068
6110
  "Sisyphus-Junior": "sisyphus-junior",
6069
6111
  "sisyphus-junior": "sisyphus-junior",
@@ -6161,7 +6203,7 @@ var init_model_versions = __esm(() => {
6161
6203
  var init_agent_category = () => {};
6162
6204
 
6163
6205
  // src/shared/write-file-atomically.ts
6164
- import { closeSync, fsyncSync, openSync, renameSync, writeFileSync } from "fs";
6206
+ import { closeSync, fsyncSync, openSync, renameSync, unlinkSync, writeFileSync } from "fs";
6165
6207
  function writeFileAtomically(filePath, content) {
6166
6208
  const tempPath = `${filePath}.tmp`;
6167
6209
  writeFileSync(tempPath, content, "utf-8");
@@ -6171,7 +6213,18 @@ function writeFileAtomically(filePath, content) {
6171
6213
  } finally {
6172
6214
  closeSync(tempFileDescriptor);
6173
6215
  }
6174
- renameSync(tempPath, filePath);
6216
+ try {
6217
+ renameSync(tempPath, filePath);
6218
+ } catch (error) {
6219
+ const isWindows = process.platform === "win32";
6220
+ const isPermissionError = error instanceof Error && (error.message.includes("EPERM") || error.message.includes("EACCES"));
6221
+ if (isWindows && isPermissionError) {
6222
+ unlinkSync(filePath);
6223
+ renameSync(tempPath, filePath);
6224
+ } else {
6225
+ throw error;
6226
+ }
6227
+ }
6175
6228
  }
6176
6229
  var init_write_file_atomically = () => {};
6177
6230
 
@@ -6319,20 +6372,28 @@ function migrateConfigFile(configPath, rawConfig) {
6319
6372
  }
6320
6373
  }
6321
6374
  if (needsWrite) {
6375
+ let finalConfig = JSON.parse(JSON.stringify(copy));
6376
+ const newContent = JSON.stringify(finalConfig, null, 2) + `
6377
+ `;
6378
+ let existingContent;
6379
+ try {
6380
+ existingContent = fs3.readFileSync(configPath, "utf-8");
6381
+ } catch {}
6382
+ const contentChanged = existingContent !== newContent;
6322
6383
  const timestamp2 = new Date().toISOString().replace(/[:.]/g, "-");
6323
6384
  const backupPath = `${configPath}.bak.${timestamp2}`;
6324
6385
  let backupSucceeded = false;
6325
- try {
6326
- fs3.copyFileSync(configPath, backupPath);
6327
- backupSucceeded = true;
6328
- } catch {
6329
- backupSucceeded = false;
6386
+ if (contentChanged) {
6387
+ try {
6388
+ fs3.copyFileSync(configPath, backupPath);
6389
+ backupSucceeded = true;
6390
+ } catch {
6391
+ backupSucceeded = false;
6392
+ }
6330
6393
  }
6331
6394
  let writeSucceeded = false;
6332
- let finalConfig = JSON.parse(JSON.stringify(copy));
6333
6395
  try {
6334
- writeFileAtomically(configPath, JSON.stringify(finalConfig, null, 2) + `
6335
- `);
6396
+ writeFileAtomically(configPath, newContent);
6336
6397
  writeSucceeded = true;
6337
6398
  } catch (err) {
6338
6399
  log(`Failed to write migrated config to ${configPath}:`, err);
@@ -6384,9 +6445,9 @@ var init_migration = __esm(() => {
6384
6445
  });
6385
6446
 
6386
6447
  // src/shared/opencode-config-dir.ts
6387
- import { existsSync as existsSync3, realpathSync as realpathSync2 } from "fs";
6448
+ import { existsSync as existsSync4, realpathSync as realpathSync3 } from "fs";
6388
6449
  import { homedir as homedir2 } from "os";
6389
- import { join as join4, resolve, win32 } from "path";
6450
+ import { join as join5, resolve as resolve2, win32 } from "path";
6390
6451
  function isDevBuild(version) {
6391
6452
  if (!version)
6392
6453
  return false;
@@ -6396,24 +6457,24 @@ function getTauriConfigDir(identifier) {
6396
6457
  const platform = process.platform;
6397
6458
  switch (platform) {
6398
6459
  case "darwin":
6399
- return join4(homedir2(), "Library", "Application Support", identifier);
6460
+ return join5(homedir2(), "Library", "Application Support", identifier);
6400
6461
  case "win32": {
6401
- const appData = process.env.APPDATA || join4(homedir2(), "AppData", "Roaming");
6462
+ const appData = process.env.APPDATA || join5(homedir2(), "AppData", "Roaming");
6402
6463
  return win32.join(appData, identifier);
6403
6464
  }
6404
6465
  case "linux":
6405
6466
  default: {
6406
- const xdgConfig = process.env.XDG_CONFIG_HOME || join4(homedir2(), ".config");
6407
- return join4(xdgConfig, identifier);
6467
+ const xdgConfig = process.env.XDG_CONFIG_HOME || join5(homedir2(), ".config");
6468
+ return join5(xdgConfig, identifier);
6408
6469
  }
6409
6470
  }
6410
6471
  }
6411
6472
  function resolveConfigPath(pathValue) {
6412
- const resolvedPath = resolve(pathValue);
6413
- if (!existsSync3(resolvedPath))
6473
+ const resolvedPath = resolve2(pathValue);
6474
+ if (!existsSync4(resolvedPath))
6414
6475
  return resolvedPath;
6415
6476
  try {
6416
- return realpathSync2(resolvedPath);
6477
+ return realpathSync3(resolvedPath);
6417
6478
  } catch {
6418
6479
  return resolvedPath;
6419
6480
  }
@@ -6423,8 +6484,8 @@ function getCliConfigDir() {
6423
6484
  if (envConfigDir) {
6424
6485
  return resolveConfigPath(envConfigDir);
6425
6486
  }
6426
- const xdgConfig = process.env.XDG_CONFIG_HOME || join4(homedir2(), ".config");
6427
- return resolveConfigPath(join4(xdgConfig, "opencode"));
6487
+ const xdgConfig = process.env.XDG_CONFIG_HOME || join5(homedir2(), ".config");
6488
+ return resolveConfigPath(join5(xdgConfig, "opencode"));
6428
6489
  }
6429
6490
  function getOpenCodeConfigDir(options) {
6430
6491
  const { binary: binary2, version, checkExisting = true } = options;
@@ -6436,9 +6497,9 @@ function getOpenCodeConfigDir(options) {
6436
6497
  const tauriDir = process.platform === "win32" ? win32.isAbsolute(tauriDirBase) ? win32.normalize(tauriDirBase) : win32.resolve(tauriDirBase) : resolveConfigPath(tauriDirBase);
6437
6498
  if (checkExisting) {
6438
6499
  const legacyDir = getCliConfigDir();
6439
- const legacyConfig = join4(legacyDir, "opencode.json");
6440
- const legacyConfigC = join4(legacyDir, "opencode.jsonc");
6441
- if (existsSync3(legacyConfig) || existsSync3(legacyConfigC)) {
6500
+ const legacyConfig = join5(legacyDir, "opencode.json");
6501
+ const legacyConfigC = join5(legacyDir, "opencode.jsonc");
6502
+ if (existsSync4(legacyConfig) || existsSync4(legacyConfigC)) {
6442
6503
  return legacyDir;
6443
6504
  }
6444
6505
  }
@@ -6448,10 +6509,10 @@ function getOpenCodeConfigPaths(options) {
6448
6509
  const configDir = getOpenCodeConfigDir(options);
6449
6510
  return {
6450
6511
  configDir,
6451
- configJson: join4(configDir, "opencode.json"),
6452
- configJsonc: join4(configDir, "opencode.jsonc"),
6453
- packageJson: join4(configDir, "package.json"),
6454
- omoConfig: join4(configDir, `${CONFIG_BASENAME}.json`)
6512
+ configJson: join5(configDir, "opencode.json"),
6513
+ configJsonc: join5(configDir, "opencode.jsonc"),
6514
+ packageJson: join5(configDir, "package.json"),
6515
+ omoConfig: join5(configDir, `${CONFIG_BASENAME}.json`)
6455
6516
  };
6456
6517
  }
6457
6518
  var TAURI_APP_IDENTIFIER = "ai.opencode.desktop", TAURI_APP_IDENTIFIER_DEV = "ai.opencode.desktop.dev";
@@ -6459,6 +6520,25 @@ var init_opencode_config_dir = __esm(() => {
6459
6520
  init_plugin_identity();
6460
6521
  });
6461
6522
 
6523
+ // src/shared/resolve-agent-definition-paths.ts
6524
+ import { homedir as homedir3 } from "os";
6525
+ import { isAbsolute as isAbsolute2, resolve as resolve3 } from "path";
6526
+ function resolveAgentDefinitionPaths(paths, baseDir, containmentDir) {
6527
+ return paths.flatMap((p) => {
6528
+ const expanded = p.startsWith("~/") ? p.replace(/^~\//, `${homedir3()}/`) : p;
6529
+ const resolved = isAbsolute2(expanded) ? expanded : resolve3(baseDir, expanded);
6530
+ if (containmentDir !== null && !isWithinProject(resolved, containmentDir)) {
6531
+ log(`agent_definitions path rejected (outside project boundary): ${p} -> ${resolved}`);
6532
+ return [];
6533
+ }
6534
+ return [resolved];
6535
+ });
6536
+ }
6537
+ var init_resolve_agent_definition_paths = __esm(() => {
6538
+ init_contains_path();
6539
+ init_logger();
6540
+ });
6541
+
6462
6542
  // src/shared/opencode-version.ts
6463
6543
  import { execSync } from "child_process";
6464
6544
  function parseVersion(version) {
@@ -6510,8 +6590,8 @@ var init_opencode_version = __esm(() => {
6510
6590
  });
6511
6591
 
6512
6592
  // src/shared/opencode-storage-detection.ts
6513
- import { existsSync as existsSync4 } from "fs";
6514
- import { join as join5 } from "path";
6593
+ import { existsSync as existsSync5 } from "fs";
6594
+ import { join as join6 } from "path";
6515
6595
  function isSqliteBackend() {
6516
6596
  if (cachedResult === true)
6517
6597
  return true;
@@ -6519,8 +6599,8 @@ function isSqliteBackend() {
6519
6599
  return false;
6520
6600
  const check = () => {
6521
6601
  const versionOk = isOpenCodeVersionAtLeast(OPENCODE_SQLITE_VERSION);
6522
- const dbPath = join5(getDataDir(), "opencode", "opencode.db");
6523
- return versionOk && existsSync4(dbPath);
6602
+ const dbPath = join6(getDataDir(), "opencode", "opencode.db");
6603
+ return versionOk && existsSync5(dbPath);
6524
6604
  };
6525
6605
  if (cachedResult === FALSE_PENDING_RETRY) {
6526
6606
  const result2 = check();
@@ -6587,11 +6667,94 @@ var init_zip_extractor = __esm(() => {
6587
6667
  });
6588
6668
 
6589
6669
  // src/shared/binary-downloader.ts
6670
+ import { chmodSync, existsSync as existsSync6, mkdirSync as mkdirSync3, unlinkSync as unlinkSync2 } from "fs";
6671
+ import * as path4 from "path";
6672
+ function getCachedBinaryPath(cacheDir, binaryName) {
6673
+ const binaryPath = path4.join(cacheDir, binaryName);
6674
+ return existsSync6(binaryPath) ? binaryPath : null;
6675
+ }
6590
6676
  var init_binary_downloader = __esm(() => {
6591
6677
  init_archive_entry_validator();
6592
6678
  init_zip_extractor();
6593
6679
  });
6594
6680
 
6681
+ // src/shared/agent-display-names.ts
6682
+ function stripInvisibleAgentCharacters(agentName) {
6683
+ return agentName.replace(INVISIBLE_AGENT_CHARACTERS_REGEX, "");
6684
+ }
6685
+ function stripAgentListSortPrefix(agentName) {
6686
+ return stripInvisibleAgentCharacters(agentName);
6687
+ }
6688
+ function getAgentRuntimeName(configKey) {
6689
+ const displayName = getAgentDisplayName(configKey);
6690
+ const prefix = AGENT_LIST_SORT_PREFIXES[configKey.toLowerCase()];
6691
+ return prefix ? `${prefix}${displayName}` : displayName;
6692
+ }
6693
+ function getAgentDisplayName(configKey) {
6694
+ const exactMatch = AGENT_DISPLAY_NAMES[configKey];
6695
+ if (exactMatch !== undefined)
6696
+ return exactMatch;
6697
+ const lowerKey = configKey.toLowerCase();
6698
+ for (const [k, v] of Object.entries(AGENT_DISPLAY_NAMES)) {
6699
+ if (k.toLowerCase() === lowerKey)
6700
+ return v;
6701
+ }
6702
+ return configKey;
6703
+ }
6704
+ function resolveKnownAgentConfigKey(agentName) {
6705
+ const lower = stripAgentListSortPrefix(agentName).trim().toLowerCase();
6706
+ const reversed = REVERSE_DISPLAY_NAMES[lower];
6707
+ if (reversed !== undefined)
6708
+ return reversed;
6709
+ const legacy = LEGACY_DISPLAY_NAMES[lower];
6710
+ if (legacy !== undefined)
6711
+ return legacy;
6712
+ if (AGENT_DISPLAY_NAMES[lower] !== undefined)
6713
+ return lower;
6714
+ return;
6715
+ }
6716
+ function getAgentConfigKey(agentName) {
6717
+ const lower = stripAgentListSortPrefix(agentName).trim().toLowerCase();
6718
+ return resolveKnownAgentConfigKey(agentName) ?? lower;
6719
+ }
6720
+ var AGENT_DISPLAY_NAMES, AGENT_LIST_SORT_PREFIXES, INVISIBLE_AGENT_CHARACTERS_REGEX, REVERSE_DISPLAY_NAMES, LEGACY_DISPLAY_NAMES;
6721
+ var init_agent_display_names = __esm(() => {
6722
+ AGENT_DISPLAY_NAMES = {
6723
+ sisyphus: "Sisyphus - Ultraworker",
6724
+ hephaestus: "Hephaestus - Deep Agent",
6725
+ prometheus: "Prometheus - Plan Builder",
6726
+ atlas: "Atlas - Plan Executor",
6727
+ "sisyphus-junior": "Sisyphus-Junior",
6728
+ metis: "Metis - Plan Consultant",
6729
+ momus: "Momus - Plan Critic",
6730
+ athena: "Athena - Council",
6731
+ "athena-junior": "Athena-Junior - Council",
6732
+ oracle: "oracle",
6733
+ librarian: "librarian",
6734
+ explore: "explore",
6735
+ "multimodal-looker": "multimodal-looker",
6736
+ "council-member": "council-member"
6737
+ };
6738
+ AGENT_LIST_SORT_PREFIXES = {
6739
+ sisyphus: "\u200B",
6740
+ hephaestus: "\u200B\u200B",
6741
+ prometheus: "\u200B\u200B\u200B",
6742
+ atlas: "\u200B\u200B\u200B\u200B"
6743
+ };
6744
+ INVISIBLE_AGENT_CHARACTERS_REGEX = /[\u200B\u200C\u200D\uFEFF]/g;
6745
+ REVERSE_DISPLAY_NAMES = Object.fromEntries(Object.entries(AGENT_DISPLAY_NAMES).map(([key, displayName]) => [displayName.toLowerCase(), key]));
6746
+ LEGACY_DISPLAY_NAMES = {
6747
+ "sisyphus (ultraworker)": "sisyphus",
6748
+ "hephaestus (deep agent)": "hephaestus",
6749
+ "prometheus (plan builder)": "prometheus",
6750
+ "atlas (plan executor)": "atlas",
6751
+ "metis (plan consultant)": "metis",
6752
+ "momus (plan critic)": "momus",
6753
+ "athena (council)": "athena",
6754
+ "athena-junior (council)": "athena-junior"
6755
+ };
6756
+ });
6757
+
6595
6758
  // src/shared/model-requirements.ts
6596
6759
  var AGENT_MODEL_REQUIREMENTS, CATEGORY_MODEL_REQUIREMENTS;
6597
6760
  var init_model_requirements = __esm(() => {
@@ -6599,11 +6762,11 @@ var init_model_requirements = __esm(() => {
6599
6762
  sisyphus: {
6600
6763
  fallbackChain: [
6601
6764
  {
6602
- providers: ["anthropic", "github-copilot", "opencode"],
6765
+ providers: ["anthropic", "github-copilot", "opencode", "vercel"],
6603
6766
  model: "claude-opus-4-6",
6604
6767
  variant: "max"
6605
6768
  },
6606
- { providers: ["opencode-go"], model: "kimi-k2.5" },
6769
+ { providers: ["opencode-go", "vercel"], model: "kimi-k2.5" },
6607
6770
  { providers: ["kimi-for-coding"], model: "k2p5" },
6608
6771
  {
6609
6772
  providers: [
@@ -6612,12 +6775,13 @@ var init_model_requirements = __esm(() => {
6612
6775
  "moonshotai-cn",
6613
6776
  "firmware",
6614
6777
  "ollama-cloud",
6615
- "aihubmix"
6778
+ "aihubmix",
6779
+ "vercel"
6616
6780
  ],
6617
6781
  model: "kimi-k2.5"
6618
6782
  },
6619
- { providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.4", variant: "medium" },
6620
- { providers: ["zai-coding-plan", "opencode"], model: "glm-5" },
6783
+ { providers: ["openai", "github-copilot", "opencode", "vercel"], model: "gpt-5.4", variant: "medium" },
6784
+ { providers: ["zai-coding-plan", "opencode", "vercel"], model: "glm-5" },
6621
6785
  { providers: ["opencode"], model: "big-pickle" }
6622
6786
  ],
6623
6787
  requiresAnyModel: true
@@ -6625,73 +6789,73 @@ var init_model_requirements = __esm(() => {
6625
6789
  hephaestus: {
6626
6790
  fallbackChain: [
6627
6791
  {
6628
- providers: ["openai", "github-copilot", "venice", "opencode"],
6792
+ providers: ["openai", "github-copilot", "venice", "opencode", "vercel"],
6629
6793
  model: "gpt-5.4",
6630
6794
  variant: "medium"
6631
6795
  }
6632
6796
  ],
6633
- requiresProvider: ["openai", "github-copilot", "venice", "opencode"]
6797
+ requiresProvider: ["openai", "github-copilot", "venice", "opencode", "vercel"]
6634
6798
  },
6635
6799
  oracle: {
6636
6800
  fallbackChain: [
6637
6801
  {
6638
- providers: ["openai", "github-copilot", "opencode"],
6802
+ providers: ["openai", "github-copilot", "opencode", "vercel"],
6639
6803
  model: "gpt-5.4",
6640
6804
  variant: "high"
6641
6805
  },
6642
6806
  {
6643
- providers: ["google", "github-copilot", "opencode"],
6807
+ providers: ["google", "github-copilot", "opencode", "vercel"],
6644
6808
  model: "gemini-3.1-pro",
6645
6809
  variant: "high"
6646
6810
  },
6647
6811
  {
6648
- providers: ["anthropic", "github-copilot", "opencode"],
6812
+ providers: ["anthropic", "github-copilot", "opencode", "vercel"],
6649
6813
  model: "claude-opus-4-6",
6650
6814
  variant: "max"
6651
6815
  },
6652
- { providers: ["opencode-go"], model: "glm-5" }
6816
+ { providers: ["opencode-go", "vercel"], model: "glm-5" }
6653
6817
  ]
6654
6818
  },
6655
6819
  librarian: {
6656
6820
  fallbackChain: [
6657
- { providers: ["opencode-go"], model: "minimax-m2.7" },
6658
- { providers: ["opencode"], model: "minimax-m2.7-highspeed" },
6659
- { providers: ["anthropic", "opencode"], model: "claude-haiku-4-5" },
6660
- { providers: ["opencode"], model: "gpt-5-nano" }
6821
+ { providers: ["opencode-go", "vercel"], model: "minimax-m2.7" },
6822
+ { providers: ["opencode", "vercel"], model: "minimax-m2.7-highspeed" },
6823
+ { providers: ["anthropic", "opencode", "vercel"], model: "claude-haiku-4-5" },
6824
+ { providers: ["opencode", "vercel"], model: "gpt-5-nano" }
6661
6825
  ]
6662
6826
  },
6663
6827
  explore: {
6664
6828
  fallbackChain: [
6665
- { providers: ["github-copilot", "xai"], model: "grok-code-fast-1" },
6666
- { providers: ["opencode-go"], model: "minimax-m2.7-highspeed" },
6667
- { providers: ["opencode"], model: "minimax-m2.7" },
6668
- { providers: ["anthropic", "opencode"], model: "claude-haiku-4-5" },
6669
- { providers: ["opencode"], model: "gpt-5-nano" }
6829
+ { providers: ["github-copilot", "xai", "vercel"], model: "grok-code-fast-1" },
6830
+ { providers: ["opencode-go", "vercel"], model: "minimax-m2.7-highspeed" },
6831
+ { providers: ["opencode", "vercel"], model: "minimax-m2.7" },
6832
+ { providers: ["anthropic", "opencode", "vercel"], model: "claude-haiku-4-5" },
6833
+ { providers: ["opencode", "vercel"], model: "gpt-5-nano" }
6670
6834
  ]
6671
6835
  },
6672
6836
  "multimodal-looker": {
6673
6837
  fallbackChain: [
6674
- { providers: ["openai", "opencode"], model: "gpt-5.4", variant: "medium" },
6675
- { providers: ["opencode-go"], model: "kimi-k2.5" },
6676
- { providers: ["zai-coding-plan"], model: "glm-4.6v" },
6677
- { providers: ["openai", "github-copilot", "opencode"], model: "gpt-5-nano" }
6838
+ { providers: ["openai", "opencode", "vercel"], model: "gpt-5.4", variant: "medium" },
6839
+ { providers: ["opencode-go", "vercel"], model: "kimi-k2.5" },
6840
+ { providers: ["zai-coding-plan", "vercel"], model: "glm-4.6v" },
6841
+ { providers: ["openai", "github-copilot", "opencode", "vercel"], model: "gpt-5-nano" }
6678
6842
  ]
6679
6843
  },
6680
6844
  prometheus: {
6681
6845
  fallbackChain: [
6682
6846
  {
6683
- providers: ["anthropic", "github-copilot", "opencode"],
6847
+ providers: ["anthropic", "github-copilot", "opencode", "vercel"],
6684
6848
  model: "claude-opus-4-6",
6685
6849
  variant: "max"
6686
6850
  },
6687
6851
  {
6688
- providers: ["openai", "github-copilot", "opencode"],
6852
+ providers: ["openai", "github-copilot", "opencode", "vercel"],
6689
6853
  model: "gpt-5.4",
6690
6854
  variant: "high"
6691
6855
  },
6692
- { providers: ["opencode-go"], model: "glm-5" },
6856
+ { providers: ["opencode-go", "vercel"], model: "glm-5" },
6693
6857
  {
6694
- providers: ["google", "github-copilot", "opencode"],
6858
+ providers: ["google", "github-copilot", "opencode", "vercel"],
6695
6859
  model: "gemini-3.1-pro"
6696
6860
  }
6697
6861
  ]
@@ -6699,61 +6863,61 @@ var init_model_requirements = __esm(() => {
6699
6863
  metis: {
6700
6864
  fallbackChain: [
6701
6865
  {
6702
- providers: ["anthropic", "github-copilot", "opencode"],
6866
+ providers: ["anthropic", "github-copilot", "opencode", "vercel"],
6703
6867
  model: "claude-opus-4-6",
6704
6868
  variant: "max"
6705
6869
  },
6706
6870
  {
6707
- providers: ["openai", "github-copilot", "opencode"],
6871
+ providers: ["openai", "github-copilot", "opencode", "vercel"],
6708
6872
  model: "gpt-5.4",
6709
6873
  variant: "high"
6710
6874
  },
6711
- { providers: ["opencode-go"], model: "glm-5" },
6875
+ { providers: ["opencode-go", "vercel"], model: "glm-5" },
6712
6876
  { providers: ["kimi-for-coding"], model: "k2p5" }
6713
6877
  ]
6714
6878
  },
6715
6879
  momus: {
6716
6880
  fallbackChain: [
6717
6881
  {
6718
- providers: ["openai", "github-copilot", "opencode"],
6882
+ providers: ["openai", "github-copilot", "opencode", "vercel"],
6719
6883
  model: "gpt-5.4",
6720
6884
  variant: "xhigh"
6721
6885
  },
6722
6886
  {
6723
- providers: ["anthropic", "github-copilot", "opencode"],
6887
+ providers: ["anthropic", "github-copilot", "opencode", "vercel"],
6724
6888
  model: "claude-opus-4-6",
6725
6889
  variant: "max"
6726
6890
  },
6727
6891
  {
6728
- providers: ["google", "github-copilot", "opencode"],
6892
+ providers: ["google", "github-copilot", "opencode", "vercel"],
6729
6893
  model: "gemini-3.1-pro",
6730
6894
  variant: "high"
6731
6895
  },
6732
- { providers: ["opencode-go"], model: "glm-5" }
6896
+ { providers: ["opencode-go", "vercel"], model: "glm-5" }
6733
6897
  ]
6734
6898
  },
6735
6899
  atlas: {
6736
6900
  fallbackChain: [
6737
- { providers: ["anthropic", "github-copilot", "opencode"], model: "claude-sonnet-4-6" },
6738
- { providers: ["opencode-go"], model: "kimi-k2.5" },
6901
+ { providers: ["anthropic", "github-copilot", "opencode", "vercel"], model: "claude-sonnet-4-6" },
6902
+ { providers: ["opencode-go", "vercel"], model: "kimi-k2.5" },
6739
6903
  {
6740
- providers: ["openai", "github-copilot", "opencode"],
6904
+ providers: ["openai", "github-copilot", "opencode", "vercel"],
6741
6905
  model: "gpt-5.4",
6742
6906
  variant: "medium"
6743
6907
  },
6744
- { providers: ["opencode-go"], model: "minimax-m2.7" }
6908
+ { providers: ["opencode-go", "vercel"], model: "minimax-m2.7" }
6745
6909
  ]
6746
6910
  },
6747
6911
  "sisyphus-junior": {
6748
6912
  fallbackChain: [
6749
- { providers: ["anthropic", "github-copilot", "opencode"], model: "claude-sonnet-4-6" },
6750
- { providers: ["opencode-go"], model: "kimi-k2.5" },
6913
+ { providers: ["anthropic", "github-copilot", "opencode", "vercel"], model: "claude-sonnet-4-6" },
6914
+ { providers: ["opencode-go", "vercel"], model: "kimi-k2.5" },
6751
6915
  {
6752
- providers: ["openai", "github-copilot", "opencode"],
6916
+ providers: ["openai", "github-copilot", "opencode", "vercel"],
6753
6917
  model: "gpt-5.4",
6754
6918
  variant: "medium"
6755
6919
  },
6756
- { providers: ["opencode-go"], model: "minimax-m2.7" },
6920
+ { providers: ["opencode-go", "vercel"], model: "minimax-m2.7" },
6757
6921
  { providers: ["opencode"], model: "big-pickle" }
6758
6922
  ]
6759
6923
  }
@@ -6762,54 +6926,54 @@ var init_model_requirements = __esm(() => {
6762
6926
  "visual-engineering": {
6763
6927
  fallbackChain: [
6764
6928
  {
6765
- providers: ["google", "github-copilot", "opencode"],
6929
+ providers: ["google", "github-copilot", "opencode", "vercel"],
6766
6930
  model: "gemini-3.1-pro",
6767
6931
  variant: "high"
6768
6932
  },
6769
- { providers: ["zai-coding-plan", "opencode"], model: "glm-5" },
6933
+ { providers: ["zai-coding-plan", "opencode", "vercel"], model: "glm-5" },
6770
6934
  {
6771
- providers: ["anthropic", "github-copilot", "opencode"],
6935
+ providers: ["anthropic", "github-copilot", "opencode", "vercel"],
6772
6936
  model: "claude-opus-4-6",
6773
6937
  variant: "max"
6774
6938
  },
6775
- { providers: ["opencode-go"], model: "glm-5" },
6939
+ { providers: ["opencode-go", "vercel"], model: "glm-5" },
6776
6940
  { providers: ["kimi-for-coding"], model: "k2p5" }
6777
6941
  ]
6778
6942
  },
6779
6943
  ultrabrain: {
6780
6944
  fallbackChain: [
6781
6945
  {
6782
- providers: ["openai", "opencode"],
6946
+ providers: ["openai", "opencode", "vercel"],
6783
6947
  model: "gpt-5.4",
6784
6948
  variant: "xhigh"
6785
6949
  },
6786
6950
  {
6787
- providers: ["google", "github-copilot", "opencode"],
6951
+ providers: ["google", "github-copilot", "opencode", "vercel"],
6788
6952
  model: "gemini-3.1-pro",
6789
6953
  variant: "high"
6790
6954
  },
6791
6955
  {
6792
- providers: ["anthropic", "github-copilot", "opencode"],
6956
+ providers: ["anthropic", "github-copilot", "opencode", "vercel"],
6793
6957
  model: "claude-opus-4-6",
6794
6958
  variant: "max"
6795
6959
  },
6796
- { providers: ["opencode-go"], model: "glm-5" }
6960
+ { providers: ["opencode-go", "vercel"], model: "glm-5" }
6797
6961
  ]
6798
6962
  },
6799
6963
  deep: {
6800
6964
  fallbackChain: [
6801
6965
  {
6802
- providers: ["openai", "github-copilot", "venice", "opencode"],
6966
+ providers: ["openai", "github-copilot", "venice", "opencode", "vercel"],
6803
6967
  model: "gpt-5.4",
6804
6968
  variant: "medium"
6805
6969
  },
6806
6970
  {
6807
- providers: ["anthropic", "github-copilot", "opencode"],
6971
+ providers: ["anthropic", "github-copilot", "opencode", "vercel"],
6808
6972
  model: "claude-opus-4-6",
6809
6973
  variant: "max"
6810
6974
  },
6811
6975
  {
6812
- providers: ["google", "github-copilot", "opencode"],
6976
+ providers: ["google", "github-copilot", "opencode", "vercel"],
6813
6977
  model: "gemini-3.1-pro",
6814
6978
  variant: "high"
6815
6979
  }
@@ -6818,72 +6982,72 @@ var init_model_requirements = __esm(() => {
6818
6982
  artistry: {
6819
6983
  fallbackChain: [
6820
6984
  {
6821
- providers: ["google", "github-copilot", "opencode"],
6985
+ providers: ["google", "github-copilot", "opencode", "vercel"],
6822
6986
  model: "gemini-3.1-pro",
6823
6987
  variant: "high"
6824
6988
  },
6825
6989
  {
6826
- providers: ["anthropic", "github-copilot", "opencode"],
6990
+ providers: ["anthropic", "github-copilot", "opencode", "vercel"],
6827
6991
  model: "claude-opus-4-6",
6828
6992
  variant: "max"
6829
6993
  },
6830
- { providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.4" }
6994
+ { providers: ["openai", "github-copilot", "opencode", "vercel"], model: "gpt-5.4" }
6831
6995
  ],
6832
6996
  requiresModel: "gemini-3.1-pro"
6833
6997
  },
6834
6998
  quick: {
6835
6999
  fallbackChain: [
6836
7000
  {
6837
- providers: ["openai", "github-copilot", "opencode"],
7001
+ providers: ["openai", "github-copilot", "opencode", "vercel"],
6838
7002
  model: "gpt-5.4-mini"
6839
7003
  },
6840
7004
  {
6841
- providers: ["anthropic", "github-copilot", "opencode"],
7005
+ providers: ["anthropic", "github-copilot", "opencode", "vercel"],
6842
7006
  model: "claude-haiku-4-5"
6843
7007
  },
6844
7008
  {
6845
- providers: ["google", "github-copilot", "opencode"],
7009
+ providers: ["google", "github-copilot", "opencode", "vercel"],
6846
7010
  model: "gemini-3-flash"
6847
7011
  },
6848
- { providers: ["opencode-go"], model: "minimax-m2.7" },
6849
- { providers: ["opencode"], model: "gpt-5-nano" }
7012
+ { providers: ["opencode-go", "vercel"], model: "minimax-m2.7" },
7013
+ { providers: ["opencode", "vercel"], model: "gpt-5-nano" }
6850
7014
  ]
6851
7015
  },
6852
7016
  "unspecified-low": {
6853
7017
  fallbackChain: [
6854
7018
  {
6855
- providers: ["anthropic", "github-copilot", "opencode"],
7019
+ providers: ["anthropic", "github-copilot", "opencode", "vercel"],
6856
7020
  model: "claude-sonnet-4-6"
6857
7021
  },
6858
7022
  {
6859
- providers: ["openai", "opencode"],
7023
+ providers: ["openai", "opencode", "vercel"],
6860
7024
  model: "gpt-5.3-codex",
6861
7025
  variant: "medium"
6862
7026
  },
6863
- { providers: ["opencode-go"], model: "kimi-k2.5" },
7027
+ { providers: ["opencode-go", "vercel"], model: "kimi-k2.5" },
6864
7028
  {
6865
- providers: ["google", "github-copilot", "opencode"],
7029
+ providers: ["google", "github-copilot", "opencode", "vercel"],
6866
7030
  model: "gemini-3-flash"
6867
7031
  },
6868
- { providers: ["opencode-go"], model: "minimax-m2.7" }
7032
+ { providers: ["opencode-go", "vercel"], model: "minimax-m2.7" }
6869
7033
  ]
6870
7034
  },
6871
7035
  "unspecified-high": {
6872
7036
  fallbackChain: [
6873
7037
  {
6874
- providers: ["anthropic", "github-copilot", "opencode"],
7038
+ providers: ["anthropic", "github-copilot", "opencode", "vercel"],
6875
7039
  model: "claude-opus-4-6",
6876
7040
  variant: "max"
6877
7041
  },
6878
7042
  {
6879
- providers: ["openai", "github-copilot", "opencode"],
7043
+ providers: ["openai", "github-copilot", "opencode", "vercel"],
6880
7044
  model: "gpt-5.4",
6881
7045
  variant: "high"
6882
7046
  },
6883
- { providers: ["zai-coding-plan", "opencode"], model: "glm-5" },
7047
+ { providers: ["zai-coding-plan", "opencode", "vercel"], model: "glm-5" },
6884
7048
  { providers: ["kimi-for-coding"], model: "k2p5" },
6885
- { providers: ["opencode-go"], model: "glm-5" },
6886
- { providers: ["opencode"], model: "kimi-k2.5" },
7049
+ { providers: ["opencode-go", "vercel"], model: "glm-5" },
7050
+ { providers: ["opencode", "vercel"], model: "kimi-k2.5" },
6887
7051
  {
6888
7052
  providers: [
6889
7053
  "opencode",
@@ -6891,7 +7055,8 @@ var init_model_requirements = __esm(() => {
6891
7055
  "moonshotai-cn",
6892
7056
  "firmware",
6893
7057
  "ollama-cloud",
6894
- "aihubmix"
7058
+ "aihubmix",
7059
+ "vercel"
6895
7060
  ],
6896
7061
  model: "kimi-k2.5"
6897
7062
  }
@@ -6900,15 +7065,15 @@ var init_model_requirements = __esm(() => {
6900
7065
  writing: {
6901
7066
  fallbackChain: [
6902
7067
  {
6903
- providers: ["google", "github-copilot", "opencode"],
7068
+ providers: ["google", "github-copilot", "opencode", "vercel"],
6904
7069
  model: "gemini-3-flash"
6905
7070
  },
6906
- { providers: ["opencode-go"], model: "kimi-k2.5" },
7071
+ { providers: ["opencode-go", "vercel"], model: "kimi-k2.5" },
6907
7072
  {
6908
- providers: ["anthropic", "github-copilot", "opencode"],
7073
+ providers: ["anthropic", "github-copilot", "opencode", "vercel"],
6909
7074
  model: "claude-sonnet-4-6"
6910
7075
  },
6911
- { providers: ["opencode-go"], model: "minimax-m2.7" }
7076
+ { providers: ["opencode-go", "vercel"], model: "minimax-m2.7" }
6912
7077
  ]
6913
7078
  }
6914
7079
  };
@@ -6916,6 +7081,7 @@ var init_model_requirements = __esm(() => {
6916
7081
 
6917
7082
  // src/shared/agent-variant.ts
6918
7083
  var init_agent_variant = __esm(() => {
7084
+ init_agent_display_names();
6919
7085
  init_model_requirements();
6920
7086
  });
6921
7087
 
@@ -6934,6 +7100,9 @@ function detectShellType() {
6934
7100
  }
6935
7101
  return "unix";
6936
7102
  }
7103
+ if (process.env.MSYSTEM) {
7104
+ return "unix";
7105
+ }
6937
7106
  if (process.env.PSModulePath) {
6938
7107
  return "powershell";
6939
7108
  }
@@ -6944,7 +7113,9 @@ function detectShellType() {
6944
7113
  var init_system_directive = () => {};
6945
7114
 
6946
7115
  // src/shared/agent-tool-restrictions.ts
6947
- var init_agent_tool_restrictions = () => {};
7116
+ var init_agent_tool_restrictions = __esm(() => {
7117
+ init_agent_display_names();
7118
+ });
6948
7119
 
6949
7120
  // src/shared/model-normalization.ts
6950
7121
  function normalizeModelID(modelID) {
@@ -6952,20 +7123,20 @@ function normalizeModelID(modelID) {
6952
7123
  }
6953
7124
 
6954
7125
  // src/shared/json-file-cache-store.ts
6955
- import { existsSync as existsSync5, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
6956
- import { join as join6 } from "path";
7126
+ import { existsSync as existsSync7, mkdirSync as mkdirSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "fs";
7127
+ import { join as join8 } from "path";
6957
7128
  function toLogLabel(cacheLabel) {
6958
7129
  return cacheLabel.toLowerCase();
6959
7130
  }
6960
7131
  function createJsonFileCacheStore(options) {
6961
7132
  let memoryValue;
6962
7133
  function getCacheFilePath() {
6963
- return join6(options.getCacheDir(), options.filename);
7134
+ return join8(options.getCacheDir(), options.filename);
6964
7135
  }
6965
7136
  function ensureCacheDir() {
6966
7137
  const cacheDir = options.getCacheDir();
6967
- if (!existsSync5(cacheDir)) {
6968
- mkdirSync3(cacheDir, { recursive: true });
7138
+ if (!existsSync7(cacheDir)) {
7139
+ mkdirSync4(cacheDir, { recursive: true });
6969
7140
  }
6970
7141
  }
6971
7142
  function read() {
@@ -6973,13 +7144,13 @@ function createJsonFileCacheStore(options) {
6973
7144
  return memoryValue;
6974
7145
  }
6975
7146
  const cacheFile = getCacheFilePath();
6976
- if (!existsSync5(cacheFile)) {
7147
+ if (!existsSync7(cacheFile)) {
6977
7148
  memoryValue = null;
6978
7149
  log(`[${options.logPrefix}] ${options.cacheLabel} file not found`, { cacheFile });
6979
7150
  return null;
6980
7151
  }
6981
7152
  try {
6982
- const content = readFileSync3(cacheFile, "utf-8");
7153
+ const content = readFileSync4(cacheFile, "utf-8");
6983
7154
  const value = JSON.parse(content);
6984
7155
  memoryValue = value;
6985
7156
  log(`[${options.logPrefix}] Read ${toLogLabel(options.cacheLabel)}`, options.describe(value));
@@ -6993,7 +7164,7 @@ function createJsonFileCacheStore(options) {
6993
7164
  }
6994
7165
  }
6995
7166
  function has() {
6996
- return existsSync5(getCacheFilePath());
7167
+ return existsSync7(getCacheFilePath());
6997
7168
  }
6998
7169
  function write(value) {
6999
7170
  ensureCacheDir();
@@ -7162,14 +7333,14 @@ var init_connected_providers_cache = __esm(() => {
7162
7333
  });
7163
7334
 
7164
7335
  // src/shared/model-availability.ts
7165
- import { existsSync as existsSync6, readFileSync as readFileSync4 } from "fs";
7166
- import { join as join7 } from "path";
7336
+ import { existsSync as existsSync8, readFileSync as readFileSync5 } from "fs";
7337
+ import { join as join9 } from "path";
7167
7338
  function isModelCacheAvailable() {
7168
7339
  if (hasProviderModelsCache()) {
7169
7340
  return true;
7170
7341
  }
7171
- const cacheFile = join7(getOpenCodeCacheDir(), "models.json");
7172
- return existsSync6(cacheFile);
7342
+ const cacheFile = join9(getOpenCodeCacheDir(), "models.json");
7343
+ return existsSync8(cacheFile);
7173
7344
  }
7174
7345
  var init_model_availability = __esm(() => {
7175
7346
  init_logger();
@@ -7178,21 +7349,14 @@ var init_model_availability = __esm(() => {
7178
7349
  });
7179
7350
 
7180
7351
  // src/shared/provider-model-id-transform.ts
7181
- function transformModelForProvider(provider, model) {
7182
- if (provider === "github-copilot") {
7183
- return model.replace("claude-opus-4-6", "claude-opus-4.6").replace("claude-sonnet-4-6", "claude-sonnet-4.6").replace("claude-sonnet-4-5", "claude-sonnet-4.5").replace("claude-haiku-4-5", "claude-haiku-4.5").replace("claude-sonnet-4", "claude-sonnet-4").replace(/gemini-3\.1-pro(?!-)/g, "gemini-3.1-pro-preview").replace(/gemini-3-flash(?!-)/g, "gemini-3-flash-preview");
7184
- }
7185
- if (provider === "google") {
7186
- return model.replace(/gemini-3\.1-pro(?!-)/g, "gemini-3.1-pro-preview").replace(/gemini-3-flash(?!-)/g, "gemini-3-flash-preview");
7187
- }
7188
- return model;
7189
- }
7352
+ var init_provider_model_id_transform = () => {};
7190
7353
 
7191
7354
  // src/shared/model-resolution-pipeline.ts
7192
7355
  var init_model_resolution_pipeline = __esm(() => {
7193
7356
  init_logger();
7194
7357
  init_connected_providers_cache();
7195
7358
  init_model_availability();
7359
+ init_provider_model_id_transform();
7196
7360
  });
7197
7361
 
7198
7362
  // src/shared/known-variants.ts
@@ -48465,19 +48629,19 @@ var init_constants = __esm(() => {
48465
48629
  });
48466
48630
 
48467
48631
  // src/shared/opencode-storage-paths.ts
48468
- import { join as join8 } from "path";
48632
+ import { join as join10 } from "path";
48469
48633
  var OPENCODE_STORAGE, MESSAGE_STORAGE, PART_STORAGE, SESSION_STORAGE;
48470
48634
  var init_opencode_storage_paths = __esm(() => {
48471
48635
  init_data_path();
48472
48636
  OPENCODE_STORAGE = getOpenCodeStorageDir();
48473
- MESSAGE_STORAGE = join8(OPENCODE_STORAGE, "message");
48474
- PART_STORAGE = join8(OPENCODE_STORAGE, "part");
48475
- SESSION_STORAGE = join8(OPENCODE_STORAGE, "session");
48637
+ MESSAGE_STORAGE = join10(OPENCODE_STORAGE, "message");
48638
+ PART_STORAGE = join10(OPENCODE_STORAGE, "part");
48639
+ SESSION_STORAGE = join10(OPENCODE_STORAGE, "session");
48476
48640
  });
48477
48641
 
48478
48642
  // src/shared/compaction-marker.ts
48479
- import { existsSync as existsSync7, readdirSync, readFileSync as readFileSync5 } from "fs";
48480
- import { join as join9 } from "path";
48643
+ import { existsSync as existsSync9, readdirSync, readFileSync as readFileSync6 } from "fs";
48644
+ import { join as join11 } from "path";
48481
48645
  function isCompactionPart(part) {
48482
48646
  return typeof part === "object" && part !== null && part.type === "compaction";
48483
48647
  }
@@ -48491,20 +48655,20 @@ function isCompactionMessage(message) {
48491
48655
  return isCompactionAgent(message.info?.agent ?? message.agent) || hasCompactionPart(message.parts);
48492
48656
  }
48493
48657
  function getCompactionPartStorageDir(messageID) {
48494
- return join9(PART_STORAGE, messageID);
48658
+ return join11(PART_STORAGE, messageID);
48495
48659
  }
48496
48660
  function hasCompactionPartInStorage(messageID) {
48497
48661
  if (!messageID) {
48498
48662
  return false;
48499
48663
  }
48500
48664
  const partDir = getCompactionPartStorageDir(messageID);
48501
- if (!existsSync7(partDir)) {
48665
+ if (!existsSync9(partDir)) {
48502
48666
  return false;
48503
48667
  }
48504
48668
  try {
48505
48669
  return readdirSync(partDir).filter((fileName) => fileName.endsWith(".json")).some((fileName) => {
48506
48670
  try {
48507
- const content = readFileSync5(join9(partDir, fileName), "utf-8");
48671
+ const content = readFileSync6(join11(partDir, fileName), "utf-8");
48508
48672
  return isCompactionPart(JSON.parse(content));
48509
48673
  } catch {
48510
48674
  return false;
@@ -48537,23 +48701,23 @@ var init_hook_message_injector = __esm(() => {
48537
48701
  });
48538
48702
 
48539
48703
  // src/shared/opencode-message-dir.ts
48540
- import { existsSync as existsSync8, readdirSync as readdirSync2 } from "fs";
48541
- import { join as join10 } from "path";
48704
+ import { existsSync as existsSync10, readdirSync as readdirSync2 } from "fs";
48705
+ import { join as join12 } from "path";
48542
48706
  function getMessageDir(sessionID) {
48543
48707
  if (!sessionID.startsWith("ses_"))
48544
48708
  return null;
48545
48709
  if (/[/\\]|\.\./.test(sessionID))
48546
48710
  return null;
48547
- if (!existsSync8(MESSAGE_STORAGE))
48711
+ if (!existsSync10(MESSAGE_STORAGE))
48548
48712
  return null;
48549
- const directPath = join10(MESSAGE_STORAGE, sessionID);
48550
- if (existsSync8(directPath)) {
48713
+ const directPath = join12(MESSAGE_STORAGE, sessionID);
48714
+ if (existsSync10(directPath)) {
48551
48715
  return directPath;
48552
48716
  }
48553
48717
  try {
48554
48718
  for (const dir of readdirSync2(MESSAGE_STORAGE)) {
48555
- const sessionPath = join10(MESSAGE_STORAGE, dir, sessionID);
48556
- if (existsSync8(sessionPath)) {
48719
+ const sessionPath = join12(MESSAGE_STORAGE, dir, sessionID);
48720
+ if (existsSync10(sessionPath)) {
48557
48721
  return sessionPath;
48558
48722
  }
48559
48723
  }
@@ -48568,68 +48732,6 @@ var init_opencode_message_dir = __esm(() => {
48568
48732
  init_logger();
48569
48733
  });
48570
48734
 
48571
- // src/shared/agent-display-names.ts
48572
- function stripInvisibleAgentCharacters(agentName) {
48573
- return agentName.replace(INVISIBLE_AGENT_CHARACTERS_REGEX, "");
48574
- }
48575
- function stripAgentListSortPrefix(agentName) {
48576
- return stripInvisibleAgentCharacters(agentName);
48577
- }
48578
- function getAgentDisplayName(configKey) {
48579
- const exactMatch = AGENT_DISPLAY_NAMES[configKey];
48580
- if (exactMatch !== undefined)
48581
- return exactMatch;
48582
- const lowerKey = configKey.toLowerCase();
48583
- for (const [k, v] of Object.entries(AGENT_DISPLAY_NAMES)) {
48584
- if (k.toLowerCase() === lowerKey)
48585
- return v;
48586
- }
48587
- return configKey;
48588
- }
48589
- function getAgentConfigKey(agentName) {
48590
- const lower = stripAgentListSortPrefix(agentName).trim().toLowerCase();
48591
- const reversed = REVERSE_DISPLAY_NAMES[lower];
48592
- if (reversed !== undefined)
48593
- return reversed;
48594
- const legacy = LEGACY_DISPLAY_NAMES[lower];
48595
- if (legacy !== undefined)
48596
- return legacy;
48597
- if (AGENT_DISPLAY_NAMES[lower] !== undefined)
48598
- return lower;
48599
- return lower;
48600
- }
48601
- var AGENT_DISPLAY_NAMES, INVISIBLE_AGENT_CHARACTERS_REGEX, REVERSE_DISPLAY_NAMES, LEGACY_DISPLAY_NAMES;
48602
- var init_agent_display_names = __esm(() => {
48603
- AGENT_DISPLAY_NAMES = {
48604
- sisyphus: "Sisyphus - Ultraworker",
48605
- hephaestus: "Hephaestus - Deep Agent",
48606
- prometheus: "Prometheus - Plan Builder",
48607
- atlas: "Atlas - Plan Executor",
48608
- "sisyphus-junior": "Sisyphus-Junior",
48609
- metis: "Metis - Plan Consultant",
48610
- momus: "Momus - Plan Critic",
48611
- athena: "Athena - Council",
48612
- "athena-junior": "Athena-Junior - Council",
48613
- oracle: "oracle",
48614
- librarian: "librarian",
48615
- explore: "explore",
48616
- "multimodal-looker": "multimodal-looker",
48617
- "council-member": "council-member"
48618
- };
48619
- INVISIBLE_AGENT_CHARACTERS_REGEX = /[\u200B\u200C\u200D\uFEFF]/g;
48620
- REVERSE_DISPLAY_NAMES = Object.fromEntries(Object.entries(AGENT_DISPLAY_NAMES).map(([key, displayName]) => [displayName.toLowerCase(), key]));
48621
- LEGACY_DISPLAY_NAMES = {
48622
- "sisyphus (ultraworker)": "sisyphus",
48623
- "hephaestus (deep agent)": "hephaestus",
48624
- "prometheus (plan builder)": "prometheus",
48625
- "atlas (plan executor)": "atlas",
48626
- "metis (plan consultant)": "metis",
48627
- "momus (plan critic)": "momus",
48628
- "athena (council)": "athena",
48629
- "athena-junior (council)": "athena-junior"
48630
- };
48631
- });
48632
-
48633
48735
  // src/shared/session-utils.ts
48634
48736
  var init_session_utils = __esm(() => {
48635
48737
  init_hook_message_injector();
@@ -48716,6 +48818,12 @@ var init_model_suggestion_retry = __esm(() => {
48716
48818
  var init_opencode_server_auth = __esm(() => {
48717
48819
  init_logger();
48718
48820
  });
48821
+
48822
+ // src/shared/opencode-provider-auth.ts
48823
+ var init_opencode_provider_auth = __esm(() => {
48824
+ init_data_path();
48825
+ init_logger();
48826
+ });
48719
48827
  // src/shared/opencode-http-api.ts
48720
48828
  var init_opencode_http_api = __esm(() => {
48721
48829
  init_opencode_server_auth();
@@ -48966,6 +49074,7 @@ var init_shared = __esm(() => {
48966
49074
  init_jsonc_parser();
48967
49075
  init_migration();
48968
49076
  init_opencode_config_dir();
49077
+ init_resolve_agent_definition_paths();
48969
49078
  init_opencode_version();
48970
49079
  init_opencode_storage_detection();
48971
49080
  init_external_plugin_detector();
@@ -48990,6 +49099,7 @@ var init_shared = __esm(() => {
48990
49099
  init_tmux();
48991
49100
  init_model_suggestion_retry();
48992
49101
  init_opencode_server_auth();
49102
+ init_opencode_provider_auth();
48993
49103
  init_opencode_http_api();
48994
49104
  init_port_utils();
48995
49105
  init_git_worktree();
@@ -49084,18 +49194,18 @@ var init_plugin_name_with_version = __esm(() => {
49084
49194
  });
49085
49195
 
49086
49196
  // src/cli/config-manager/backup-config.ts
49087
- import { copyFileSync as copyFileSync2, existsSync as existsSync9, mkdirSync as mkdirSync4 } from "fs";
49088
- import { dirname as dirname2 } from "path";
49197
+ import { copyFileSync as copyFileSync2, existsSync as existsSync11, mkdirSync as mkdirSync5 } from "fs";
49198
+ import { dirname as dirname3 } from "path";
49089
49199
  function backupConfigFile(configPath) {
49090
- if (!existsSync9(configPath)) {
49200
+ if (!existsSync11(configPath)) {
49091
49201
  return { success: true };
49092
49202
  }
49093
49203
  const timestamp2 = new Date().toISOString().replace(/[:.]/g, "-");
49094
49204
  const backupPath = `${configPath}.backup-${timestamp2}`;
49095
49205
  try {
49096
- const dir = dirname2(backupPath);
49097
- if (!existsSync9(dir)) {
49098
- mkdirSync4(dir, { recursive: true });
49206
+ const dir = dirname3(backupPath);
49207
+ if (!existsSync11(dir)) {
49208
+ mkdirSync5(dir, { recursive: true });
49099
49209
  }
49100
49210
  copyFileSync2(configPath, backupPath);
49101
49211
  return { success: true, backupPath };
@@ -49109,11 +49219,11 @@ function backupConfigFile(configPath) {
49109
49219
  var init_backup_config = () => {};
49110
49220
 
49111
49221
  // src/cli/config-manager/ensure-config-directory-exists.ts
49112
- import { existsSync as existsSync10, mkdirSync as mkdirSync5 } from "fs";
49222
+ import { existsSync as existsSync12, mkdirSync as mkdirSync6 } from "fs";
49113
49223
  function ensureConfigDirectoryExists() {
49114
49224
  const configDir = getConfigDir();
49115
- if (!existsSync10(configDir)) {
49116
- mkdirSync5(configDir, { recursive: true });
49225
+ if (!existsSync12(configDir)) {
49226
+ mkdirSync6(configDir, { recursive: true });
49117
49227
  }
49118
49228
  }
49119
49229
  var init_ensure_config_directory_exists = __esm(() => {
@@ -49150,14 +49260,14 @@ function formatErrorWithSuggestion(err, context) {
49150
49260
  }
49151
49261
 
49152
49262
  // src/cli/config-manager/opencode-config-format.ts
49153
- import { existsSync as existsSync11 } from "fs";
49263
+ import { existsSync as existsSync13 } from "fs";
49154
49264
  function detectConfigFormat() {
49155
49265
  const configJsonc = getConfigJsonc();
49156
49266
  const configJson = getConfigJson();
49157
- if (existsSync11(configJsonc)) {
49267
+ if (existsSync13(configJsonc)) {
49158
49268
  return { format: "jsonc", path: configJsonc };
49159
49269
  }
49160
- if (existsSync11(configJson)) {
49270
+ if (existsSync13(configJson)) {
49161
49271
  return { format: "json", path: configJson };
49162
49272
  }
49163
49273
  return { format: "none", path: configJson };
@@ -49167,33 +49277,33 @@ var init_opencode_config_format = __esm(() => {
49167
49277
  });
49168
49278
 
49169
49279
  // src/cli/config-manager/parse-opencode-config-file.ts
49170
- import { readFileSync as readFileSync6, statSync } from "fs";
49280
+ import { readFileSync as readFileSync7, statSync } from "fs";
49171
49281
  function isEmptyOrWhitespace(content) {
49172
49282
  return content.trim().length === 0;
49173
49283
  }
49174
- function parseOpenCodeConfigFileWithError(path4) {
49284
+ function parseOpenCodeConfigFileWithError(path5) {
49175
49285
  try {
49176
- const stat = statSync(path4);
49286
+ const stat = statSync(path5);
49177
49287
  if (stat.size === 0) {
49178
- return { config: null, error: `Config file is empty: ${path4}. Delete it or add valid JSON content.` };
49288
+ return { config: null, error: `Config file is empty: ${path5}. Delete it or add valid JSON content.` };
49179
49289
  }
49180
- const content = readFileSync6(path4, "utf-8");
49290
+ const content = readFileSync7(path5, "utf-8");
49181
49291
  if (isEmptyOrWhitespace(content)) {
49182
- return { config: null, error: `Config file contains only whitespace: ${path4}. Delete it or add valid JSON content.` };
49292
+ return { config: null, error: `Config file contains only whitespace: ${path5}. Delete it or add valid JSON content.` };
49183
49293
  }
49184
49294
  const config = parseJsonc(content);
49185
- if (config === null || config === undefined) {
49186
- return { config: null, error: `Config file parsed to null/undefined: ${path4}. Ensure it contains valid JSON.` };
49295
+ if (config == null) {
49296
+ return { config: null, error: `Config file parsed to null/undefined: ${path5}. Ensure it contains valid JSON.` };
49187
49297
  }
49188
49298
  if (typeof config !== "object" || Array.isArray(config)) {
49189
49299
  return {
49190
49300
  config: null,
49191
- error: `Config file must contain a JSON object, not ${Array.isArray(config) ? "an array" : typeof config}: ${path4}`
49301
+ error: `Config file must contain a JSON object, not ${Array.isArray(config) ? "an array" : typeof config}: ${path5}`
49192
49302
  };
49193
49303
  }
49194
49304
  return { config };
49195
49305
  } catch (err) {
49196
- return { config: null, error: formatErrorWithSuggestion(err, `parse config file ${path4}`) };
49306
+ return { config: null, error: formatErrorWithSuggestion(err, `parse config file ${path5}`) };
49197
49307
  }
49198
49308
  }
49199
49309
  var init_parse_opencode_config_file = __esm(() => {
@@ -49283,7 +49393,7 @@ function extractVersionFromPluginEntry(entry) {
49283
49393
  }
49284
49394
 
49285
49395
  // src/cli/config-manager/add-plugin-to-opencode-config.ts
49286
- import { readFileSync as readFileSync7, writeFileSync as writeFileSync3 } from "fs";
49396
+ import { readFileSync as readFileSync8, writeFileSync as writeFileSync3 } from "fs";
49287
49397
  async function addPluginToOpenCodeConfig(currentVersion) {
49288
49398
  try {
49289
49399
  ensureConfigDirectoryExists();
@@ -49294,20 +49404,20 @@ async function addPluginToOpenCodeConfig(currentVersion) {
49294
49404
  error: formatErrorWithSuggestion(err, "create config directory")
49295
49405
  };
49296
49406
  }
49297
- const { format: format2, path: path4 } = detectConfigFormat();
49407
+ const { format: format2, path: path5 } = detectConfigFormat();
49298
49408
  const pluginEntry = await getPluginNameWithVersion(currentVersion, PLUGIN_NAME);
49299
49409
  try {
49300
49410
  if (format2 === "none") {
49301
49411
  const config2 = { plugin: [pluginEntry] };
49302
- writeFileSync3(path4, JSON.stringify(config2, null, 2) + `
49412
+ writeFileSync3(path5, JSON.stringify(config2, null, 2) + `
49303
49413
  `);
49304
- return { success: true, configPath: path4 };
49414
+ return { success: true, configPath: path5 };
49305
49415
  }
49306
- const parseResult = parseOpenCodeConfigFileWithError(path4);
49416
+ const parseResult = parseOpenCodeConfigFileWithError(path5);
49307
49417
  if (!parseResult.config) {
49308
49418
  return {
49309
49419
  success: false,
49310
- configPath: path4,
49420
+ configPath: path5,
49311
49421
  error: parseResult.error ?? "Failed to parse config file"
49312
49422
  };
49313
49423
  }
@@ -49323,28 +49433,24 @@ async function addPluginToOpenCodeConfig(currentVersion) {
49323
49433
  if (!compatibility.canUpgrade) {
49324
49434
  return {
49325
49435
  success: false,
49326
- configPath: path4,
49436
+ configPath: path5,
49327
49437
  error: compatibility.reason ?? "Version compatibility check failed"
49328
49438
  };
49329
49439
  }
49330
- const backupResult = backupConfigFile(path4);
49440
+ const backupResult = backupConfigFile(path5);
49331
49441
  if (!backupResult.success) {
49332
49442
  return {
49333
49443
  success: false,
49334
- configPath: path4,
49444
+ configPath: path5,
49335
49445
  error: `Failed to create backup: ${backupResult.error}`
49336
49446
  };
49337
49447
  }
49338
49448
  }
49339
49449
  const normalizedPlugins = [...otherPlugins];
49340
- if (canonicalEntries.length > 0 || legacyEntries.length > 0) {
49341
- normalizedPlugins.push(pluginEntry);
49342
- } else {
49343
- normalizedPlugins.push(pluginEntry);
49344
- }
49450
+ normalizedPlugins.push(pluginEntry);
49345
49451
  config.plugin = normalizedPlugins;
49346
49452
  if (format2 === "jsonc") {
49347
- const content = readFileSync7(path4, "utf-8");
49453
+ const content = readFileSync8(path5, "utf-8");
49348
49454
  const pluginArrayRegex = /((?:"plugin"|plugin)\s*:\s*)\[([\s\S]*?)\]/;
49349
49455
  const match = content.match(pluginArrayRegex);
49350
49456
  if (match) {
@@ -49353,21 +49459,21 @@ async function addPluginToOpenCodeConfig(currentVersion) {
49353
49459
  const newContent = content.replace(pluginArrayRegex, `$1[
49354
49460
  ${formattedPlugins}
49355
49461
  ]`);
49356
- writeFileSync3(path4, newContent);
49462
+ writeFileSync3(path5, newContent);
49357
49463
  } else {
49358
49464
  const newContent = content.replace(/(\{)/, `$1
49359
49465
  "plugin": ["${pluginEntry}"],`);
49360
- writeFileSync3(path4, newContent);
49466
+ writeFileSync3(path5, newContent);
49361
49467
  }
49362
49468
  } else {
49363
- writeFileSync3(path4, JSON.stringify(config, null, 2) + `
49469
+ writeFileSync3(path5, JSON.stringify(config, null, 2) + `
49364
49470
  `);
49365
49471
  }
49366
- return { success: true, configPath: path4 };
49472
+ return { success: true, configPath: path5 };
49367
49473
  } catch (err) {
49368
49474
  return {
49369
49475
  success: false,
49370
- configPath: path4,
49476
+ configPath: path5,
49371
49477
  error: formatErrorWithSuggestion(err, "update opencode config")
49372
49478
  };
49373
49479
  }
@@ -49434,6 +49540,7 @@ function toProviderAvailability(config) {
49434
49540
  zai: config.hasZaiCodingPlan,
49435
49541
  kimiForCoding: config.hasKimiForCoding,
49436
49542
  opencodeGo: config.hasOpencodeGo,
49543
+ vercelAiGateway: config.hasVercelAiGateway,
49437
49544
  isMaxPlan: config.isMax20
49438
49545
  };
49439
49546
  }
@@ -49446,20 +49553,74 @@ function isProviderAvailable(provider, availability) {
49446
49553
  opencode: availability.opencodeZen,
49447
49554
  "zai-coding-plan": availability.zai,
49448
49555
  "kimi-for-coding": availability.kimiForCoding,
49449
- "opencode-go": availability.opencodeGo
49556
+ "opencode-go": availability.opencodeGo,
49557
+ vercel: availability.vercelAiGateway
49450
49558
  };
49451
49559
  return mapping[provider] ?? false;
49452
49560
  }
49453
49561
 
49454
49562
  // src/cli/provider-model-id-transform.ts
49455
- var init_provider_model_id_transform = () => {};
49563
+ function inferSubProvider(model) {
49564
+ if (model.startsWith("claude-"))
49565
+ return "anthropic";
49566
+ if (model.startsWith("gpt-"))
49567
+ return "openai";
49568
+ if (model.startsWith("gemini-"))
49569
+ return "google";
49570
+ if (model.startsWith("grok-"))
49571
+ return "xai";
49572
+ if (model.startsWith("minimax-"))
49573
+ return "minimax";
49574
+ if (model.startsWith("kimi-"))
49575
+ return "moonshotai";
49576
+ if (model.startsWith("glm-"))
49577
+ return "zai";
49578
+ return;
49579
+ }
49580
+ function claudeVersionDot(model) {
49581
+ return model.replace(CLAUDE_VERSION_DOT, "claude-$1-$2.$3");
49582
+ }
49583
+ function applyGatewayTransforms(model) {
49584
+ return claudeVersionDot(model).replace(GEMINI_31_PRO_PREVIEW, "gemini-3.1-pro-preview");
49585
+ }
49586
+ function transformModelForProvider2(provider, model) {
49587
+ if (provider === "vercel") {
49588
+ const slashIndex = model.indexOf("/");
49589
+ if (slashIndex !== -1) {
49590
+ const subProvider2 = model.substring(0, slashIndex);
49591
+ const subModel = model.substring(slashIndex + 1);
49592
+ return `${subProvider2}/${applyGatewayTransforms(subModel)}`;
49593
+ }
49594
+ const subProvider = inferSubProvider(model);
49595
+ if (subProvider) {
49596
+ return `${subProvider}/${applyGatewayTransforms(model)}`;
49597
+ }
49598
+ return model;
49599
+ }
49600
+ if (provider === "github-copilot") {
49601
+ return claudeVersionDot(model).replace(GEMINI_31_PRO_PREVIEW, "gemini-3.1-pro-preview").replace(GEMINI_3_FLASH_PREVIEW, "gemini-3-flash-preview");
49602
+ }
49603
+ if (provider === "google") {
49604
+ return model.replace(GEMINI_31_PRO_PREVIEW, "gemini-3.1-pro-preview").replace(GEMINI_3_FLASH_PREVIEW, "gemini-3-flash-preview");
49605
+ }
49606
+ if (provider === "anthropic") {
49607
+ return model;
49608
+ }
49609
+ return model;
49610
+ }
49611
+ var CLAUDE_VERSION_DOT, GEMINI_31_PRO_PREVIEW, GEMINI_3_FLASH_PREVIEW;
49612
+ var init_provider_model_id_transform2 = __esm(() => {
49613
+ CLAUDE_VERSION_DOT = /claude-(\w+)-(\d+)-(\d+)/g;
49614
+ GEMINI_31_PRO_PREVIEW = /gemini-3\.1-pro(?!-)/g;
49615
+ GEMINI_3_FLASH_PREVIEW = /gemini-3-flash(?!-)/g;
49616
+ });
49456
49617
 
49457
49618
  // src/cli/fallback-chain-resolution.ts
49458
49619
  function resolveModelFromChain(fallbackChain, availability) {
49459
49620
  for (const entry of fallbackChain) {
49460
49621
  for (const provider of entry.providers) {
49461
49622
  if (isProviderAvailable(provider, availability)) {
49462
- const transformedModel = transformModelForProvider(provider, entry.model);
49623
+ const transformedModel = transformModelForProvider2(provider, entry.model);
49463
49624
  return {
49464
49625
  model: `${provider}/${transformedModel}`,
49465
49626
  variant: entry.variant
@@ -49486,13 +49647,13 @@ function isRequiredProviderAvailable(requiredProviders, availability) {
49486
49647
  }
49487
49648
  var init_fallback_chain_resolution = __esm(() => {
49488
49649
  init_model_fallback_requirements();
49489
- init_provider_model_id_transform();
49650
+ init_provider_model_id_transform2();
49490
49651
  });
49491
49652
 
49492
49653
  // src/cli/model-fallback.ts
49493
49654
  function toFallbackModelObject(entry, provider) {
49494
49655
  return {
49495
- model: `${provider}/${transformModelForProvider(provider, entry.model)}`,
49656
+ model: `${provider}/${transformModelForProvider2(provider, entry.model)}`,
49496
49657
  ...entry.variant ? { variant: entry.variant } : {},
49497
49658
  ...entry.reasoningEffort ? { reasoningEffort: entry.reasoningEffort } : {},
49498
49659
  ...entry.temperature !== undefined ? { temperature: entry.temperature } : {},
@@ -49533,7 +49694,7 @@ function attachAllFallbackModels(config, fallbackChain, availability) {
49533
49694
  }
49534
49695
  function generateModelConfig(config) {
49535
49696
  const avail = toProviderAvailability(config);
49536
- const hasAnyProvider = avail.native.claude || avail.native.openai || avail.native.gemini || avail.opencodeZen || avail.copilot || avail.zai || avail.kimiForCoding || avail.opencodeGo;
49697
+ const hasAnyProvider = avail.native.claude || avail.native.openai || avail.native.gemini || avail.opencodeZen || avail.copilot || avail.zai || avail.kimiForCoding || avail.opencodeGo || avail.vercelAiGateway;
49537
49698
  if (!hasAnyProvider) {
49538
49699
  return {
49539
49700
  $schema: SCHEMA_URL,
@@ -49550,6 +49711,8 @@ function generateModelConfig(config) {
49550
49711
  agentConfig = { model: "opencode-go/minimax-m2.7" };
49551
49712
  } else if (avail.zai) {
49552
49713
  agentConfig = { model: ZAI_MODEL };
49714
+ } else if (avail.vercelAiGateway) {
49715
+ agentConfig = { model: "vercel/minimax/minimax-m2.7" };
49553
49716
  }
49554
49717
  if (agentConfig) {
49555
49718
  agents[role] = attachAllFallbackModels(agentConfig, req.fallbackChain, avail);
@@ -49566,6 +49729,8 @@ function generateModelConfig(config) {
49566
49729
  agentConfig = { model: "opencode-go/minimax-m2.7" };
49567
49730
  } else if (avail.copilot) {
49568
49731
  agentConfig = { model: "github-copilot/gpt-5-mini" };
49732
+ } else if (avail.vercelAiGateway) {
49733
+ agentConfig = { model: "vercel/minimax/minimax-m2.7-highspeed" };
49569
49734
  } else {
49570
49735
  agentConfig = { model: "opencode/gpt-5-nano" };
49571
49736
  }
@@ -49629,7 +49794,7 @@ var init_model_fallback = __esm(() => {
49629
49794
  init_model_fallback_requirements();
49630
49795
  init_openai_only_model_catalog();
49631
49796
  init_fallback_chain_resolution();
49632
- init_provider_model_id_transform();
49797
+ init_provider_model_id_transform2();
49633
49798
  });
49634
49799
 
49635
49800
  // src/cli/config-manager/generate-omo-config.ts
@@ -49641,12 +49806,12 @@ var init_generate_omo_config = __esm(() => {
49641
49806
  });
49642
49807
 
49643
49808
  // src/shared/migrate-legacy-config-file.ts
49644
- import { existsSync as existsSync12, readFileSync as readFileSync8, renameSync as renameSync2, rmSync } from "fs";
49645
- import { join as join11, dirname as dirname3, basename } from "path";
49809
+ import { existsSync as existsSync14, readFileSync as readFileSync9, renameSync as renameSync2, rmSync } from "fs";
49810
+ import { join as join13, dirname as dirname4, basename as basename2 } from "path";
49646
49811
  function buildCanonicalPath(legacyPath) {
49647
- const dir = dirname3(legacyPath);
49648
- const ext = basename(legacyPath).includes(".jsonc") ? ".jsonc" : ".json";
49649
- return join11(dir, `${CONFIG_BASENAME}${ext}`);
49812
+ const dir = dirname4(legacyPath);
49813
+ const ext = basename2(legacyPath).includes(".jsonc") ? ".jsonc" : ".json";
49814
+ return join13(dir, `${CONFIG_BASENAME}${ext}`);
49650
49815
  }
49651
49816
  function archiveLegacyConfigFile(legacyPath) {
49652
49817
  const backupPath = `${legacyPath}.bak`;
@@ -49678,15 +49843,15 @@ function archiveLegacyConfigFile(legacyPath) {
49678
49843
  }
49679
49844
  }
49680
49845
  function migrateLegacyConfigFile(legacyPath) {
49681
- if (!existsSync12(legacyPath))
49846
+ if (!existsSync14(legacyPath))
49682
49847
  return false;
49683
- if (!basename(legacyPath).startsWith(LEGACY_CONFIG_BASENAME))
49848
+ if (!basename2(legacyPath).startsWith(LEGACY_CONFIG_BASENAME))
49684
49849
  return false;
49685
49850
  const canonicalPath = buildCanonicalPath(legacyPath);
49686
- if (existsSync12(canonicalPath))
49851
+ if (existsSync14(canonicalPath))
49687
49852
  return false;
49688
49853
  try {
49689
- const content = readFileSync8(legacyPath, "utf-8");
49854
+ const content = readFileSync9(legacyPath, "utf-8");
49690
49855
  writeFileAtomically(canonicalPath, content);
49691
49856
  const archivedLegacyConfig = archiveLegacyConfigFile(legacyPath);
49692
49857
  log("[migrateLegacyConfigFile] Migrated legacy config to canonical path", {
@@ -49694,7 +49859,7 @@ function migrateLegacyConfigFile(legacyPath) {
49694
49859
  to: canonicalPath,
49695
49860
  archivedLegacyConfig
49696
49861
  });
49697
- return archivedLegacyConfig;
49862
+ return true;
49698
49863
  } catch (error) {
49699
49864
  log("[migrateLegacyConfigFile] Failed to migrate legacy config file", { legacyPath, error });
49700
49865
  return false;
@@ -49724,8 +49889,8 @@ function deepMergeRecord(target, source) {
49724
49889
  }
49725
49890
 
49726
49891
  // src/cli/config-manager/write-omo-config.ts
49727
- import { existsSync as existsSync13, readFileSync as readFileSync9, statSync as statSync2, writeFileSync as writeFileSync4 } from "fs";
49728
- import { basename as basename2, dirname as dirname4, extname, join as join12 } from "path";
49892
+ import { existsSync as existsSync15, readFileSync as readFileSync10, statSync as statSync2, writeFileSync as writeFileSync4 } from "fs";
49893
+ import { basename as basename3, dirname as dirname5, extname, join as join14 } from "path";
49729
49894
  function isEmptyOrWhitespace2(content) {
49730
49895
  return content.trim().length === 0;
49731
49896
  }
@@ -49740,12 +49905,12 @@ function writeOmoConfig(installConfig) {
49740
49905
  };
49741
49906
  }
49742
49907
  const detectedConfigPath = getOmoConfigPath();
49743
- const canonicalConfigPath = join12(dirname4(detectedConfigPath), `${CONFIG_BASENAME}${extname(detectedConfigPath) || ".json"}`);
49744
- const shouldMigrateLegacyPath = basename2(detectedConfigPath).startsWith(LEGACY_CONFIG_BASENAME);
49745
- const omoConfigPath = shouldMigrateLegacyPath ? migrateLegacyConfigFile(detectedConfigPath) || existsSync13(canonicalConfigPath) ? canonicalConfigPath : detectedConfigPath : detectedConfigPath;
49908
+ const canonicalConfigPath = join14(dirname5(detectedConfigPath), `${CONFIG_BASENAME}${extname(detectedConfigPath) || ".json"}`);
49909
+ const shouldMigrateLegacyPath = basename3(detectedConfigPath).startsWith(LEGACY_CONFIG_BASENAME);
49910
+ const omoConfigPath = shouldMigrateLegacyPath ? migrateLegacyConfigFile(detectedConfigPath) || existsSync15(canonicalConfigPath) ? canonicalConfigPath : detectedConfigPath : detectedConfigPath;
49746
49911
  try {
49747
49912
  const newConfig = generateOmoConfig(installConfig);
49748
- if (existsSync13(omoConfigPath)) {
49913
+ if (existsSync15(omoConfigPath)) {
49749
49914
  const backupResult = backupConfigFile(omoConfigPath);
49750
49915
  if (!backupResult.success) {
49751
49916
  return {
@@ -49756,7 +49921,7 @@ function writeOmoConfig(installConfig) {
49756
49921
  }
49757
49922
  try {
49758
49923
  const stat = statSync2(omoConfigPath);
49759
- const content = readFileSync9(omoConfigPath, "utf-8");
49924
+ const content = readFileSync10(omoConfigPath, "utf-8");
49760
49925
  if (stat.size === 0 || isEmptyOrWhitespace2(content)) {
49761
49926
  writeFileSync4(omoConfigPath, JSON.stringify(newConfig, null, 2) + `
49762
49927
  `);
@@ -49815,8 +49980,8 @@ function toReadableStream(stream) {
49815
49980
  function wrapNodeProcess(proc) {
49816
49981
  let resolveExited;
49817
49982
  let exitCode = null;
49818
- const exited = new Promise((resolve2) => {
49819
- resolveExited = resolve2;
49983
+ const exited = new Promise((resolve4) => {
49984
+ resolveExited = resolve4;
49820
49985
  });
49821
49986
  proc.on("exit", (code) => {
49822
49987
  exitCode = code ?? 1;
@@ -49899,20 +50064,21 @@ var init_opencode_binary = __esm(() => {
49899
50064
  });
49900
50065
 
49901
50066
  // src/cli/config-manager/detect-current-config.ts
49902
- import { existsSync as existsSync14, readFileSync as readFileSync10 } from "fs";
50067
+ import { existsSync as existsSync16, readFileSync as readFileSync11 } from "fs";
49903
50068
  function detectProvidersFromOmoConfig() {
49904
50069
  const omoConfigPath = getOmoConfigPath();
49905
- if (!existsSync14(omoConfigPath)) {
50070
+ if (!existsSync16(omoConfigPath)) {
49906
50071
  return {
49907
50072
  hasOpenAI: true,
49908
50073
  hasOpencodeZen: true,
49909
50074
  hasZaiCodingPlan: false,
49910
50075
  hasKimiForCoding: false,
49911
- hasOpencodeGo: false
50076
+ hasOpencodeGo: false,
50077
+ hasVercelAiGateway: false
49912
50078
  };
49913
50079
  }
49914
50080
  try {
49915
- const content = readFileSync10(omoConfigPath, "utf-8");
50081
+ const content = readFileSync11(omoConfigPath, "utf-8");
49916
50082
  const omoConfig = parseJsonc(content);
49917
50083
  if (!omoConfig || typeof omoConfig !== "object") {
49918
50084
  return {
@@ -49920,7 +50086,8 @@ function detectProvidersFromOmoConfig() {
49920
50086
  hasOpencodeZen: true,
49921
50087
  hasZaiCodingPlan: false,
49922
50088
  hasKimiForCoding: false,
49923
- hasOpencodeGo: false
50089
+ hasOpencodeGo: false,
50090
+ hasVercelAiGateway: false
49924
50091
  };
49925
50092
  }
49926
50093
  const configStr = JSON.stringify(omoConfig);
@@ -49929,14 +50096,16 @@ function detectProvidersFromOmoConfig() {
49929
50096
  const hasZaiCodingPlan = configStr.includes('"zai-coding-plan/');
49930
50097
  const hasKimiForCoding = configStr.includes('"kimi-for-coding/');
49931
50098
  const hasOpencodeGo = configStr.includes('"opencode-go/');
49932
- return { hasOpenAI, hasOpencodeZen, hasZaiCodingPlan, hasKimiForCoding, hasOpencodeGo };
50099
+ const hasVercelAiGateway = configStr.includes('"vercel/');
50100
+ return { hasOpenAI, hasOpencodeZen, hasZaiCodingPlan, hasKimiForCoding, hasOpencodeGo, hasVercelAiGateway };
49933
50101
  } catch {
49934
50102
  return {
49935
50103
  hasOpenAI: true,
49936
50104
  hasOpencodeZen: true,
49937
50105
  hasZaiCodingPlan: false,
49938
50106
  hasKimiForCoding: false,
49939
- hasOpencodeGo: false
50107
+ hasOpencodeGo: false,
50108
+ hasVercelAiGateway: false
49940
50109
  };
49941
50110
  }
49942
50111
  }
@@ -49958,13 +50127,14 @@ function detectCurrentConfig() {
49958
50127
  hasOpencodeZen: true,
49959
50128
  hasZaiCodingPlan: false,
49960
50129
  hasKimiForCoding: false,
49961
- hasOpencodeGo: false
50130
+ hasOpencodeGo: false,
50131
+ hasVercelAiGateway: false
49962
50132
  };
49963
- const { format: format2, path: path4 } = detectConfigFormat();
50133
+ const { format: format2, path: path5 } = detectConfigFormat();
49964
50134
  if (format2 === "none") {
49965
50135
  return result;
49966
50136
  }
49967
- const parseResult = parseOpenCodeConfigFileWithError(path4);
50137
+ const parseResult = parseOpenCodeConfigFileWithError(path5);
49968
50138
  if (!parseResult.config) {
49969
50139
  return result;
49970
50140
  }
@@ -49980,12 +50150,13 @@ function detectCurrentConfig() {
49980
50150
  }
49981
50151
  const providers = openCodeConfig.provider;
49982
50152
  result.hasGemini = providers ? "google" in providers : false;
49983
- const { hasOpenAI, hasOpencodeZen, hasZaiCodingPlan, hasKimiForCoding, hasOpencodeGo } = detectProvidersFromOmoConfig();
50153
+ const { hasOpenAI, hasOpencodeZen, hasZaiCodingPlan, hasKimiForCoding, hasOpencodeGo, hasVercelAiGateway } = detectProvidersFromOmoConfig();
49984
50154
  result.hasOpenAI = hasOpenAI;
49985
50155
  result.hasOpencodeZen = hasOpencodeZen;
49986
50156
  result.hasZaiCodingPlan = hasZaiCodingPlan;
49987
50157
  result.hasKimiForCoding = hasKimiForCoding;
49988
50158
  result.hasOpencodeGo = hasOpencodeGo;
50159
+ result.hasVercelAiGateway = hasVercelAiGateway;
49989
50160
  return result;
49990
50161
  }
49991
50162
  var init_detect_current_config = __esm(() => {
@@ -49996,10 +50167,10 @@ var init_detect_current_config = __esm(() => {
49996
50167
  });
49997
50168
 
49998
50169
  // src/cli/config-manager/bun-install.ts
49999
- import { existsSync as existsSync15 } from "fs";
50000
- import { join as join13 } from "path";
50170
+ import { existsSync as existsSync17 } from "fs";
50171
+ import { join as join15 } from "path";
50001
50172
  function getDefaultWorkspaceDir() {
50002
- return join13(getOpenCodeCacheDir(), "packages");
50173
+ return join15(getOpenCodeCacheDir(), "packages");
50003
50174
  }
50004
50175
  function readProcessOutput(stream) {
50005
50176
  if (!stream) {
@@ -50025,7 +50196,7 @@ async function runBunInstallWithDetails(options) {
50025
50196
  const outputMode = options?.outputMode ?? "pipe";
50026
50197
  const cacheDir = options?.workspaceDir ?? getDefaultWorkspaceDir();
50027
50198
  const packageJsonPath = `${cacheDir}/package.json`;
50028
- if (!existsSync15(packageJsonPath)) {
50199
+ if (!existsSync17(packageJsonPath)) {
50029
50200
  return {
50030
50201
  success: false,
50031
50202
  error: `Workspace not initialized: ${packageJsonPath} not found. OpenCode should create this on first run.`
@@ -50039,8 +50210,8 @@ async function runBunInstallWithDetails(options) {
50039
50210
  });
50040
50211
  const outputPromise = Promise.all([readProcessOutput(proc.stdout), readProcessOutput(proc.stderr)]).then(([stdout, stderr]) => ({ stdout, stderr }));
50041
50212
  let timeoutId;
50042
- const timeoutPromise = new Promise((resolve2) => {
50043
- timeoutId = setTimeout(() => resolve2("timeout"), BUN_INSTALL_TIMEOUT_MS);
50213
+ const timeoutPromise = new Promise((resolve4) => {
50214
+ timeoutId = setTimeout(() => resolve4("timeout"), BUN_INSTALL_TIMEOUT_MS);
50044
50215
  });
50045
50216
  const exitPromise = proc.exited.then(() => "completed");
50046
50217
  const result = await Promise.race([exitPromise, timeoutPromise]);
@@ -50167,7 +50338,7 @@ var require_windows = __commonJS((exports2, module) => {
50167
50338
  module.exports = isexe;
50168
50339
  isexe.sync = sync;
50169
50340
  var fs5 = __require("fs");
50170
- function checkPathExt(path5, options) {
50341
+ function checkPathExt(path6, options) {
50171
50342
  var pathext = options.pathExt !== undefined ? options.pathExt : process.env.PATHEXT;
50172
50343
  if (!pathext) {
50173
50344
  return true;
@@ -50178,25 +50349,25 @@ var require_windows = __commonJS((exports2, module) => {
50178
50349
  }
50179
50350
  for (var i2 = 0;i2 < pathext.length; i2++) {
50180
50351
  var p2 = pathext[i2].toLowerCase();
50181
- if (p2 && path5.substr(-p2.length).toLowerCase() === p2) {
50352
+ if (p2 && path6.substr(-p2.length).toLowerCase() === p2) {
50182
50353
  return true;
50183
50354
  }
50184
50355
  }
50185
50356
  return false;
50186
50357
  }
50187
- function checkStat(stat, path5, options) {
50358
+ function checkStat(stat, path6, options) {
50188
50359
  if (!stat.isSymbolicLink() && !stat.isFile()) {
50189
50360
  return false;
50190
50361
  }
50191
- return checkPathExt(path5, options);
50362
+ return checkPathExt(path6, options);
50192
50363
  }
50193
- function isexe(path5, options, cb) {
50194
- fs5.stat(path5, function(er, stat) {
50195
- cb(er, er ? false : checkStat(stat, path5, options));
50364
+ function isexe(path6, options, cb) {
50365
+ fs5.stat(path6, function(er, stat) {
50366
+ cb(er, er ? false : checkStat(stat, path6, options));
50196
50367
  });
50197
50368
  }
50198
- function sync(path5, options) {
50199
- return checkStat(fs5.statSync(path5), path5, options);
50369
+ function sync(path6, options) {
50370
+ return checkStat(fs5.statSync(path6), path6, options);
50200
50371
  }
50201
50372
  });
50202
50373
 
@@ -50205,13 +50376,13 @@ var require_mode = __commonJS((exports2, module) => {
50205
50376
  module.exports = isexe;
50206
50377
  isexe.sync = sync;
50207
50378
  var fs5 = __require("fs");
50208
- function isexe(path5, options, cb) {
50209
- fs5.stat(path5, function(er, stat) {
50379
+ function isexe(path6, options, cb) {
50380
+ fs5.stat(path6, function(er, stat) {
50210
50381
  cb(er, er ? false : checkStat(stat, options));
50211
50382
  });
50212
50383
  }
50213
- function sync(path5, options) {
50214
- return checkStat(fs5.statSync(path5), options);
50384
+ function sync(path6, options) {
50385
+ return checkStat(fs5.statSync(path6), options);
50215
50386
  }
50216
50387
  function checkStat(stat, options) {
50217
50388
  return stat.isFile() && checkMode(stat, options);
@@ -50242,7 +50413,7 @@ var require_isexe = __commonJS((exports2, module) => {
50242
50413
  }
50243
50414
  module.exports = isexe;
50244
50415
  isexe.sync = sync;
50245
- function isexe(path5, options, cb) {
50416
+ function isexe(path6, options, cb) {
50246
50417
  if (typeof options === "function") {
50247
50418
  cb = options;
50248
50419
  options = {};
@@ -50251,17 +50422,17 @@ var require_isexe = __commonJS((exports2, module) => {
50251
50422
  if (typeof Promise !== "function") {
50252
50423
  throw new TypeError("callback not provided");
50253
50424
  }
50254
- return new Promise(function(resolve2, reject) {
50255
- isexe(path5, options || {}, function(er, is) {
50425
+ return new Promise(function(resolve4, reject) {
50426
+ isexe(path6, options || {}, function(er, is) {
50256
50427
  if (er) {
50257
50428
  reject(er);
50258
50429
  } else {
50259
- resolve2(is);
50430
+ resolve4(is);
50260
50431
  }
50261
50432
  });
50262
50433
  });
50263
50434
  }
50264
- core3(path5, options || {}, function(er, is) {
50435
+ core3(path6, options || {}, function(er, is) {
50265
50436
  if (er) {
50266
50437
  if (er.code === "EACCES" || options && options.ignoreErrors) {
50267
50438
  er = null;
@@ -50271,9 +50442,9 @@ var require_isexe = __commonJS((exports2, module) => {
50271
50442
  cb(er, is);
50272
50443
  });
50273
50444
  }
50274
- function sync(path5, options) {
50445
+ function sync(path6, options) {
50275
50446
  try {
50276
- return core3.sync(path5, options || {});
50447
+ return core3.sync(path6, options || {});
50277
50448
  } catch (er) {
50278
50449
  if (options && options.ignoreErrors || er.code === "EACCES") {
50279
50450
  return false;
@@ -50287,7 +50458,7 @@ var require_isexe = __commonJS((exports2, module) => {
50287
50458
  // node_modules/which/which.js
50288
50459
  var require_which = __commonJS((exports2, module) => {
50289
50460
  var isWindows = process.platform === "win32" || process.env.OSTYPE === "cygwin" || process.env.OSTYPE === "msys";
50290
- var path5 = __require("path");
50461
+ var path6 = __require("path");
50291
50462
  var COLON = isWindows ? ";" : ":";
50292
50463
  var isexe = require_isexe();
50293
50464
  var getNotFoundError = (cmd) => Object.assign(new Error(`not found: ${cmd}`), { code: "ENOENT" });
@@ -50318,27 +50489,27 @@ var require_which = __commonJS((exports2, module) => {
50318
50489
  opt = {};
50319
50490
  const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
50320
50491
  const found = [];
50321
- const step = (i2) => new Promise((resolve2, reject) => {
50492
+ const step = (i2) => new Promise((resolve4, reject) => {
50322
50493
  if (i2 === pathEnv.length)
50323
- return opt.all && found.length ? resolve2(found) : reject(getNotFoundError(cmd));
50494
+ return opt.all && found.length ? resolve4(found) : reject(getNotFoundError(cmd));
50324
50495
  const ppRaw = pathEnv[i2];
50325
50496
  const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
50326
- const pCmd = path5.join(pathPart, cmd);
50497
+ const pCmd = path6.join(pathPart, cmd);
50327
50498
  const p2 = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
50328
- resolve2(subStep(p2, i2, 0));
50499
+ resolve4(subStep(p2, i2, 0));
50329
50500
  });
50330
- const subStep = (p2, i2, ii) => new Promise((resolve2, reject) => {
50501
+ const subStep = (p2, i2, ii) => new Promise((resolve4, reject) => {
50331
50502
  if (ii === pathExt.length)
50332
- return resolve2(step(i2 + 1));
50503
+ return resolve4(step(i2 + 1));
50333
50504
  const ext = pathExt[ii];
50334
50505
  isexe(p2 + ext, { pathExt: pathExtExe }, (er, is) => {
50335
50506
  if (!er && is) {
50336
50507
  if (opt.all)
50337
50508
  found.push(p2 + ext);
50338
50509
  else
50339
- return resolve2(p2 + ext);
50510
+ return resolve4(p2 + ext);
50340
50511
  }
50341
- return resolve2(subStep(p2, i2, ii + 1));
50512
+ return resolve4(subStep(p2, i2, ii + 1));
50342
50513
  });
50343
50514
  });
50344
50515
  return cb ? step(0).then((res) => cb(null, res), cb) : step(0);
@@ -50350,7 +50521,7 @@ var require_which = __commonJS((exports2, module) => {
50350
50521
  for (let i2 = 0;i2 < pathEnv.length; i2++) {
50351
50522
  const ppRaw = pathEnv[i2];
50352
50523
  const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
50353
- const pCmd = path5.join(pathPart, cmd);
50524
+ const pCmd = path6.join(pathPart, cmd);
50354
50525
  const p2 = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
50355
50526
  for (let j2 = 0;j2 < pathExt.length; j2++) {
50356
50527
  const cur = p2 + pathExt[j2];
@@ -50391,7 +50562,7 @@ var require_path_key = __commonJS((exports2, module) => {
50391
50562
 
50392
50563
  // node_modules/cross-spawn/lib/util/resolveCommand.js
50393
50564
  var require_resolveCommand = __commonJS((exports2, module) => {
50394
- var path5 = __require("path");
50565
+ var path6 = __require("path");
50395
50566
  var which = require_which();
50396
50567
  var getPathKey = require_path_key();
50397
50568
  function resolveCommandAttempt(parsed, withoutPathExt) {
@@ -50408,7 +50579,7 @@ var require_resolveCommand = __commonJS((exports2, module) => {
50408
50579
  try {
50409
50580
  resolved = which.sync(parsed.command, {
50410
50581
  path: env[getPathKey({ env })],
50411
- pathExt: withoutPathExt ? path5.delimiter : undefined
50582
+ pathExt: withoutPathExt ? path6.delimiter : undefined
50412
50583
  });
50413
50584
  } catch (e2) {} finally {
50414
50585
  if (shouldSwitchCwd) {
@@ -50416,7 +50587,7 @@ var require_resolveCommand = __commonJS((exports2, module) => {
50416
50587
  }
50417
50588
  }
50418
50589
  if (resolved) {
50419
- resolved = path5.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
50590
+ resolved = path6.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
50420
50591
  }
50421
50592
  return resolved;
50422
50593
  }
@@ -50461,8 +50632,8 @@ var require_shebang_command = __commonJS((exports2, module) => {
50461
50632
  if (!match) {
50462
50633
  return null;
50463
50634
  }
50464
- const [path5, argument] = match[0].replace(/#! ?/, "").split(" ");
50465
- const binary2 = path5.split("/").pop();
50635
+ const [path6, argument] = match[0].replace(/#! ?/, "").split(" ");
50636
+ const binary2 = path6.split("/").pop();
50466
50637
  if (binary2 === "env") {
50467
50638
  return argument;
50468
50639
  }
@@ -50490,7 +50661,7 @@ var require_readShebang = __commonJS((exports2, module) => {
50490
50661
 
50491
50662
  // node_modules/cross-spawn/lib/parse.js
50492
50663
  var require_parse = __commonJS((exports2, module) => {
50493
- var path5 = __require("path");
50664
+ var path6 = __require("path");
50494
50665
  var resolveCommand = require_resolveCommand();
50495
50666
  var escape = require_escape();
50496
50667
  var readShebang = require_readShebang();
@@ -50515,7 +50686,7 @@ var require_parse = __commonJS((exports2, module) => {
50515
50686
  const needsShell = !isExecutableRegExp.test(commandFile);
50516
50687
  if (parsed.options.forceShell || needsShell) {
50517
50688
  const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile);
50518
- parsed.command = path5.normalize(parsed.command);
50689
+ parsed.command = path6.normalize(parsed.command);
50519
50690
  parsed.command = escape.command(parsed.command);
50520
50691
  parsed.args = parsed.args.map((arg) => escape.argument(arg, needsDoubleEscapeMetaChars));
50521
50692
  const shellCommand = [parsed.command].concat(parsed.args).join(" ");
@@ -50619,21 +50790,21 @@ var require_cross_spawn = __commonJS((exports2, module) => {
50619
50790
  });
50620
50791
 
50621
50792
  // src/hooks/auto-update-checker/constants.ts
50622
- import * as path5 from "path";
50793
+ import * as path6 from "path";
50623
50794
  import * as os4 from "os";
50624
50795
  function getWindowsAppdataDir() {
50625
50796
  if (process.platform !== "win32")
50626
50797
  return null;
50627
- return process.env.APPDATA ?? path5.join(os4.homedir(), "AppData", "Roaming");
50798
+ return process.env.APPDATA ?? path6.join(os4.homedir(), "AppData", "Roaming");
50628
50799
  }
50629
50800
  function getUserConfigDir() {
50630
50801
  return getOpenCodeConfigDir({ binary: "opencode" });
50631
50802
  }
50632
50803
  function getUserOpencodeConfig() {
50633
- return path5.join(getUserConfigDir(), "opencode.json");
50804
+ return path6.join(getUserConfigDir(), "opencode.json");
50634
50805
  }
50635
50806
  function getUserOpencodeConfigJsonc() {
50636
- return path5.join(getUserConfigDir(), "opencode.jsonc");
50807
+ return path6.join(getUserConfigDir(), "opencode.jsonc");
50637
50808
  }
50638
50809
  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;
50639
50810
  var init_constants3 = __esm(() => {
@@ -50644,30 +50815,30 @@ var init_constants3 = __esm(() => {
50644
50815
  ACCEPTED_PACKAGE_NAMES2 = ACCEPTED_PACKAGE_NAMES;
50645
50816
  NPM_REGISTRY_URL = `https://registry.npmjs.org/-/package/${PACKAGE_NAME2}/dist-tags`;
50646
50817
  CACHE_ROOT_DIR = getOpenCodeCacheDir();
50647
- CACHE_DIR = path5.join(CACHE_ROOT_DIR, "packages");
50648
- VERSION_FILE = path5.join(CACHE_ROOT_DIR, "version");
50649
- INSTALLED_PACKAGE_JSON = path5.join(CACHE_DIR, "node_modules", PACKAGE_NAME2, "package.json");
50650
- INSTALLED_PACKAGE_JSON_CANDIDATES = ACCEPTED_PACKAGE_NAMES2.map((name) => path5.join(CACHE_DIR, "node_modules", name, "package.json"));
50818
+ CACHE_DIR = path6.join(CACHE_ROOT_DIR, "packages");
50819
+ VERSION_FILE = path6.join(CACHE_ROOT_DIR, "version");
50820
+ INSTALLED_PACKAGE_JSON = path6.join(CACHE_DIR, "node_modules", PACKAGE_NAME2, "package.json");
50821
+ INSTALLED_PACKAGE_JSON_CANDIDATES = ACCEPTED_PACKAGE_NAMES2.map((name) => path6.join(CACHE_DIR, "node_modules", name, "package.json"));
50651
50822
  });
50652
50823
 
50653
50824
  // src/hooks/auto-update-checker/checker/config-paths.ts
50654
50825
  import * as os5 from "os";
50655
- import * as path6 from "path";
50826
+ import * as path7 from "path";
50656
50827
  function getConfigPaths(directory) {
50657
50828
  const userConfigDir = getUserConfigDir();
50658
50829
  const paths = [
50659
- path6.join(directory, ".opencode", "opencode.json"),
50660
- path6.join(directory, ".opencode", "opencode.jsonc"),
50830
+ path7.join(directory, ".opencode", "opencode.json"),
50831
+ path7.join(directory, ".opencode", "opencode.jsonc"),
50661
50832
  getUserOpencodeConfig(),
50662
50833
  getUserOpencodeConfigJsonc()
50663
50834
  ];
50664
50835
  if (process.platform === "win32") {
50665
- const crossPlatformDir = path6.join(os5.homedir(), ".config");
50836
+ const crossPlatformDir = path7.join(os5.homedir(), ".config");
50666
50837
  const appdataDir = getWindowsAppdataDir();
50667
50838
  if (appdataDir) {
50668
50839
  const alternateDir = userConfigDir === crossPlatformDir ? appdataDir : crossPlatformDir;
50669
- const alternateConfig = path6.join(alternateDir, "opencode", "opencode.json");
50670
- const alternateConfigJsonc = path6.join(alternateDir, "opencode", "opencode.jsonc");
50840
+ const alternateConfig = path7.join(alternateDir, "opencode", "opencode.json");
50841
+ const alternateConfigJsonc = path7.join(alternateDir, "opencode", "opencode.jsonc");
50671
50842
  if (!paths.includes(alternateConfig)) {
50672
50843
  paths.push(alternateConfig);
50673
50844
  }
@@ -50725,13 +50896,13 @@ var init_local_dev_path = __esm(() => {
50725
50896
 
50726
50897
  // src/hooks/auto-update-checker/checker/package-json-locator.ts
50727
50898
  import * as fs6 from "fs";
50728
- import * as path7 from "path";
50899
+ import * as path8 from "path";
50729
50900
  function findPackageJsonUp(startPath) {
50730
50901
  try {
50731
50902
  const stat = fs6.statSync(startPath);
50732
- let dir = stat.isDirectory() ? startPath : path7.dirname(startPath);
50903
+ let dir = stat.isDirectory() ? startPath : path8.dirname(startPath);
50733
50904
  for (let i2 = 0;i2 < 10; i2++) {
50734
- const pkgPath = path7.join(dir, "package.json");
50905
+ const pkgPath = path8.join(dir, "package.json");
50735
50906
  if (fs6.existsSync(pkgPath)) {
50736
50907
  try {
50737
50908
  const content = fs6.readFileSync(pkgPath, "utf-8");
@@ -50740,7 +50911,7 @@ function findPackageJsonUp(startPath) {
50740
50911
  return pkgPath;
50741
50912
  } catch {}
50742
50913
  }
50743
- const parent = path7.dirname(dir);
50914
+ const parent = path8.dirname(dir);
50744
50915
  if (parent === dir)
50745
50916
  break;
50746
50917
  dir = parent;
@@ -50815,7 +50986,7 @@ var init_plugin_entry = __esm(() => {
50815
50986
 
50816
50987
  // src/hooks/auto-update-checker/checker/cached-version.ts
50817
50988
  import * as fs9 from "fs";
50818
- import * as path8 from "path";
50989
+ import * as path9 from "path";
50819
50990
  import { fileURLToPath as fileURLToPath2 } from "url";
50820
50991
  function readPackageVersion(packageJsonPath) {
50821
50992
  const content = fs9.readFileSync(packageJsonPath, "utf-8");
@@ -50831,7 +51002,7 @@ function getCachedVersion() {
50831
51002
  } catch {}
50832
51003
  }
50833
51004
  try {
50834
- const currentDir = path8.dirname(fileURLToPath2(import.meta.url));
51005
+ const currentDir = path9.dirname(fileURLToPath2(import.meta.url));
50835
51006
  const pkgPath = findPackageJsonUp(currentDir);
50836
51007
  if (pkgPath) {
50837
51008
  return readPackageVersion(pkgPath);
@@ -50840,7 +51011,7 @@ function getCachedVersion() {
50840
51011
  log("[auto-update-checker] Failed to resolve version from current directory:", err);
50841
51012
  }
50842
51013
  try {
50843
- const execDir = path8.dirname(fs9.realpathSync(process.execPath));
51014
+ const execDir = path9.dirname(fs9.realpathSync(process.execPath));
50844
51015
  const pkgPath = findPackageJsonUp(execDir);
50845
51016
  if (pkgPath) {
50846
51017
  return readPackageVersion(pkgPath);
@@ -50983,7 +51154,7 @@ var init_check_for_update = __esm(() => {
50983
51154
  // src/hooks/auto-update-checker/checker/sync-package-json.ts
50984
51155
  import * as crypto from "crypto";
50985
51156
  import * as fs10 from "fs";
50986
- import * as path9 from "path";
51157
+ import * as path10 from "path";
50987
51158
  function safeUnlink(filePath) {
50988
51159
  try {
50989
51160
  fs10.unlinkSync(filePath);
@@ -51000,7 +51171,7 @@ function getIntentVersion(pluginInfo) {
51000
51171
  function writeCachePackageJson(cachePackageJsonPath, pkgJson) {
51001
51172
  const tmpPath = `${cachePackageJsonPath}.${crypto.randomUUID()}`;
51002
51173
  try {
51003
- fs10.mkdirSync(path9.dirname(cachePackageJsonPath), { recursive: true });
51174
+ fs10.mkdirSync(path10.dirname(cachePackageJsonPath), { recursive: true });
51004
51175
  fs10.writeFileSync(tmpPath, JSON.stringify(pkgJson, null, 2));
51005
51176
  fs10.renameSync(tmpPath, cachePackageJsonPath);
51006
51177
  return { synced: true, error: null };
@@ -51011,7 +51182,7 @@ function writeCachePackageJson(cachePackageJsonPath, pkgJson) {
51011
51182
  }
51012
51183
  }
51013
51184
  function syncCachePackageJsonToIntent(pluginInfo) {
51014
- const cachePackageJsonPath = path9.join(CACHE_DIR, "package.json");
51185
+ const cachePackageJsonPath = path10.join(CACHE_DIR, "package.json");
51015
51186
  const intentVersion = getIntentVersion(pluginInfo);
51016
51187
  if (!fs10.existsSync(cachePackageJsonPath)) {
51017
51188
  log("[auto-update-checker] Cache package.json missing, creating workspace package.json", { intentVersion });
@@ -51087,7 +51258,7 @@ var init_checker = __esm(() => {
51087
51258
 
51088
51259
  // src/hooks/auto-update-checker/cache.ts
51089
51260
  import * as fs11 from "fs";
51090
- import * as path10 from "path";
51261
+ import * as path11 from "path";
51091
51262
  function stripTrailingCommas(json3) {
51092
51263
  return json3.replace(/,(\s*[}\]])/g, "$1");
51093
51264
  }
@@ -51116,8 +51287,8 @@ function deleteBinaryBunLock(lockPath) {
51116
51287
  }
51117
51288
  }
51118
51289
  function removeFromBunLock(packageName) {
51119
- const textLockPath = path10.join(CACHE_DIR, "bun.lock");
51120
- const binaryLockPath = path10.join(CACHE_DIR, "bun.lockb");
51290
+ const textLockPath = path11.join(CACHE_DIR, "bun.lock");
51291
+ const binaryLockPath = path11.join(CACHE_DIR, "bun.lockb");
51121
51292
  if (fs11.existsSync(textLockPath)) {
51122
51293
  return removeFromTextBunLock(textLockPath, packageName);
51123
51294
  }
@@ -51130,8 +51301,8 @@ function invalidatePackage(packageName = PACKAGE_NAME2) {
51130
51301
  try {
51131
51302
  const userConfigDir = getUserConfigDir();
51132
51303
  const pkgDirs = [
51133
- path10.join(userConfigDir, "node_modules", packageName),
51134
- path10.join(CACHE_DIR, "node_modules", packageName)
51304
+ path11.join(userConfigDir, "node_modules", packageName),
51305
+ path11.join(CACHE_DIR, "node_modules", packageName)
51135
51306
  ];
51136
51307
  let packageRemoved = false;
51137
51308
  let lockRemoved = false;
@@ -51191,8 +51362,8 @@ var init_update_toasts = __esm(() => {
51191
51362
  });
51192
51363
 
51193
51364
  // src/hooks/auto-update-checker/hook/background-update-check.ts
51194
- import { existsSync as existsSync27 } from "fs";
51195
- import { join as join26 } from "path";
51365
+ import { existsSync as existsSync29 } from "fs";
51366
+ import { join as join28 } from "path";
51196
51367
  function getCacheWorkspaceDir(deps) {
51197
51368
  return deps.join(deps.getOpenCodeCacheDir(), "packages");
51198
51369
  }
@@ -51310,8 +51481,8 @@ var init_background_update_check = __esm(() => {
51310
51481
  init_checker();
51311
51482
  init_update_toasts();
51312
51483
  defaultDeps = {
51313
- existsSync: existsSync27,
51314
- join: join26,
51484
+ existsSync: existsSync29,
51485
+ join: join28,
51315
51486
  runBunInstallWithDetails,
51316
51487
  log,
51317
51488
  getOpenCodeCacheDir,
@@ -51464,7 +51635,7 @@ async function showSpinnerToast(ctx, version3, message) {
51464
51635
  duration: frameInterval + 50
51465
51636
  }
51466
51637
  }).catch(() => {});
51467
- await new Promise((resolve2) => setTimeout(resolve2, frameInterval));
51638
+ await new Promise((resolve4) => setTimeout(resolve4, frameInterval));
51468
51639
  }
51469
51640
  }
51470
51641
  var SISYPHUS_SPINNER;
@@ -51604,7 +51775,7 @@ var {
51604
51775
  // package.json
51605
51776
  var package_default = {
51606
51777
  name: "evil-omo",
51607
- version: "3.17.0",
51778
+ version: "3.17.4",
51608
51779
  description: "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
51609
51780
  main: "./dist/index.js",
51610
51781
  types: "dist/index.d.ts",
@@ -51683,17 +51854,17 @@ var package_default = {
51683
51854
  typescript: "^5.7.3"
51684
51855
  },
51685
51856
  optionalDependencies: {
51686
- "evil-omo-darwin-arm64": "3.17.0",
51687
- "evil-omo-darwin-x64": "3.17.0",
51688
- "evil-omo-darwin-x64-baseline": "3.17.0",
51689
- "evil-omo-linux-x64": "3.17.0",
51690
- "evil-omo-linux-x64-baseline": "3.17.0",
51691
- "evil-omo-linux-arm64": "3.17.0",
51692
- "evil-omo-linux-x64-musl": "3.17.0",
51693
- "evil-omo-linux-x64-musl-baseline": "3.17.0",
51694
- "evil-omo-linux-arm64-musl": "3.17.0",
51695
- "evil-omo-windows-x64": "3.17.0",
51696
- "evil-omo-windows-x64-baseline": "3.17.0"
51857
+ "evil-omo-darwin-arm64": "3.17.4",
51858
+ "evil-omo-darwin-x64": "3.17.4",
51859
+ "evil-omo-darwin-x64-baseline": "3.17.4",
51860
+ "evil-omo-linux-x64": "3.17.4",
51861
+ "evil-omo-linux-x64-baseline": "3.17.4",
51862
+ "evil-omo-linux-arm64": "3.17.4",
51863
+ "evil-omo-linux-x64-musl": "3.17.4",
51864
+ "evil-omo-linux-x64-musl-baseline": "3.17.4",
51865
+ "evil-omo-linux-arm64-musl": "3.17.4",
51866
+ "evil-omo-windows-x64": "3.17.4",
51867
+ "evil-omo-windows-x64-baseline": "3.17.4"
51697
51868
  },
51698
51869
  overrides: {},
51699
51870
  trustedDependencies: [
@@ -51738,6 +51909,7 @@ function formatConfigSummary(config) {
51738
51909
  lines.push(formatProvider("OpenCode Zen", config.hasOpencodeZen, "opencode/ models"));
51739
51910
  lines.push(formatProvider("Z.ai Coding Plan", config.hasZaiCodingPlan, "Librarian/Multimodal"));
51740
51911
  lines.push(formatProvider("Kimi For Coding", config.hasKimiForCoding, "Sisyphus/Prometheus fallback"));
51912
+ lines.push(formatProvider("Vercel AI Gateway", config.hasVercelAiGateway, "universal proxy"));
51741
51913
  lines.push("");
51742
51914
  lines.push(import_picocolors.default.dim("\u2500".repeat(40)));
51743
51915
  lines.push("");
@@ -51821,6 +51993,9 @@ function validateNonTuiArgs(args) {
51821
51993
  if (args.kimiForCoding !== undefined && !["no", "yes"].includes(args.kimiForCoding)) {
51822
51994
  errors.push(`Invalid --kimi-for-coding value: ${args.kimiForCoding} (expected: no, yes)`);
51823
51995
  }
51996
+ if (args.vercelAiGateway !== undefined && !["no", "yes"].includes(args.vercelAiGateway)) {
51997
+ errors.push(`Invalid --vercel-ai-gateway value: ${args.vercelAiGateway} (expected: no, yes)`);
51998
+ }
51824
51999
  return { valid: errors.length === 0, errors };
51825
52000
  }
51826
52001
  function argsToConfig(args) {
@@ -51833,7 +52008,8 @@ function argsToConfig(args) {
51833
52008
  hasOpencodeZen: args.opencodeZen === "yes",
51834
52009
  hasZaiCodingPlan: args.zaiCodingPlan === "yes",
51835
52010
  hasKimiForCoding: args.kimiForCoding === "yes",
51836
- hasOpencodeGo: args.opencodeGo === "yes"
52011
+ hasOpencodeGo: args.opencodeGo === "yes",
52012
+ hasVercelAiGateway: args.vercelAiGateway === "yes"
51837
52013
  };
51838
52014
  }
51839
52015
  function detectedToInitialValues(detected) {
@@ -51849,7 +52025,8 @@ function detectedToInitialValues(detected) {
51849
52025
  opencodeZen: detected.hasOpencodeZen ? "yes" : "no",
51850
52026
  zaiCodingPlan: detected.hasZaiCodingPlan ? "yes" : "no",
51851
52027
  kimiForCoding: detected.hasKimiForCoding ? "yes" : "no",
51852
- opencodeGo: detected.hasOpencodeGo ? "yes" : "no"
52028
+ opencodeGo: detected.hasOpencodeGo ? "yes" : "no",
52029
+ vercelAiGateway: detected.hasVercelAiGateway ? "yes" : "no"
51853
52030
  };
51854
52031
  }
51855
52032
 
@@ -51908,7 +52085,7 @@ import os3 from "os";
51908
52085
  import { createHash } from "crypto";
51909
52086
 
51910
52087
  // node_modules/posthog-node/dist/extensions/error-tracking/modifiers/module.node.mjs
51911
- import { dirname as dirname5, posix, sep } from "path";
52088
+ import { dirname as dirname6, posix, sep } from "path";
51912
52089
  function createModulerModifier() {
51913
52090
  const getModuleFromFileName = createGetModuleFromFilename();
51914
52091
  return async (frames) => {
@@ -51917,7 +52094,7 @@ function createModulerModifier() {
51917
52094
  return frames;
51918
52095
  };
51919
52096
  }
51920
- function createGetModuleFromFilename(basePath = process.argv[1] ? dirname5(process.argv[1]) : process.cwd(), isWindows = sep === "\\") {
52097
+ function createGetModuleFromFilename(basePath = process.argv[1] ? dirname6(process.argv[1]) : process.cwd(), isWindows = sep === "\\") {
51921
52098
  const normalizedBase = isWindows ? normalizeWindowsPath(basePath) : basePath;
51922
52099
  return (filename) => {
51923
52100
  if (!filename)
@@ -51939,8 +52116,8 @@ function createGetModuleFromFilename(basePath = process.argv[1] ? dirname5(proce
51939
52116
  return decodedFile;
51940
52117
  };
51941
52118
  }
51942
- function normalizeWindowsPath(path4) {
51943
- return path4.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
52119
+ function normalizeWindowsPath(path5) {
52120
+ return path5.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
51944
52121
  }
51945
52122
 
51946
52123
  // node_modules/@posthog/core/dist/featureFlagUtils.mjs
@@ -54255,15 +54432,15 @@ async function addSourceContext(frames) {
54255
54432
  LRU_FILE_CONTENTS_CACHE.reduce();
54256
54433
  return frames;
54257
54434
  }
54258
- function getContextLinesFromFile(path4, ranges, output) {
54259
- return new Promise((resolve2) => {
54260
- const stream = createReadStream(path4);
54435
+ function getContextLinesFromFile(path5, ranges, output) {
54436
+ return new Promise((resolve4) => {
54437
+ const stream = createReadStream(path5);
54261
54438
  const lineReaded = createInterface({
54262
54439
  input: stream
54263
54440
  });
54264
54441
  function destroyStreamAndResolve() {
54265
54442
  stream.destroy();
54266
- resolve2();
54443
+ resolve4();
54267
54444
  }
54268
54445
  let lineNumber = 0;
54269
54446
  let currentRangeIndex = 0;
@@ -54273,7 +54450,7 @@ function getContextLinesFromFile(path4, ranges, output) {
54273
54450
  let rangeStart = range[0];
54274
54451
  let rangeEnd = range[1];
54275
54452
  function onStreamError() {
54276
- LRU_FILE_CONTENTS_FS_READ_FAILED.set(path4, 1);
54453
+ LRU_FILE_CONTENTS_FS_READ_FAILED.set(path5, 1);
54277
54454
  lineReaded.close();
54278
54455
  lineReaded.removeAllListeners();
54279
54456
  destroyStreamAndResolve();
@@ -54341,8 +54518,8 @@ function clearLineContext(frame) {
54341
54518
  delete frame.context_line;
54342
54519
  delete frame.post_context;
54343
54520
  }
54344
- function shouldSkipContextLinesForFile(path4) {
54345
- return path4.startsWith("node:") || path4.endsWith(".min.js") || path4.endsWith(".min.cjs") || path4.endsWith(".min.mjs") || path4.startsWith("data:");
54521
+ function shouldSkipContextLinesForFile(path5) {
54522
+ return path5.startsWith("node:") || path5.endsWith(".min.js") || path5.endsWith(".min.cjs") || path5.endsWith(".min.mjs") || path5.startsWith("data:");
54346
54523
  }
54347
54524
  function shouldSkipContextLinesForFrame(frame) {
54348
54525
  if (frame.lineno !== undefined && frame.lineno > MAX_CONTEXTLINES_LINENO)
@@ -55503,9 +55680,9 @@ class PostHogBackendClient extends PostHogCoreStateless {
55503
55680
  if (this.disabled || this.optedOut)
55504
55681
  return;
55505
55682
  if (!this._waitUntilCycle) {
55506
- let resolve2;
55683
+ let resolve4;
55507
55684
  const promise = new Promise((r) => {
55508
- resolve2 = r;
55685
+ resolve4 = r;
55509
55686
  });
55510
55687
  try {
55511
55688
  waitUntil(promise);
@@ -55513,7 +55690,7 @@ class PostHogBackendClient extends PostHogCoreStateless {
55513
55690
  return;
55514
55691
  }
55515
55692
  this._waitUntilCycle = {
55516
- resolve: resolve2,
55693
+ resolve: resolve4,
55517
55694
  startedAt: Date.now(),
55518
55695
  timer: undefined
55519
55696
  };
@@ -55539,11 +55716,11 @@ class PostHogBackendClient extends PostHogCoreStateless {
55539
55716
  return cycle?.resolve;
55540
55717
  }
55541
55718
  async resolveWaitUntilFlush() {
55542
- const resolve2 = this._consumeWaitUntilCycle();
55719
+ const resolve4 = this._consumeWaitUntilCycle();
55543
55720
  try {
55544
55721
  await super.flush();
55545
55722
  } catch {} finally {
55546
- resolve2?.();
55723
+ resolve4?.();
55547
55724
  }
55548
55725
  }
55549
55726
  getPersistedProperty(key) {
@@ -55643,15 +55820,15 @@ class PostHogBackendClient extends PostHogCoreStateless {
55643
55820
  return true;
55644
55821
  if (this.featureFlagsPoller === undefined)
55645
55822
  return false;
55646
- return new Promise((resolve2) => {
55823
+ return new Promise((resolve4) => {
55647
55824
  const timeout = setTimeout(() => {
55648
55825
  cleanup();
55649
- resolve2(false);
55826
+ resolve4(false);
55650
55827
  }, timeoutMs);
55651
55828
  const cleanup = this._events.on("localEvaluationFlagsLoaded", (count) => {
55652
55829
  clearTimeout(timeout);
55653
55830
  cleanup();
55654
- resolve2(count > 0);
55831
+ resolve4(count > 0);
55655
55832
  });
55656
55833
  });
55657
55834
  }
@@ -55995,13 +56172,13 @@ class PostHogBackendClient extends PostHogCoreStateless {
55995
56172
  this.context?.enter(data, options);
55996
56173
  }
55997
56174
  async _shutdown(shutdownTimeoutMs) {
55998
- const resolve2 = this._consumeWaitUntilCycle();
56175
+ const resolve4 = this._consumeWaitUntilCycle();
55999
56176
  await this.featureFlagsPoller?.stopPoller(shutdownTimeoutMs);
56000
56177
  this.errorTracking.shutdown();
56001
56178
  try {
56002
56179
  return await super._shutdown(shutdownTimeoutMs);
56003
56180
  } finally {
56004
- resolve2?.();
56181
+ resolve4?.();
56005
56182
  }
56006
56183
  }
56007
56184
  async _requestRemoteConfigPayload(flagKey) {
@@ -56355,11 +56532,11 @@ init_data_path();
56355
56532
  init_logger();
56356
56533
  init_plugin_identity();
56357
56534
  init_write_file_atomically();
56358
- import { existsSync as existsSync16, mkdirSync as mkdirSync6, readFileSync as readFileSync11 } from "fs";
56359
- import { join as join14 } from "path";
56535
+ import { existsSync as existsSync18, mkdirSync as mkdirSync7, readFileSync as readFileSync12 } from "fs";
56536
+ import { join as join16 } from "path";
56360
56537
  var POSTHOG_ACTIVITY_STATE_FILE = "posthog-activity.json";
56361
56538
  function getPostHogActivityStateFilePath() {
56362
- return join14(getDataDir(), CACHE_DIR_NAME, POSTHOG_ACTIVITY_STATE_FILE);
56539
+ return join16(getDataDir(), CACHE_DIR_NAME, POSTHOG_ACTIVITY_STATE_FILE);
56363
56540
  }
56364
56541
  function getUtcDayString(date) {
56365
56542
  return date.toISOString().slice(0, 10);
@@ -56372,11 +56549,11 @@ function isPostHogActivityState(value) {
56372
56549
  }
56373
56550
  function readPostHogActivityState() {
56374
56551
  const stateFilePath = getPostHogActivityStateFilePath();
56375
- if (!existsSync16(stateFilePath)) {
56552
+ if (!existsSync18(stateFilePath)) {
56376
56553
  return {};
56377
56554
  }
56378
56555
  try {
56379
- const content = readFileSync11(stateFilePath, "utf-8");
56556
+ const content = readFileSync12(stateFilePath, "utf-8");
56380
56557
  const parsed = JSON.parse(content);
56381
56558
  if (!isPostHogActivityState(parsed)) {
56382
56559
  return {};
@@ -56393,7 +56570,7 @@ function readPostHogActivityState() {
56393
56570
  function writePostHogActivityState(nextState) {
56394
56571
  const stateFilePath = getPostHogActivityStateFilePath();
56395
56572
  try {
56396
- mkdirSync6(join14(getDataDir(), CACHE_DIR_NAME), { recursive: true });
56573
+ mkdirSync7(join16(getDataDir(), CACHE_DIR_NAME), { recursive: true });
56397
56574
  writeFileAtomically(stateFilePath, `${JSON.stringify(nextState, null, 2)}
56398
56575
  `);
56399
56576
  } catch (error) {
@@ -56465,17 +56642,36 @@ function getSharedProperties(source) {
56465
56642
  plugin_name: PLUGIN_NAME,
56466
56643
  package_version: package_default.version,
56467
56644
  runtime: "bun",
56468
- source
56645
+ runtime_version: process.versions.bun ?? process.version,
56646
+ source,
56647
+ $os: os3.platform(),
56648
+ $os_version: os3.release(),
56649
+ os_arch: os3.arch(),
56650
+ os_type: os3.type(),
56651
+ cpu_count: os3.cpus().length,
56652
+ cpu_model: os3.cpus()[0]?.model,
56653
+ total_memory_gb: Math.round(os3.totalmem() / 1024 / 1024 / 1024),
56654
+ locale: Intl.DateTimeFormat().resolvedOptions().locale,
56655
+ timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
56656
+ shell: process.env.SHELL,
56657
+ ci: Boolean(process.env.CI),
56658
+ terminal: process.env.TERM_PROGRAM
56469
56659
  };
56470
56660
  }
56471
56661
  function createPostHogClient(source, options) {
56472
56662
  if (shouldDisablePostHog() || !hasPostHogApiKey()) {
56473
56663
  return NO_OP_POSTHOG;
56474
56664
  }
56475
- const configuredClient = new PostHog(getPostHogApiKey(), {
56476
- ...options,
56477
- host: getPostHogHost()
56478
- });
56665
+ let configuredClient;
56666
+ try {
56667
+ configuredClient = new PostHog(getPostHogApiKey(), {
56668
+ ...options,
56669
+ host: getPostHogHost(),
56670
+ disableGeoip: false
56671
+ });
56672
+ } catch {
56673
+ return NO_OP_POSTHOG;
56674
+ }
56479
56675
  const sharedProperties = getSharedProperties(source);
56480
56676
  return {
56481
56677
  capture: (message) => {
@@ -56526,7 +56722,7 @@ function getPostHogDistinctId() {
56526
56722
  }
56527
56723
  function createCliPostHog() {
56528
56724
  return createPostHogClient("cli", {
56529
- enableExceptionAutocapture: true,
56725
+ enableExceptionAutocapture: false,
56530
56726
  flushAt: 1,
56531
56727
  flushInterval: 0
56532
56728
  });
@@ -56608,7 +56804,7 @@ async function runCliInstaller(args, version2) {
56608
56804
  if (!config.hasClaude) {
56609
56805
  printInfo("Note: Sisyphus agent performs best with Claude Opus 4.5+. " + "Other models work but may have reduced orchestration quality.");
56610
56806
  }
56611
- if (!config.hasClaude && !config.hasOpenAI && !config.hasGemini && !config.hasCopilot && !config.hasOpencodeZen) {
56807
+ if (!config.hasClaude && !config.hasOpenAI && !config.hasGemini && !config.hasCopilot && !config.hasOpencodeZen && !config.hasVercelAiGateway) {
56612
56808
  printWarning("No model providers configured. Using opencode/big-pickle as fallback.");
56613
56809
  }
56614
56810
  console.log(`${SYMBOLS.star} ${import_picocolors3.default.bold(import_picocolors3.default.green(isUpdate ? "Configuration updated!" : "Installation complete!"))}`);
@@ -57335,6 +57531,16 @@ async function promptInstallConfig(detected) {
57335
57531
  });
57336
57532
  if (!opencodeGo)
57337
57533
  return null;
57534
+ const vercelAiGateway = await selectOrCancel({
57535
+ message: "Do you have a Vercel AI Gateway API key?",
57536
+ options: [
57537
+ { value: "no", label: "No", hint: "Will use other configured providers" },
57538
+ { value: "yes", label: "Yes", hint: "Universal proxy for OpenAI, Anthropic, Google, etc." }
57539
+ ],
57540
+ initialValue: initial.vercelAiGateway
57541
+ });
57542
+ if (!vercelAiGateway)
57543
+ return null;
57338
57544
  return {
57339
57545
  hasClaude: claude !== "no",
57340
57546
  isMax20: claude === "max20",
@@ -57344,7 +57550,8 @@ async function promptInstallConfig(detected) {
57344
57550
  hasOpencodeZen: opencodeZen === "yes",
57345
57551
  hasZaiCodingPlan: zaiCodingPlan === "yes",
57346
57552
  hasKimiForCoding: kimiForCoding === "yes",
57347
- hasOpencodeGo: opencodeGo === "yes"
57553
+ hasOpencodeGo: opencodeGo === "yes",
57554
+ hasVercelAiGateway: vercelAiGateway === "yes"
57348
57555
  };
57349
57556
  }
57350
57557
 
@@ -57401,7 +57608,7 @@ async function runTuiInstaller(args, version2) {
57401
57608
  M2.info(`${import_picocolors5.default.bold("Note:")} Sisyphus agent performs best with Claude Opus 4.5+.
57402
57609
  ` + `Other models work but may have reduced orchestration quality.`);
57403
57610
  }
57404
- if (!config.hasClaude && !config.hasOpenAI && !config.hasGemini && !config.hasCopilot && !config.hasOpencodeZen) {
57611
+ if (!config.hasClaude && !config.hasOpenAI && !config.hasGemini && !config.hasCopilot && !config.hasOpencodeZen && !config.hasVercelAiGateway) {
57405
57612
  M2.warn("No model providers configured. Using opencode/big-pickle as fallback.");
57406
57613
  }
57407
57614
  Me(formatConfigSummary(config), isUpdate ? "Updated Configuration" : "Installation Complete");
@@ -57627,10 +57834,10 @@ function formatToolHeader(toolName, input) {
57627
57834
  };
57628
57835
  }
57629
57836
  if (toolName === "list") {
57630
- const path4 = str2(input.path);
57837
+ const path5 = str2(input.path);
57631
57838
  return {
57632
57839
  icon: "\u2192",
57633
- title: path4 ? `List ${path4}` : "List"
57840
+ title: path5 ? `List ${path5}` : "List"
57634
57841
  };
57635
57842
  }
57636
57843
  if (toolName === "read") {
@@ -58139,7 +58346,7 @@ async function processEvents(ctx, stream, state) {
58139
58346
  }
58140
58347
  // src/plugin-config.ts
58141
58348
  import * as fs4 from "fs";
58142
- import * as path4 from "path";
58349
+ import * as path5 from "path";
58143
58350
 
58144
58351
  // node_modules/zod/v4/classic/external.js
58145
58352
  var exports_external = {};
@@ -58906,10 +59113,10 @@ function mergeDefs(...defs) {
58906
59113
  function cloneDef(schema2) {
58907
59114
  return mergeDefs(schema2._zod.def);
58908
59115
  }
58909
- function getElementAtPath(obj, path4) {
58910
- if (!path4)
59116
+ function getElementAtPath(obj, path5) {
59117
+ if (!path5)
58911
59118
  return obj;
58912
- return path4.reduce((acc, key) => acc?.[key], obj);
59119
+ return path5.reduce((acc, key) => acc?.[key], obj);
58913
59120
  }
58914
59121
  function promiseAllObject(promisesObj) {
58915
59122
  const keys = Object.keys(promisesObj);
@@ -59290,11 +59497,11 @@ function aborted(x2, startIndex = 0) {
59290
59497
  }
59291
59498
  return false;
59292
59499
  }
59293
- function prefixIssues(path4, issues) {
59500
+ function prefixIssues(path5, issues) {
59294
59501
  return issues.map((iss) => {
59295
59502
  var _a;
59296
59503
  (_a = iss).path ?? (_a.path = []);
59297
- iss.path.unshift(path4);
59504
+ iss.path.unshift(path5);
59298
59505
  return iss;
59299
59506
  });
59300
59507
  }
@@ -59477,7 +59684,7 @@ function formatError2(error, mapper = (issue2) => issue2.message) {
59477
59684
  }
59478
59685
  function treeifyError(error, mapper = (issue2) => issue2.message) {
59479
59686
  const result = { errors: [] };
59480
- const processError = (error2, path4 = []) => {
59687
+ const processError = (error2, path5 = []) => {
59481
59688
  var _a, _b;
59482
59689
  for (const issue2 of error2.issues) {
59483
59690
  if (issue2.code === "invalid_union" && issue2.errors.length) {
@@ -59487,7 +59694,7 @@ function treeifyError(error, mapper = (issue2) => issue2.message) {
59487
59694
  } else if (issue2.code === "invalid_element") {
59488
59695
  processError({ issues: issue2.issues }, issue2.path);
59489
59696
  } else {
59490
- const fullpath = [...path4, ...issue2.path];
59697
+ const fullpath = [...path5, ...issue2.path];
59491
59698
  if (fullpath.length === 0) {
59492
59699
  result.errors.push(mapper(issue2));
59493
59700
  continue;
@@ -59519,8 +59726,8 @@ function treeifyError(error, mapper = (issue2) => issue2.message) {
59519
59726
  }
59520
59727
  function toDotPath(_path) {
59521
59728
  const segs = [];
59522
- const path4 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
59523
- for (const seg of path4) {
59729
+ const path5 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
59730
+ for (const seg of path5) {
59524
59731
  if (typeof seg === "number")
59525
59732
  segs.push(`[${seg}]`);
59526
59733
  else if (typeof seg === "symbol")
@@ -71267,13 +71474,13 @@ function resolveRef(ref, ctx) {
71267
71474
  if (!ref.startsWith("#")) {
71268
71475
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
71269
71476
  }
71270
- const path4 = ref.slice(1).split("/").filter(Boolean);
71271
- if (path4.length === 0) {
71477
+ const path5 = ref.slice(1).split("/").filter(Boolean);
71478
+ if (path5.length === 0) {
71272
71479
  return ctx.rootSchema;
71273
71480
  }
71274
71481
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
71275
- if (path4[0] === defsKey) {
71276
- const key = path4[1];
71482
+ if (path5[0] === defsKey) {
71483
+ const key = path5[1];
71277
71484
  if (!key || !ctx.defs[key]) {
71278
71485
  throw new Error(`Reference not found: ${ref}`);
71279
71486
  }
@@ -72053,6 +72260,10 @@ var OpenClawConfigSchema = exports_external.object({
72053
72260
  hooks: exports_external.record(exports_external.string(), OpenClawHookSchema).default({}),
72054
72261
  replyListener: OpenClawReplyListenerConfigSchema.optional()
72055
72262
  });
72263
+ // src/config/schema/agent-definitions.ts
72264
+ var AgentDefinitionPathSchema = exports_external.string().min(1);
72265
+ var AgentDefinitionsConfigSchema = exports_external.array(AgentDefinitionPathSchema).optional();
72266
+
72056
72267
  // src/config/schema/ralph-loop.ts
72057
72268
  var RalphLoopConfigSchema = exports_external.object({
72058
72269
  enabled: exports_external.boolean().default(false),
@@ -72166,9 +72377,10 @@ var OhMyOpenCodeConfigSchema = exports_external.object({
72166
72377
  $schema: exports_external.string().optional(),
72167
72378
  new_task_system_enabled: exports_external.boolean().optional(),
72168
72379
  default_run_agent: exports_external.string().optional(),
72380
+ agent_definitions: AgentDefinitionsConfigSchema,
72169
72381
  disabled_mcps: exports_external.array(AnyMcpNameSchema).optional(),
72170
72382
  disabled_agents: StringListSchema.optional(),
72171
- disabled_skills: StringListSchema.optional(),
72383
+ disabled_skills: exports_external.array(BuiltinSkillNameSchema).optional(),
72172
72384
  disabled_hooks: StringListSchema.optional(),
72173
72385
  disabled_commands: exports_external.array(BuiltinCommandNameSchema).optional(),
72174
72386
  disabled_tools: StringListSchema.optional(),
@@ -72189,7 +72401,11 @@ var OhMyOpenCodeConfigSchema = exports_external.object({
72189
72401
  model_capabilities: ModelCapabilitiesConfigSchema.optional(),
72190
72402
  openclaw: OpenClawConfigSchema.optional(),
72191
72403
  babysitting: BabysittingConfigSchema.optional(),
72192
- git_master: GitMasterConfigSchema.optional(),
72404
+ git_master: GitMasterConfigSchema.default({
72405
+ commit_footer: true,
72406
+ include_co_authored_by: true,
72407
+ git_env_prefix: "GIT_MASTER=1"
72408
+ }),
72193
72409
  browser_automation_engine: BrowserAutomationConfigSchema.optional(),
72194
72410
  websearch: WebsearchConfigSchema.optional(),
72195
72411
  tmux: TmuxConfigSchema.optional(),
@@ -72202,6 +72418,22 @@ var OhMyOpenCodeConfigSchema = exports_external.object({
72202
72418
  init_shared();
72203
72419
  init_migrate_legacy_config_file();
72204
72420
  init_plugin_identity();
72421
+ function loadExplicitGitMasterOverrides(configPath) {
72422
+ try {
72423
+ if (!fs4.existsSync(configPath)) {
72424
+ return;
72425
+ }
72426
+ const content = fs4.readFileSync(configPath, "utf-8");
72427
+ const rawConfig = parseJsonc(content);
72428
+ const gitMaster = rawConfig.git_master;
72429
+ if (gitMaster && typeof gitMaster === "object" && !Array.isArray(gitMaster)) {
72430
+ return gitMaster;
72431
+ }
72432
+ } catch {
72433
+ return;
72434
+ }
72435
+ return;
72436
+ }
72205
72437
  var PARTIAL_STRING_ARRAY_KEYS = new Set([
72206
72438
  "disabled_mcps",
72207
72439
  "disabled_agents",
@@ -72209,7 +72441,8 @@ var PARTIAL_STRING_ARRAY_KEYS = new Set([
72209
72441
  "disabled_hooks",
72210
72442
  "disabled_commands",
72211
72443
  "disabled_tools",
72212
- "mcp_env_allowlist"
72444
+ "mcp_env_allowlist",
72445
+ "agent_definitions"
72213
72446
  ]);
72214
72447
  function parseConfigPartially(rawConfig) {
72215
72448
  const fullResult = OhMyOpenCodeConfigSchema.safeParse(rawConfig);
@@ -72281,6 +72514,12 @@ function mergeConfigs(base, override) {
72281
72514
  ...override,
72282
72515
  agents: deepMerge(base.agents, override.agents),
72283
72516
  categories: deepMerge(base.categories, override.categories),
72517
+ agent_definitions: [
72518
+ ...new Set([
72519
+ ...base.agent_definitions ?? [],
72520
+ ...override.agent_definitions ?? []
72521
+ ])
72522
+ ],
72284
72523
  disabled_agents: [
72285
72524
  ...new Set([
72286
72525
  ...base.disabled_agents ?? [],
@@ -72329,42 +72568,61 @@ function mergeConfigs(base, override) {
72329
72568
  function loadPluginConfig(directory, ctx) {
72330
72569
  const configDir = getOpenCodeConfigDir({ binary: "opencode" });
72331
72570
  const userDetected = detectPluginConfigFile(configDir);
72332
- let userConfigPath = userDetected.format !== "none" ? userDetected.path : path4.join(configDir, `${CONFIG_BASENAME}.json`);
72571
+ let userConfigPath = userDetected.format !== "none" ? userDetected.path : path5.join(configDir, `${CONFIG_BASENAME}.json`);
72333
72572
  if (userDetected.legacyPath) {
72334
72573
  log("Canonical plugin config detected alongside legacy config. Remove the legacy file to avoid confusion.", {
72335
72574
  canonicalPath: userDetected.path,
72336
72575
  legacyPath: userDetected.legacyPath
72337
72576
  });
72338
72577
  }
72339
- if (userDetected.format !== "none" && path4.basename(userDetected.path).startsWith(LEGACY_CONFIG_BASENAME)) {
72578
+ if (userDetected.format !== "none" && path5.basename(userDetected.path).startsWith(LEGACY_CONFIG_BASENAME)) {
72340
72579
  const migrated = migrateLegacyConfigFile(userDetected.path);
72341
- const canonicalPath = path4.join(path4.dirname(userDetected.path), `${CONFIG_BASENAME}${path4.extname(userDetected.path)}`);
72580
+ const canonicalPath = path5.join(path5.dirname(userDetected.path), `${CONFIG_BASENAME}${path5.extname(userDetected.path)}`);
72342
72581
  if (migrated || fs4.existsSync(canonicalPath)) {
72343
72582
  userConfigPath = canonicalPath;
72344
72583
  }
72345
72584
  }
72346
- const projectBasePath = path4.join(directory, ".opencode");
72585
+ const projectBasePath = path5.join(directory, ".opencode");
72347
72586
  const projectDetected = detectPluginConfigFile(projectBasePath);
72348
- let projectConfigPath = projectDetected.format !== "none" ? projectDetected.path : path4.join(projectBasePath, `${CONFIG_BASENAME}.json`);
72587
+ let projectConfigPath = projectDetected.format !== "none" ? projectDetected.path : path5.join(projectBasePath, `${CONFIG_BASENAME}.json`);
72349
72588
  if (projectDetected.legacyPath) {
72350
72589
  log("Canonical plugin config detected alongside legacy config. Remove the legacy file to avoid confusion.", {
72351
72590
  canonicalPath: projectDetected.path,
72352
72591
  legacyPath: projectDetected.legacyPath
72353
72592
  });
72354
72593
  }
72355
- if (projectDetected.format !== "none" && path4.basename(projectDetected.path).startsWith(LEGACY_CONFIG_BASENAME)) {
72594
+ if (projectDetected.format !== "none" && path5.basename(projectDetected.path).startsWith(LEGACY_CONFIG_BASENAME)) {
72356
72595
  const projectMigrated = migrateLegacyConfigFile(projectDetected.path);
72357
- const canonicalProjectPath = path4.join(path4.dirname(projectDetected.path), `${CONFIG_BASENAME}${path4.extname(projectDetected.path)}`);
72596
+ const canonicalProjectPath = path5.join(path5.dirname(projectDetected.path), `${CONFIG_BASENAME}${path5.extname(projectDetected.path)}`);
72358
72597
  if (projectMigrated || fs4.existsSync(canonicalProjectPath)) {
72359
72598
  projectConfigPath = canonicalProjectPath;
72360
72599
  }
72361
72600
  }
72362
72601
  const userConfig = loadConfigFromPath(userConfigPath, ctx);
72602
+ const userGitMasterOverrides = loadExplicitGitMasterOverrides(userConfigPath);
72603
+ if (userConfig?.agent_definitions) {
72604
+ userConfig.agent_definitions = resolveAgentDefinitionPaths(userConfig.agent_definitions, configDir, null);
72605
+ }
72363
72606
  let config2 = userConfig ?? OhMyOpenCodeConfigSchema.parse({});
72607
+ const defaultGitMaster = OhMyOpenCodeConfigSchema.parse({}).git_master;
72364
72608
  const projectConfig = loadConfigFromPath(projectConfigPath, ctx);
72609
+ const projectGitMasterOverrides = loadExplicitGitMasterOverrides(projectConfigPath);
72610
+ if (projectConfig?.agent_definitions) {
72611
+ projectConfig.agent_definitions = resolveAgentDefinitionPaths(projectConfig.agent_definitions, projectBasePath, directory);
72612
+ }
72365
72613
  if (projectConfig) {
72366
72614
  config2 = mergeConfigs(config2, projectConfig);
72367
72615
  }
72616
+ if (userGitMasterOverrides || projectGitMasterOverrides) {
72617
+ config2 = {
72618
+ ...config2,
72619
+ git_master: {
72620
+ ...defaultGitMaster,
72621
+ ...userGitMasterOverrides ?? {},
72622
+ ...projectGitMasterOverrides ?? {}
72623
+ }
72624
+ };
72625
+ }
72368
72626
  config2 = {
72369
72627
  ...config2,
72370
72628
  mcp_env_allowlist: userConfig?.mcp_env_allowlist ?? []
@@ -72381,7 +72639,7 @@ function loadPluginConfig(directory, ctx) {
72381
72639
  // node_modules/@opencode-ai/sdk/dist/gen/core/serverSentEvents.gen.js
72382
72640
  var createSseClient = ({ onSseError, onSseEvent, responseTransformer, responseValidator, sseDefaultRetryDelay, sseMaxRetryAttempts, sseMaxRetryDelay, sseSleepFn, url: url2, ...options }) => {
72383
72641
  let lastEventId;
72384
- const sleep = sseSleepFn ?? ((ms) => new Promise((resolve2) => setTimeout(resolve2, ms)));
72642
+ const sleep = sseSleepFn ?? ((ms) => new Promise((resolve4) => setTimeout(resolve4, ms)));
72385
72643
  const createStream = async function* () {
72386
72644
  let retryDelay = sseDefaultRetryDelay ?? 3000;
72387
72645
  let attempt = 0;
@@ -72612,7 +72870,7 @@ var serializeObjectParam = ({ allowReserved, explode, name, style, value, valueO
72612
72870
 
72613
72871
  // node_modules/@opencode-ai/sdk/dist/gen/core/utils.gen.js
72614
72872
  var PATH_PARAM_RE = /\{[^{}]+\}/g;
72615
- var defaultPathSerializer = ({ path: path5, url: _url2 }) => {
72873
+ var defaultPathSerializer = ({ path: path6, url: _url2 }) => {
72616
72874
  let url2 = _url2;
72617
72875
  const matches = _url2.match(PATH_PARAM_RE);
72618
72876
  if (matches) {
@@ -72631,7 +72889,7 @@ var defaultPathSerializer = ({ path: path5, url: _url2 }) => {
72631
72889
  name = name.substring(1);
72632
72890
  style = "matrix";
72633
72891
  }
72634
- const value = path5[name];
72892
+ const value = path6[name];
72635
72893
  if (value === undefined || value === null) {
72636
72894
  continue;
72637
72895
  }
@@ -72662,11 +72920,11 @@ var defaultPathSerializer = ({ path: path5, url: _url2 }) => {
72662
72920
  }
72663
72921
  return url2;
72664
72922
  };
72665
- var getUrl = ({ baseUrl, path: path5, query, querySerializer, url: _url2 }) => {
72923
+ var getUrl = ({ baseUrl, path: path6, query, querySerializer, url: _url2 }) => {
72666
72924
  const pathUrl = _url2.startsWith("/") ? _url2 : `/${_url2}`;
72667
72925
  let url2 = (baseUrl ?? "") + pathUrl;
72668
- if (path5) {
72669
- url2 = defaultPathSerializer({ path: path5, url: url2 });
72926
+ if (path6) {
72927
+ url2 = defaultPathSerializer({ path: path6, url: url2 });
72670
72928
  }
72671
72929
  let search = query ? querySerializer(query) : "";
72672
72930
  if (search.startsWith("?")) {
@@ -73816,7 +74074,7 @@ async function createOpencodeServer(options) {
73816
74074
  }
73817
74075
  });
73818
74076
  let clear = () => {};
73819
- const url2 = await new Promise((resolve2, reject) => {
74077
+ const url2 = await new Promise((resolve4, reject) => {
73820
74078
  const id = setTimeout(() => {
73821
74079
  clear();
73822
74080
  stop(proc);
@@ -73842,7 +74100,7 @@ async function createOpencodeServer(options) {
73842
74100
  }
73843
74101
  clearTimeout(id);
73844
74102
  resolved = true;
73845
- resolve2(match[1]);
74103
+ resolve4(match[1]);
73846
74104
  return;
73847
74105
  }
73848
74106
  }
@@ -73896,7 +74154,7 @@ var import_picocolors10 = __toESM(require_picocolors(), 1);
73896
74154
 
73897
74155
  // src/cli/run/opencode-binary-resolver.ts
73898
74156
  init_spawn_with_windows_hide();
73899
- import { delimiter, dirname as dirname7, join as join16 } from "path";
74157
+ import { delimiter, dirname as dirname8, join as join18 } from "path";
73900
74158
  var OPENCODE_COMMANDS = ["opencode", "opencode-desktop"];
73901
74159
  var WINDOWS_SUFFIXES = ["", ".exe", ".cmd", ".bat", ".ps1"];
73902
74160
  function getCommandCandidates(platform) {
@@ -73919,7 +74177,7 @@ function collectCandidateBinaryPaths(pathEnv, which = Bun.which, platform = proc
73919
74177
  }
73920
74178
  for (const entry of (pathEnv ?? "").split(delimiter).filter(Boolean)) {
73921
74179
  for (const command of commandCandidates) {
73922
- addCandidate(join16(entry, command));
74180
+ addCandidate(join18(entry, command));
73923
74181
  }
73924
74182
  }
73925
74183
  return candidates;
@@ -73946,7 +74204,7 @@ async function findWorkingOpencodeBinary(pathEnv = process.env.PATH, probe = can
73946
74204
  return null;
73947
74205
  }
73948
74206
  function buildPathWithBinaryFirst(pathEnv, binaryPath) {
73949
- const preferredDir = dirname7(binaryPath);
74207
+ const preferredDir = dirname8(binaryPath);
73950
74208
  const existing = (pathEnv ?? "").split(delimiter).filter((entry) => entry.length > 0 && entry !== preferredDir);
73951
74209
  return [preferredDir, ...existing].join(delimiter);
73952
74210
  }
@@ -74084,7 +74342,7 @@ async function resolveSession(options) {
74084
74342
  if (attempt < SESSION_CREATE_MAX_RETRIES) {
74085
74343
  const delay = SESSION_CREATE_RETRY_DELAY_MS * attempt;
74086
74344
  console.log(import_picocolors11.default.dim(` Retrying in ${delay}ms...`));
74087
- await new Promise((resolve2) => setTimeout(resolve2, delay));
74345
+ await new Promise((resolve4) => setTimeout(resolve4, delay));
74088
74346
  }
74089
74347
  continue;
74090
74348
  }
@@ -74095,7 +74353,7 @@ async function resolveSession(options) {
74095
74353
  if (attempt < SESSION_CREATE_MAX_RETRIES) {
74096
74354
  const delay = SESSION_CREATE_RETRY_DELAY_MS * attempt;
74097
74355
  console.log(import_picocolors11.default.dim(` Retrying in ${delay}ms...`));
74098
- await new Promise((resolve2) => setTimeout(resolve2, delay));
74356
+ await new Promise((resolve4) => setTimeout(resolve4, delay));
74099
74357
  }
74100
74358
  }
74101
74359
  throw new Error("Failed to create session after all retries");
@@ -74224,10 +74482,11 @@ var normalizeAgentName = (agent) => {
74224
74482
  return;
74225
74483
  const configKey = getAgentConfigKey(trimmed);
74226
74484
  const displayName = getAgentDisplayName(configKey);
74485
+ const runtimeName = getAgentRuntimeName(configKey);
74227
74486
  const isKnownAgent = displayName !== configKey;
74228
74487
  return {
74229
74488
  configKey,
74230
- resolvedName: isKnownAgent ? displayName : trimmed
74489
+ resolvedName: isKnownAgent ? runtimeName : trimmed
74231
74490
  };
74232
74491
  };
74233
74492
  var isAgentDisabled = (agentConfigKey, config2) => {
@@ -74251,18 +74510,19 @@ var resolveRunAgent = (options, pluginConfig, env = process.env) => {
74251
74510
  const configAgent = normalizeAgentName(pluginConfig.default_run_agent);
74252
74511
  const resolved = cliAgent ?? envAgent ?? configAgent ?? {
74253
74512
  configKey: DEFAULT_AGENT,
74254
- resolvedName: getAgentDisplayName(DEFAULT_AGENT)
74513
+ resolvedName: getAgentRuntimeName(DEFAULT_AGENT)
74255
74514
  };
74256
74515
  if (isAgentDisabled(resolved.configKey, pluginConfig)) {
74257
74516
  const fallback = pickFallbackAgent(pluginConfig);
74258
- const fallbackName = getAgentDisplayName(fallback);
74517
+ const fallbackDisplayName = getAgentDisplayName(fallback);
74518
+ const fallbackRuntimeName = getAgentRuntimeName(fallback);
74259
74519
  const fallbackDisabled = isAgentDisabled(fallback, pluginConfig);
74260
74520
  if (fallbackDisabled) {
74261
- console.log(import_picocolors12.default.yellow(`Requested agent "${resolved.resolvedName}" is disabled and no enabled core agent was found. Proceeding with "${fallbackName}".`));
74262
- return fallbackName;
74521
+ console.log(import_picocolors12.default.yellow(`Requested agent "${resolved.resolvedName}" is disabled and no enabled core agent was found. Proceeding with "${fallbackDisplayName}".`));
74522
+ return fallbackRuntimeName;
74263
74523
  }
74264
- console.log(import_picocolors12.default.yellow(`Requested agent "${resolved.resolvedName}" is disabled. Falling back to "${fallbackName}".`));
74265
- return fallbackName;
74524
+ console.log(import_picocolors12.default.yellow(`Requested agent "${resolved.resolvedName}" is disabled. Falling back to "${fallbackDisplayName}".`));
74525
+ return fallbackRuntimeName;
74266
74526
  }
74267
74527
  return resolved.resolvedName;
74268
74528
  };
@@ -74304,19 +74564,19 @@ var BOULDER_STATE_PATH = `${BOULDER_DIR}/${BOULDER_FILE}`;
74304
74564
  var NOTEPAD_DIR = "notepads";
74305
74565
  var NOTEPAD_BASE_PATH = `${BOULDER_DIR}/${NOTEPAD_DIR}`;
74306
74566
  // src/features/boulder-state/storage.ts
74307
- import { existsSync as existsSync18, readFileSync as readFileSync13, writeFileSync as writeFileSync5, mkdirSync as mkdirSync7, readdirSync as readdirSync3 } from "fs";
74308
- import { dirname as dirname8, join as join17, basename as basename4 } from "path";
74567
+ import { existsSync as existsSync20, readFileSync as readFileSync14, writeFileSync as writeFileSync5, mkdirSync as mkdirSync8, readdirSync as readdirSync3 } from "fs";
74568
+ import { dirname as dirname9, join as join19, basename as basename5 } from "path";
74309
74569
  var RESERVED_KEYS = new Set(["__proto__", "prototype", "constructor"]);
74310
74570
  function getBoulderFilePath(directory) {
74311
- return join17(directory, BOULDER_DIR, BOULDER_FILE);
74571
+ return join19(directory, BOULDER_DIR, BOULDER_FILE);
74312
74572
  }
74313
74573
  function readBoulderState(directory) {
74314
74574
  const filePath = getBoulderFilePath(directory);
74315
- if (!existsSync18(filePath)) {
74575
+ if (!existsSync20(filePath)) {
74316
74576
  return null;
74317
74577
  }
74318
74578
  try {
74319
- const content = readFileSync13(filePath, "utf-8");
74579
+ const content = readFileSync14(filePath, "utf-8");
74320
74580
  const parsed = JSON.parse(content);
74321
74581
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
74322
74582
  return null;
@@ -74349,11 +74609,11 @@ var CHECKED_CHECKBOX_PATTERN = /^(\s*)[-*]\s*\[[xX]\]\s*(.+)$/;
74349
74609
  var TODO_TASK_PATTERN = /^\d+\.\s+/;
74350
74610
  var FINAL_WAVE_TASK_PATTERN = /^F\d+\.\s+/i;
74351
74611
  function getPlanProgress(planPath) {
74352
- if (!existsSync18(planPath)) {
74612
+ if (!existsSync20(planPath)) {
74353
74613
  return { total: 0, completed: 0, isComplete: true };
74354
74614
  }
74355
74615
  try {
74356
- const content = readFileSync13(planPath, "utf-8");
74616
+ const content = readFileSync14(planPath, "utf-8");
74357
74617
  const lines = content.split(/\r?\n/);
74358
74618
  const hasStructuredSections = lines.some((line) => TODO_HEADING_PATTERN.test(line) || FINAL_VERIFICATION_HEADING_PATTERN.test(line));
74359
74619
  if (hasStructuredSections) {
@@ -74425,17 +74685,17 @@ function getSessionAgent(sessionID) {
74425
74685
  // src/features/run-continuation-state/constants.ts
74426
74686
  var CONTINUATION_MARKER_DIR = ".sisyphus/run-continuation";
74427
74687
  // src/features/run-continuation-state/storage.ts
74428
- import { existsSync as existsSync19, mkdirSync as mkdirSync8, readFileSync as readFileSync14, rmSync as rmSync2, writeFileSync as writeFileSync6 } from "fs";
74429
- import { join as join18 } from "path";
74688
+ import { existsSync as existsSync21, mkdirSync as mkdirSync9, readFileSync as readFileSync15, rmSync as rmSync2, writeFileSync as writeFileSync6 } from "fs";
74689
+ import { join as join20 } from "path";
74430
74690
  function getMarkerPath(directory, sessionID) {
74431
- return join18(directory, CONTINUATION_MARKER_DIR, `${sessionID}.json`);
74691
+ return join20(directory, CONTINUATION_MARKER_DIR, `${sessionID}.json`);
74432
74692
  }
74433
74693
  function readContinuationMarker(directory, sessionID) {
74434
74694
  const markerPath = getMarkerPath(directory, sessionID);
74435
- if (!existsSync19(markerPath))
74695
+ if (!existsSync21(markerPath))
74436
74696
  return null;
74437
74697
  try {
74438
- const raw = readFileSync14(markerPath, "utf-8");
74698
+ const raw = readFileSync15(markerPath, "utf-8");
74439
74699
  const parsed = JSON.parse(raw);
74440
74700
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
74441
74701
  return null;
@@ -74496,8 +74756,8 @@ async function isSessionInBoulderLineage(input) {
74496
74756
  // src/hooks/atlas/session-last-agent.ts
74497
74757
  init_shared();
74498
74758
  init_compaction_marker();
74499
- import { readFileSync as readFileSync15, readdirSync as readdirSync4 } from "fs";
74500
- import { join as join19 } from "path";
74759
+ import { readFileSync as readFileSync16, readdirSync as readdirSync4 } from "fs";
74760
+ import { join as join21 } from "path";
74501
74761
  var defaultSessionLastAgentDeps = {
74502
74762
  getMessageDir,
74503
74763
  isSqliteBackend,
@@ -74545,7 +74805,7 @@ async function getLastAgentFromSession(sessionID, client3, deps = {}) {
74545
74805
  try {
74546
74806
  const messages = readdirSync4(messageDir).filter((fileName) => fileName.endsWith(".json")).map((fileName) => {
74547
74807
  try {
74548
- const content = readFileSync15(join19(messageDir, fileName), "utf-8");
74808
+ const content = readFileSync16(join21(messageDir, fileName), "utf-8");
74549
74809
  const parsed = JSON.parse(content);
74550
74810
  return {
74551
74811
  fileName,
@@ -74578,8 +74838,8 @@ init_agent_display_names();
74578
74838
 
74579
74839
  // src/hooks/ralph-loop/storage.ts
74580
74840
  init_frontmatter();
74581
- import { existsSync as existsSync20, readFileSync as readFileSync16, writeFileSync as writeFileSync7, unlinkSync, mkdirSync as mkdirSync9 } from "fs";
74582
- import { dirname as dirname9, join as join20 } from "path";
74841
+ import { existsSync as existsSync22, readFileSync as readFileSync17, writeFileSync as writeFileSync7, unlinkSync as unlinkSync3, mkdirSync as mkdirSync10 } from "fs";
74842
+ import { dirname as dirname10, join as join22 } from "path";
74583
74843
 
74584
74844
  // src/hooks/ralph-loop/constants.ts
74585
74845
  var DEFAULT_STATE_FILE = ".sisyphus/ralph-loop.local.md";
@@ -74588,15 +74848,15 @@ var DEFAULT_COMPLETION_PROMISE = "DONE";
74588
74848
 
74589
74849
  // src/hooks/ralph-loop/storage.ts
74590
74850
  function getStateFilePath(directory, customPath) {
74591
- return customPath ? join20(directory, customPath) : join20(directory, DEFAULT_STATE_FILE);
74851
+ return customPath ? join22(directory, customPath) : join22(directory, DEFAULT_STATE_FILE);
74592
74852
  }
74593
74853
  function readState(directory, customPath) {
74594
74854
  const filePath = getStateFilePath(directory, customPath);
74595
- if (!existsSync20(filePath)) {
74855
+ if (!existsSync22(filePath)) {
74596
74856
  return null;
74597
74857
  }
74598
74858
  try {
74599
- const content = readFileSync16(filePath, "utf-8");
74859
+ const content = readFileSync17(filePath, "utf-8");
74600
74860
  const { data, body } = parseFrontmatter(content);
74601
74861
  const active = data.active;
74602
74862
  const iteration = data.iteration;
@@ -74805,7 +75065,7 @@ async function pollForCompletion(ctx, eventState, abortController, options = {})
74805
75065
  let secondaryTimeoutChecked = false;
74806
75066
  const pollStartTimestamp = Date.now();
74807
75067
  while (!abortController.signal.aborted) {
74808
- await new Promise((resolve2) => setTimeout(resolve2, pollIntervalMs));
75068
+ await new Promise((resolve4) => setTimeout(resolve4, pollIntervalMs));
74809
75069
  if (abortController.signal.aborted) {
74810
75070
  return 130;
74811
75071
  }
@@ -74912,6 +75172,9 @@ async function getMainSessionStatus(ctx) {
74912
75172
  query: { directory: ctx.directory }
74913
75173
  });
74914
75174
  const statuses = normalizeSDKResponse(statusesRes, {});
75175
+ if (!(ctx.sessionID in statuses)) {
75176
+ return "idle";
75177
+ }
74915
75178
  const status = statuses[ctx.sessionID]?.type;
74916
75179
  if (status === "idle" || status === "busy" || status === "retry") {
74917
75180
  return status;
@@ -75033,7 +75296,7 @@ var EVENT_PROCESSOR_SHUTDOWN_TIMEOUT_MS = 2000;
75033
75296
  async function waitForEventProcessorShutdown(eventProcessor, timeoutMs = EVENT_PROCESSOR_SHUTDOWN_TIMEOUT_MS) {
75034
75297
  const completed = await Promise.race([
75035
75298
  eventProcessor.then(() => true),
75036
- new Promise((resolve2) => setTimeout(() => resolve2(false), timeoutMs))
75299
+ new Promise((resolve4) => setTimeout(() => resolve4(false), timeoutMs))
75037
75300
  ]);
75038
75301
  }
75039
75302
  async function run(options) {
@@ -75361,30 +75624,61 @@ async function getLocalVersion(options = {}) {
75361
75624
  }
75362
75625
  }
75363
75626
  // src/cli/doctor/checks/system.ts
75364
- import { existsSync as existsSync31, readFileSync as readFileSync26 } from "fs";
75627
+ import { existsSync as existsSync33, readFileSync as readFileSync27 } from "fs";
75365
75628
 
75366
75629
  // src/cli/doctor/checks/system-binary.ts
75630
+ import { existsSync as existsSync30 } from "fs";
75631
+ import { homedir as homedir6 } from "os";
75632
+ import { join as join29 } from "path";
75633
+
75634
+ // src/cli/doctor/spawn-with-timeout.ts
75367
75635
  init_spawn_with_windows_hide();
75368
- import { existsSync as existsSync28 } from "fs";
75369
- import { homedir as homedir5 } from "os";
75370
- import { join as join27 } from "path";
75636
+ var DEFAULT_SPAWN_TIMEOUT_MS = 1e4;
75637
+ async function spawnWithTimeout(command, options, timeoutMs = DEFAULT_SPAWN_TIMEOUT_MS) {
75638
+ let proc;
75639
+ try {
75640
+ proc = spawnWithWindowsHide(command, options);
75641
+ } catch {
75642
+ return { stdout: "", stderr: "", exitCode: 1, timedOut: false };
75643
+ }
75644
+ let timer;
75645
+ const timeoutPromise = new Promise((resolve4) => {
75646
+ timer = setTimeout(() => resolve4("timeout"), timeoutMs);
75647
+ });
75648
+ const processPromise = (async () => {
75649
+ await proc.exited;
75650
+ return "done";
75651
+ })();
75652
+ const race = await Promise.race([processPromise, timeoutPromise]);
75653
+ if (race === "timeout") {
75654
+ proc.kill("SIGTERM");
75655
+ await proc.exited.catch(() => {});
75656
+ return { stdout: "", stderr: "", exitCode: 1, timedOut: true };
75657
+ }
75658
+ clearTimeout(timer);
75659
+ const stdout = proc.stdout ? await new Response(proc.stdout).text() : "";
75660
+ const stderr = proc.stderr ? await new Response(proc.stderr).text() : "";
75661
+ return { stdout, stderr, exitCode: proc.exitCode ?? 1, timedOut: false };
75662
+ }
75663
+
75664
+ // src/cli/doctor/checks/system-binary.ts
75371
75665
  function getDesktopAppPaths(platform) {
75372
- const home = homedir5();
75666
+ const home = homedir6();
75373
75667
  switch (platform) {
75374
75668
  case "darwin":
75375
75669
  return [
75376
75670
  "/Applications/OpenCode.app/Contents/MacOS/OpenCode",
75377
- join27(home, "Applications", "OpenCode.app", "Contents", "MacOS", "OpenCode")
75671
+ join29(home, "Applications", "OpenCode.app", "Contents", "MacOS", "OpenCode")
75378
75672
  ];
75379
75673
  case "win32": {
75380
75674
  const programFiles = process.env.ProgramFiles;
75381
75675
  const localAppData = process.env.LOCALAPPDATA;
75382
75676
  const paths = [];
75383
75677
  if (programFiles) {
75384
- paths.push(join27(programFiles, "OpenCode", "OpenCode.exe"));
75678
+ paths.push(join29(programFiles, "OpenCode", "OpenCode.exe"));
75385
75679
  }
75386
75680
  if (localAppData) {
75387
- paths.push(join27(localAppData, "OpenCode", "OpenCode.exe"));
75681
+ paths.push(join29(localAppData, "OpenCode", "OpenCode.exe"));
75388
75682
  }
75389
75683
  return paths;
75390
75684
  }
@@ -75392,8 +75686,8 @@ function getDesktopAppPaths(platform) {
75392
75686
  return [
75393
75687
  "/usr/bin/opencode",
75394
75688
  "/usr/lib/opencode/opencode",
75395
- join27(home, "Applications", "opencode-desktop-linux-x86_64.AppImage"),
75396
- join27(home, "Applications", "opencode-desktop-linux-aarch64.AppImage")
75689
+ join29(home, "Applications", "opencode-desktop-linux-x86_64.AppImage"),
75690
+ join29(home, "Applications", "opencode-desktop-linux-aarch64.AppImage")
75397
75691
  ];
75398
75692
  default:
75399
75693
  return [];
@@ -75405,7 +75699,7 @@ function buildVersionCommand(binaryPath, platform) {
75405
75699
  }
75406
75700
  return [binaryPath, "--version"];
75407
75701
  }
75408
- function findDesktopBinary(platform = process.platform, checkExists = existsSync28) {
75702
+ function findDesktopBinary(platform = process.platform, checkExists = existsSync30) {
75409
75703
  for (const desktopPath of getDesktopAppPaths(platform)) {
75410
75704
  if (checkExists(desktopPath)) {
75411
75705
  return { binary: "opencode", path: desktopPath };
@@ -75415,9 +75709,9 @@ function findDesktopBinary(platform = process.platform, checkExists = existsSync
75415
75709
  }
75416
75710
  async function findOpenCodeBinary() {
75417
75711
  for (const binary2 of OPENCODE_BINARIES2) {
75418
- const path11 = Bun.which(binary2);
75419
- if (path11) {
75420
- return { binary: binary2, path: path11 };
75712
+ const path12 = Bun.which(binary2);
75713
+ if (path12) {
75714
+ return { binary: binary2, path: path12 };
75421
75715
  }
75422
75716
  }
75423
75717
  return findDesktopBinary();
@@ -75425,12 +75719,10 @@ async function findOpenCodeBinary() {
75425
75719
  async function getOpenCodeVersion3(binaryPath, platform = process.platform) {
75426
75720
  try {
75427
75721
  const command = buildVersionCommand(binaryPath, platform);
75428
- const processResult = spawnWithWindowsHide(command, { stdout: "pipe", stderr: "pipe" });
75429
- const output = await new Response(processResult.stdout).text();
75430
- await processResult.exited;
75431
- if (processResult.exitCode !== 0)
75722
+ const result = await spawnWithTimeout(command, { stdout: "pipe", stderr: "pipe" });
75723
+ if (result.timedOut || result.exitCode !== 0)
75432
75724
  return null;
75433
- return output.trim() || null;
75725
+ return result.stdout.trim() || null;
75434
75726
  } catch {
75435
75727
  return null;
75436
75728
  }
@@ -75453,12 +75745,12 @@ function compareVersions3(current, minimum) {
75453
75745
 
75454
75746
  // src/cli/doctor/checks/system-plugin.ts
75455
75747
  init_shared();
75456
- import { existsSync as existsSync29, readFileSync as readFileSync24 } from "fs";
75748
+ import { existsSync as existsSync31, readFileSync as readFileSync25 } from "fs";
75457
75749
  function detectConfigPath() {
75458
75750
  const paths = getOpenCodeConfigPaths({ binary: "opencode", version: null });
75459
- if (existsSync29(paths.configJsonc))
75751
+ if (existsSync31(paths.configJsonc))
75460
75752
  return paths.configJsonc;
75461
- if (existsSync29(paths.configJson))
75753
+ if (existsSync31(paths.configJson))
75462
75754
  return paths.configJson;
75463
75755
  return null;
75464
75756
  }
@@ -75504,7 +75796,7 @@ function getPluginInfo() {
75504
75796
  };
75505
75797
  }
75506
75798
  try {
75507
- const content = readFileSync24(configPath, "utf-8");
75799
+ const content = readFileSync25(configPath, "utf-8");
75508
75800
  const parsedConfig = parseJsonc(content);
75509
75801
  const pluginEntry = findPluginEntry2(parsedConfig.plugin ?? []);
75510
75802
  if (!pluginEntry) {
@@ -75542,37 +75834,37 @@ function getPluginInfo() {
75542
75834
  init_file_utils();
75543
75835
  init_checker();
75544
75836
  init_auto_update_checker();
75545
- import { existsSync as existsSync30, readFileSync as readFileSync25 } from "fs";
75546
- import { homedir as homedir6 } from "os";
75547
- import { join as join28 } from "path";
75837
+ import { existsSync as existsSync32, readFileSync as readFileSync26 } from "fs";
75838
+ import { homedir as homedir7 } from "os";
75839
+ import { join as join30 } from "path";
75548
75840
  init_shared();
75549
75841
  function getPlatformDefaultCacheDir(platform = process.platform) {
75550
75842
  if (platform === "darwin")
75551
- return join28(homedir6(), "Library", "Caches");
75843
+ return join30(homedir7(), "Library", "Caches");
75552
75844
  if (platform === "win32")
75553
- return process.env.LOCALAPPDATA ?? join28(homedir6(), "AppData", "Local");
75554
- return join28(homedir6(), ".cache");
75845
+ return process.env.LOCALAPPDATA ?? join30(homedir7(), "AppData", "Local");
75846
+ return join30(homedir7(), ".cache");
75555
75847
  }
75556
75848
  function resolveOpenCodeCacheDir() {
75557
75849
  const xdgCacheHome = process.env.XDG_CACHE_HOME;
75558
75850
  if (xdgCacheHome)
75559
- return join28(xdgCacheHome, "opencode");
75851
+ return join30(xdgCacheHome, "opencode");
75560
75852
  const fromShared = getOpenCodeCacheDir();
75561
- const platformDefault = join28(getPlatformDefaultCacheDir(), "opencode");
75562
- if (existsSync30(fromShared) || !existsSync30(platformDefault))
75853
+ const platformDefault = join30(getPlatformDefaultCacheDir(), "opencode");
75854
+ if (existsSync32(fromShared) || !existsSync32(platformDefault))
75563
75855
  return fromShared;
75564
75856
  return platformDefault;
75565
75857
  }
75566
75858
  function resolveExistingDir(dirPath) {
75567
- if (!existsSync30(dirPath))
75859
+ if (!existsSync32(dirPath))
75568
75860
  return dirPath;
75569
75861
  return resolveSymlink(dirPath);
75570
75862
  }
75571
75863
  function readPackageJson(filePath) {
75572
- if (!existsSync30(filePath))
75864
+ if (!existsSync32(filePath))
75573
75865
  return null;
75574
75866
  try {
75575
- const content = readFileSync25(filePath, "utf-8");
75867
+ const content = readFileSync26(filePath, "utf-8");
75576
75868
  return parseJsonc(content);
75577
75869
  } catch {
75578
75870
  return null;
@@ -75587,11 +75879,11 @@ function normalizeVersion(value) {
75587
75879
  function createPackageCandidates(rootDir) {
75588
75880
  return ACCEPTED_PACKAGE_NAMES.map((packageName) => ({
75589
75881
  packageName,
75590
- installedPackagePath: join28(rootDir, "node_modules", packageName, "package.json")
75882
+ installedPackagePath: join30(rootDir, "node_modules", packageName, "package.json")
75591
75883
  }));
75592
75884
  }
75593
75885
  function selectInstalledPackage(candidate) {
75594
- return candidate.packageCandidates.find((packageCandidate) => existsSync30(packageCandidate.installedPackagePath)) ?? candidate.packageCandidates[0];
75886
+ return candidate.packageCandidates.find((packageCandidate) => existsSync32(packageCandidate.installedPackagePath)) ?? candidate.packageCandidates[0];
75595
75887
  }
75596
75888
  function getExpectedVersion(cachePackage, packageName) {
75597
75889
  return normalizeVersion(cachePackage?.dependencies?.[packageName]) ?? normalizeVersion(cachePackage?.dependencies?.[PACKAGE_NAME]);
@@ -75603,16 +75895,16 @@ function getLoadedPluginVersion() {
75603
75895
  const candidates = [
75604
75896
  {
75605
75897
  cacheDir: configDir,
75606
- cachePackagePath: join28(configDir, "package.json"),
75898
+ cachePackagePath: join30(configDir, "package.json"),
75607
75899
  packageCandidates: createPackageCandidates(configDir)
75608
75900
  },
75609
75901
  {
75610
75902
  cacheDir,
75611
- cachePackagePath: join28(cacheDir, "package.json"),
75903
+ cachePackagePath: join30(cacheDir, "package.json"),
75612
75904
  packageCandidates: createPackageCandidates(cacheDir)
75613
75905
  }
75614
75906
  ];
75615
- const selectedCandidate = candidates.find((candidate) => candidate.packageCandidates.some((packageCandidate) => existsSync30(packageCandidate.installedPackagePath))) ?? candidates[0];
75907
+ const selectedCandidate = candidates.find((candidate) => candidate.packageCandidates.some((packageCandidate) => existsSync32(packageCandidate.installedPackagePath))) ?? candidates[0];
75616
75908
  const { cacheDir: selectedDir, cachePackagePath } = selectedCandidate;
75617
75909
  const selectedPackage = selectInstalledPackage(selectedCandidate);
75618
75910
  const installedPackagePath = selectedPackage.installedPackagePath;
@@ -75651,10 +75943,10 @@ var defaultDeps3 = {
75651
75943
  function isConfigValid(configPath) {
75652
75944
  if (!configPath)
75653
75945
  return true;
75654
- if (!existsSync31(configPath))
75946
+ if (!existsSync33(configPath))
75655
75947
  return false;
75656
75948
  try {
75657
- parseJsonc(readFileSync26(configPath, "utf-8"));
75949
+ parseJsonc(readFileSync27(configPath, "utf-8"));
75658
75950
  return true;
75659
75951
  } catch {
75660
75952
  return false;
@@ -75776,32 +76068,32 @@ async function checkSystem(deps = defaultDeps3) {
75776
76068
  }
75777
76069
 
75778
76070
  // src/cli/doctor/checks/config.ts
75779
- import { readFileSync as readFileSync29 } from "fs";
75780
- import { join as join32 } from "path";
76071
+ import { readFileSync as readFileSync30 } from "fs";
76072
+ import { join as join34 } from "path";
75781
76073
  init_shared();
75782
76074
 
75783
76075
  // src/cli/doctor/checks/model-resolution-cache.ts
75784
76076
  init_shared();
75785
- import { existsSync as existsSync32, readFileSync as readFileSync27 } from "fs";
75786
- import { homedir as homedir7 } from "os";
75787
- import { join as join29 } from "path";
76077
+ import { existsSync as existsSync34, readFileSync as readFileSync28 } from "fs";
76078
+ import { homedir as homedir8 } from "os";
76079
+ import { join as join31 } from "path";
75788
76080
  function getUserConfigDir2() {
75789
76081
  const xdgConfig = process.env.XDG_CONFIG_HOME;
75790
76082
  if (xdgConfig)
75791
- return join29(xdgConfig, "opencode");
75792
- return join29(homedir7(), ".config", "opencode");
76083
+ return join31(xdgConfig, "opencode");
76084
+ return join31(homedir8(), ".config", "opencode");
75793
76085
  }
75794
76086
  function loadCustomProviderNames() {
75795
76087
  const configDir = getUserConfigDir2();
75796
76088
  const candidatePaths = [
75797
- join29(configDir, "opencode.json"),
75798
- join29(configDir, "opencode.jsonc")
76089
+ join31(configDir, "opencode.json"),
76090
+ join31(configDir, "opencode.jsonc")
75799
76091
  ];
75800
76092
  for (const configPath of candidatePaths) {
75801
- if (!existsSync32(configPath))
76093
+ if (!existsSync34(configPath))
75802
76094
  continue;
75803
76095
  try {
75804
- const content = readFileSync27(configPath, "utf-8");
76096
+ const content = readFileSync28(configPath, "utf-8");
75805
76097
  const data = parseJsonc(content);
75806
76098
  if (data?.provider && typeof data.provider === "object") {
75807
76099
  return Object.keys(data.provider);
@@ -75811,16 +76103,16 @@ function loadCustomProviderNames() {
75811
76103
  return [];
75812
76104
  }
75813
76105
  function loadAvailableModelsFromCache() {
75814
- const cacheFile = join29(getOpenCodeCacheDir(), "models.json");
76106
+ const cacheFile = join31(getOpenCodeCacheDir(), "models.json");
75815
76107
  const customProviders = loadCustomProviderNames();
75816
- if (!existsSync32(cacheFile)) {
76108
+ if (!existsSync34(cacheFile)) {
75817
76109
  if (customProviders.length > 0) {
75818
76110
  return { providers: customProviders, modelCount: 0, cacheExists: true };
75819
76111
  }
75820
76112
  return { providers: [], modelCount: 0, cacheExists: false };
75821
76113
  }
75822
76114
  try {
75823
- const content = readFileSync27(cacheFile, "utf-8");
76115
+ const content = readFileSync28(cacheFile, "utf-8");
75824
76116
  const data = parseJsonc(content);
75825
76117
  const cacheProviders = Object.keys(data);
75826
76118
  let modelCount = 0;
@@ -75843,14 +76135,14 @@ init_model_capabilities();
75843
76135
 
75844
76136
  // src/cli/doctor/checks/model-resolution-config.ts
75845
76137
  init_shared();
75846
- import { readFileSync as readFileSync28 } from "fs";
75847
- import { join as join30 } from "path";
75848
- var PROJECT_CONFIG_DIR = join30(process.cwd(), ".opencode");
76138
+ import { readFileSync as readFileSync29 } from "fs";
76139
+ import { join as join32 } from "path";
76140
+ var PROJECT_CONFIG_DIR = join32(process.cwd(), ".opencode");
75849
76141
  function loadOmoConfig() {
75850
76142
  const projectDetected = detectPluginConfigFile(PROJECT_CONFIG_DIR);
75851
76143
  if (projectDetected.format !== "none") {
75852
76144
  try {
75853
- const content = readFileSync28(projectDetected.path, "utf-8");
76145
+ const content = readFileSync29(projectDetected.path, "utf-8");
75854
76146
  return parseJsonc(content);
75855
76147
  } catch {
75856
76148
  return null;
@@ -75860,7 +76152,7 @@ function loadOmoConfig() {
75860
76152
  const userDetected = detectPluginConfigFile(userConfigDir);
75861
76153
  if (userDetected.format !== "none") {
75862
76154
  try {
75863
- const content = readFileSync28(userDetected.path, "utf-8");
76155
+ const content = readFileSync29(userDetected.path, "utf-8");
75864
76156
  return parseJsonc(content);
75865
76157
  } catch {
75866
76158
  return null;
@@ -75871,7 +76163,7 @@ function loadOmoConfig() {
75871
76163
 
75872
76164
  // src/cli/doctor/checks/model-resolution-details.ts
75873
76165
  init_shared();
75874
- import { join as join31 } from "path";
76166
+ import { join as join33 } from "path";
75875
76167
 
75876
76168
  // src/cli/doctor/checks/model-resolution-variant.ts
75877
76169
  function formatModelWithVariant(model, variant) {
@@ -75913,7 +76205,7 @@ function formatCapabilityResolutionLabel(mode) {
75913
76205
  }
75914
76206
  function buildModelResolutionDetails(options) {
75915
76207
  const details = [];
75916
- const cacheFile = join31(getOpenCodeCacheDir(), "models.json");
76208
+ const cacheFile = join33(getOpenCodeCacheDir(), "models.json");
75917
76209
  details.push("\u2550\u2550\u2550 Available Models (from cache) \u2550\u2550\u2550");
75918
76210
  details.push("");
75919
76211
  if (options.available.cacheExists) {
@@ -76068,7 +76360,7 @@ async function checkModels() {
76068
76360
  }
76069
76361
 
76070
76362
  // src/cli/doctor/checks/config.ts
76071
- var PROJECT_CONFIG_DIR2 = join32(process.cwd(), ".opencode");
76363
+ var PROJECT_CONFIG_DIR2 = join34(process.cwd(), ".opencode");
76072
76364
  function findConfigPath() {
76073
76365
  const projectConfig = detectPluginConfigFile(PROJECT_CONFIG_DIR2);
76074
76366
  if (projectConfig.format !== "none")
@@ -76085,7 +76377,7 @@ function validateConfig() {
76085
76377
  return { exists: false, path: null, valid: true, config: null, errors: [] };
76086
76378
  }
76087
76379
  try {
76088
- const content = readFileSync29(configPath, "utf-8");
76380
+ const content = readFileSync30(configPath, "utf-8");
76089
76381
  const rawConfig = parseJsonc(content);
76090
76382
  const schemaResult = OhMyOpenCodeConfigSchema.safeParse(rawConfig);
76091
76383
  if (!schemaResult.success) {
@@ -76188,30 +76480,55 @@ async function checkConfig() {
76188
76480
  }
76189
76481
 
76190
76482
  // src/cli/doctor/checks/dependencies.ts
76191
- init_spawn_with_windows_hide();
76192
- import { existsSync as existsSync33 } from "fs";
76483
+ import { existsSync as existsSync35 } from "fs";
76193
76484
  import { createRequire } from "module";
76194
- import { dirname as dirname13, join as join33 } from "path";
76485
+ import { dirname as dirname14, join as join36 } from "path";
76486
+
76487
+ // src/hooks/comment-checker/downloader.ts
76488
+ import { join as join35 } from "path";
76489
+ import { homedir as homedir9, tmpdir as tmpdir3 } from "os";
76490
+ init_binary_downloader();
76491
+ init_logger();
76492
+ init_plugin_identity();
76493
+ var DEBUG = process.env.COMMENT_CHECKER_DEBUG === "1";
76494
+ var DEBUG_FILE = join35(tmpdir3(), "comment-checker-debug.log");
76495
+ function getCacheDir2() {
76496
+ if (process.platform === "win32") {
76497
+ const localAppData = process.env.LOCALAPPDATA || process.env.APPDATA;
76498
+ const base2 = localAppData || join35(homedir9(), "AppData", "Local");
76499
+ return join35(base2, CACHE_DIR_NAME, "bin");
76500
+ }
76501
+ const xdgCache = process.env.XDG_CACHE_HOME;
76502
+ const base = xdgCache || join35(homedir9(), ".cache");
76503
+ return join35(base, CACHE_DIR_NAME, "bin");
76504
+ }
76505
+ function getBinaryName() {
76506
+ return process.platform === "win32" ? "comment-checker.exe" : "comment-checker";
76507
+ }
76508
+ function getCachedBinaryPath2() {
76509
+ return getCachedBinaryPath(getCacheDir2(), getBinaryName());
76510
+ }
76511
+
76512
+ // src/cli/doctor/checks/dependencies.ts
76195
76513
  async function checkBinaryExists(binary2) {
76196
76514
  try {
76197
- const path11 = Bun.which(binary2);
76198
- if (path11) {
76199
- return { exists: true, path: path11 };
76515
+ const path12 = Bun.which(binary2);
76516
+ if (path12) {
76517
+ return { exists: true, path: path12 };
76200
76518
  }
76201
76519
  } catch {}
76202
76520
  return { exists: false, path: null };
76203
76521
  }
76204
76522
  async function getBinaryVersion(binary2) {
76205
76523
  try {
76206
- const proc = spawnWithWindowsHide([binary2, "--version"], { stdout: "pipe", stderr: "pipe" });
76207
- const output = await new Response(proc.stdout).text();
76208
- await proc.exited;
76209
- if (proc.exitCode === 0) {
76210
- return output.trim().split(`
76211
- `)[0];
76212
- }
76213
- } catch {}
76214
- return null;
76524
+ const result = await spawnWithTimeout([binary2, "--version"], { stdout: "pipe", stderr: "pipe" });
76525
+ if (result.timedOut || result.exitCode !== 0)
76526
+ return null;
76527
+ return result.stdout.trim().split(`
76528
+ `)[0] ?? null;
76529
+ } catch {
76530
+ return null;
76531
+ }
76215
76532
  }
76216
76533
  async function checkAstGrepCli() {
76217
76534
  const binaryCheck = await checkBinaryExists("sg");
@@ -76247,15 +76564,15 @@ async function checkAstGrepNapi() {
76247
76564
  path: null
76248
76565
  };
76249
76566
  } catch {
76250
- const { existsSync: existsSync34 } = await import("fs");
76251
- const { join: join34 } = await import("path");
76252
- const { homedir: homedir8 } = await import("os");
76567
+ const { existsSync: existsSync36 } = await import("fs");
76568
+ const { join: join37 } = await import("path");
76569
+ const { homedir: homedir10 } = await import("os");
76253
76570
  const pathsToCheck = [
76254
- join34(homedir8(), ".config", "opencode", "node_modules", "@ast-grep", "napi"),
76255
- join34(process.cwd(), "node_modules", "@ast-grep", "napi")
76571
+ join37(homedir10(), ".config", "opencode", "node_modules", "@ast-grep", "napi"),
76572
+ join37(process.cwd(), "node_modules", "@ast-grep", "napi")
76256
76573
  ];
76257
76574
  for (const napiPath of pathsToCheck) {
76258
- if (existsSync34(napiPath)) {
76575
+ if (existsSync36(napiPath)) {
76259
76576
  return {
76260
76577
  name: "AST-Grep NAPI",
76261
76578
  required: false,
@@ -76280,13 +76597,24 @@ function findCommentCheckerPackageBinary() {
76280
76597
  try {
76281
76598
  const require2 = createRequire(import.meta.url);
76282
76599
  const pkgPath = require2.resolve("@code-yeongyu/comment-checker/package.json");
76283
- const binaryPath = join33(dirname13(pkgPath), "bin", binaryName);
76284
- if (existsSync33(binaryPath))
76600
+ const binaryPath = join36(dirname14(pkgPath), "bin", binaryName);
76601
+ if (existsSync35(binaryPath))
76285
76602
  return binaryPath;
76286
76603
  } catch {}
76287
76604
  return null;
76288
76605
  }
76289
76606
  async function checkCommentChecker() {
76607
+ const cachedPath = getCachedBinaryPath2();
76608
+ if (cachedPath) {
76609
+ const version4 = await getBinaryVersion(cachedPath);
76610
+ return {
76611
+ name: "Comment Checker",
76612
+ required: false,
76613
+ installed: true,
76614
+ version: version4,
76615
+ path: cachedPath
76616
+ };
76617
+ }
76290
76618
  const binaryCheck = await checkBinaryExists("comment-checker");
76291
76619
  const resolvedPath = binaryCheck.exists ? binaryCheck.path : findCommentCheckerPackageBinary();
76292
76620
  if (!resolvedPath) {
@@ -76310,7 +76638,6 @@ async function checkCommentChecker() {
76310
76638
  }
76311
76639
 
76312
76640
  // src/cli/doctor/checks/tools-gh.ts
76313
- init_spawn_with_windows_hide();
76314
76641
  async function checkBinaryExists2(binary2) {
76315
76642
  try {
76316
76643
  const binaryPath = Bun.which(binary2);
@@ -76321,13 +76648,11 @@ async function checkBinaryExists2(binary2) {
76321
76648
  }
76322
76649
  async function getGhVersion() {
76323
76650
  try {
76324
- const processResult = spawnWithWindowsHide(["gh", "--version"], { stdout: "pipe", stderr: "pipe" });
76325
- const output = await new Response(processResult.stdout).text();
76326
- await processResult.exited;
76327
- if (processResult.exitCode !== 0)
76651
+ const result = await spawnWithTimeout(["gh", "--version"], { stdout: "pipe", stderr: "pipe" });
76652
+ if (result.timedOut || result.exitCode !== 0)
76328
76653
  return null;
76329
- const matchedVersion = output.match(/gh version (\S+)/);
76330
- return matchedVersion?.[1] ?? output.trim().split(`
76654
+ const matchedVersion = result.stdout.match(/gh version (\S+)/);
76655
+ return matchedVersion?.[1] ?? result.stdout.trim().split(`
76331
76656
  `)[0] ?? null;
76332
76657
  } catch {
76333
76658
  return null;
@@ -76335,16 +76660,12 @@ async function getGhVersion() {
76335
76660
  }
76336
76661
  async function getGhAuthStatus() {
76337
76662
  try {
76338
- const processResult = spawnWithWindowsHide(["gh", "auth", "status"], {
76339
- stdout: "pipe",
76340
- stderr: "pipe",
76341
- env: { ...process.env, GH_NO_UPDATE_NOTIFIER: "1" }
76342
- });
76343
- const stdout = await new Response(processResult.stdout).text();
76344
- const stderr = await new Response(processResult.stderr).text();
76345
- await processResult.exited;
76346
- const output = stderr || stdout;
76347
- if (processResult.exitCode === 0) {
76663
+ const result = await spawnWithTimeout(["gh", "auth", "status"], { stdout: "pipe", stderr: "pipe", env: { ...process.env, GH_NO_UPDATE_NOTIFIER: "1" } });
76664
+ if (result.timedOut) {
76665
+ return { authenticated: false, username: null, scopes: [], error: "gh auth status timed out" };
76666
+ }
76667
+ const output = result.stderr || result.stdout;
76668
+ if (result.exitCode === 0) {
76348
76669
  const usernameMatch = output.match(/Logged in to github\.com account (\S+)/);
76349
76670
  const scopesMatch = output.match(/Token scopes?:\s*(.+)/i);
76350
76671
  return {
@@ -76438,15 +76759,15 @@ var BUILTIN_SERVERS = {
76438
76759
  "kotlin-ls": { command: ["kotlin-lsp"], extensions: [".kt", ".kts"] }
76439
76760
  };
76440
76761
  // src/tools/lsp/server-config-loader.ts
76441
- import { existsSync as existsSync34, readFileSync as readFileSync30 } from "fs";
76442
- import { join as join34 } from "path";
76762
+ import { existsSync as existsSync36, readFileSync as readFileSync31 } from "fs";
76763
+ import { join as join37 } from "path";
76443
76764
  init_shared();
76444
76765
  init_jsonc_parser();
76445
- function loadJsonFile(path11) {
76446
- if (!existsSync34(path11))
76766
+ function loadJsonFile(path12) {
76767
+ if (!existsSync36(path12))
76447
76768
  return null;
76448
76769
  try {
76449
- return parseJsonc(readFileSync30(path11, "utf-8"));
76770
+ return parseJsonc(readFileSync31(path12, "utf-8"));
76450
76771
  } catch {
76451
76772
  return null;
76452
76773
  }
@@ -76455,9 +76776,9 @@ function getConfigPaths2() {
76455
76776
  const cwd = process.cwd();
76456
76777
  const configDir = getOpenCodeConfigDir({ binary: "opencode" });
76457
76778
  return {
76458
- project: detectPluginConfigFile(join34(cwd, ".opencode")).path,
76779
+ project: detectPluginConfigFile(join37(cwd, ".opencode")).path,
76459
76780
  user: detectPluginConfigFile(configDir).path,
76460
- opencode: detectConfigFile(join34(configDir, "opencode")).path
76781
+ opencode: detectConfigFile(join37(configDir, "opencode")).path
76461
76782
  };
76462
76783
  }
76463
76784
  function loadAllConfigs() {
@@ -76526,21 +76847,21 @@ function getMergedServers() {
76526
76847
  }
76527
76848
 
76528
76849
  // src/tools/lsp/server-installation.ts
76529
- import { existsSync as existsSync35 } from "fs";
76530
- import { delimiter as delimiter2, join as join36 } from "path";
76850
+ import { existsSync as existsSync37 } from "fs";
76851
+ import { delimiter as delimiter2, join as join39 } from "path";
76531
76852
 
76532
76853
  // src/tools/lsp/server-path-bases.ts
76533
76854
  init_shared();
76534
- import { join as join35 } from "path";
76855
+ import { join as join38 } from "path";
76535
76856
  function getLspServerAdditionalPathBases(workingDirectory) {
76536
76857
  const configDir = getOpenCodeConfigDir({ binary: "opencode" });
76537
- const dataDir = join35(getDataDir(), "opencode");
76858
+ const dataDir = join38(getDataDir(), "opencode");
76538
76859
  return [
76539
- join35(workingDirectory, "node_modules", ".bin"),
76540
- join35(configDir, "bin"),
76541
- join35(configDir, "node_modules", ".bin"),
76542
- join35(dataDir, "bin"),
76543
- join35(dataDir, "bin", "node_modules", ".bin")
76860
+ join38(workingDirectory, "node_modules", ".bin"),
76861
+ join38(configDir, "bin"),
76862
+ join38(configDir, "node_modules", ".bin"),
76863
+ join38(dataDir, "bin"),
76864
+ join38(dataDir, "bin", "node_modules", ".bin")
76544
76865
  ];
76545
76866
  }
76546
76867
 
@@ -76550,7 +76871,7 @@ function isServerInstalled(command) {
76550
76871
  return false;
76551
76872
  const cmd = command[0];
76552
76873
  if (cmd.includes("/") || cmd.includes("\\")) {
76553
- if (existsSync35(cmd))
76874
+ if (existsSync37(cmd))
76554
76875
  return true;
76555
76876
  }
76556
76877
  const isWindows = process.platform === "win32";
@@ -76571,14 +76892,14 @@ function isServerInstalled(command) {
76571
76892
  const paths = pathEnv.split(delimiter2);
76572
76893
  for (const p2 of paths) {
76573
76894
  for (const suffix of exts) {
76574
- if (existsSync35(join36(p2, cmd + suffix))) {
76895
+ if (existsSync37(join39(p2, cmd + suffix))) {
76575
76896
  return true;
76576
76897
  }
76577
76898
  }
76578
76899
  }
76579
76900
  for (const base of getLspServerAdditionalPathBases(process.cwd())) {
76580
76901
  for (const suffix of exts) {
76581
- if (existsSync35(join36(base, cmd + suffix))) {
76902
+ if (existsSync37(join39(base, cmd + suffix))) {
76582
76903
  return true;
76583
76904
  }
76584
76905
  }
@@ -76640,24 +76961,24 @@ function getInstalledLspServers() {
76640
76961
 
76641
76962
  // src/cli/doctor/checks/tools-mcp.ts
76642
76963
  init_shared();
76643
- import { existsSync as existsSync36, readFileSync as readFileSync31 } from "fs";
76644
- import { homedir as homedir8 } from "os";
76645
- import { join as join37 } from "path";
76964
+ import { existsSync as existsSync38, readFileSync as readFileSync32 } from "fs";
76965
+ import { homedir as homedir10 } from "os";
76966
+ import { join as join40 } from "path";
76646
76967
  var BUILTIN_MCP_SERVERS = ["context7", "grep_app"];
76647
76968
  function getMcpConfigPaths() {
76648
76969
  return [
76649
- join37(homedir8(), ".claude", ".mcp.json"),
76650
- join37(process.cwd(), ".mcp.json"),
76651
- join37(process.cwd(), ".claude", ".mcp.json")
76970
+ join40(homedir10(), ".claude", ".mcp.json"),
76971
+ join40(process.cwd(), ".mcp.json"),
76972
+ join40(process.cwd(), ".claude", ".mcp.json")
76652
76973
  ];
76653
76974
  }
76654
76975
  function loadUserMcpConfig() {
76655
76976
  const servers = {};
76656
76977
  for (const configPath of getMcpConfigPaths()) {
76657
- if (!existsSync36(configPath))
76978
+ if (!existsSync38(configPath))
76658
76979
  continue;
76659
76980
  try {
76660
- const content = readFileSync31(configPath, "utf-8");
76981
+ const content = readFileSync32(configPath, "utf-8");
76661
76982
  const config2 = parseJsonc(content);
76662
76983
  if (config2.mcpServers) {
76663
76984
  Object.assign(servers, config2.mcpServers);
@@ -77017,6 +77338,14 @@ function formatJsonOutput2(result) {
77017
77338
  }
77018
77339
 
77019
77340
  // src/cli/doctor/runner.ts
77341
+ var DOCTOR_TIMEOUT_MS = 30000;
77342
+
77343
+ class DoctorTimeoutError extends Error {
77344
+ constructor() {
77345
+ super("Doctor timed out");
77346
+ this.name = "DoctorTimeoutError";
77347
+ }
77348
+ }
77020
77349
  async function runCheck(check2) {
77021
77350
  const start = performance.now();
77022
77351
  try {
@@ -77046,14 +77375,49 @@ function calculateSummary(results, duration3) {
77046
77375
  function determineExitCode(results) {
77047
77376
  return results.some((r2) => r2.status === "fail") ? EXIT_CODES.FAILURE : EXIT_CODES.SUCCESS;
77048
77377
  }
77378
+ function buildTimeoutResult(start, options) {
77379
+ const timeoutResult = {
77380
+ results: [{ name: "Timeout", status: "fail", message: "Doctor timed out after 30s", issues: [{ title: "Doctor timeout", description: "Checks did not complete within 30s. A subprocess may be hanging.", severity: "error" }] }],
77381
+ systemInfo: { opencodeVersion: null, opencodePath: null, pluginVersion: null, loadedVersion: null, bunVersion: null, configPath: null, configValid: false, isLocalDev: false },
77382
+ tools: { lspServers: [], astGrepCli: false, astGrepNapi: false, commentChecker: false, ghCli: { installed: false, authenticated: false, username: null }, mcpBuiltin: [], mcpUser: [] },
77383
+ summary: { total: 1, passed: 0, failed: 1, warnings: 0, skipped: 0, duration: Math.round(performance.now() - start) },
77384
+ exitCode: EXIT_CODES.FAILURE
77385
+ };
77386
+ if (options.json) {
77387
+ console.log(formatJsonOutput2(timeoutResult));
77388
+ } else {
77389
+ console.error(`
77390
+ Doctor timed out after 30s. A subprocess may be hanging.`);
77391
+ console.error(`Try running with --verbose to identify the stuck check.
77392
+ `);
77393
+ }
77394
+ return timeoutResult;
77395
+ }
77049
77396
  async function runDoctor(options) {
77050
77397
  const start = performance.now();
77051
77398
  const allChecks = getAllCheckDefinitions();
77052
- const [results, systemInfo, tools] = await Promise.all([
77399
+ const checksPromise = Promise.all([
77053
77400
  Promise.all(allChecks.map(runCheck)),
77054
77401
  gatherSystemInfo(),
77055
77402
  gatherToolsSummary()
77056
77403
  ]);
77404
+ let timer;
77405
+ const timeoutPromise = new Promise((_3, reject) => {
77406
+ timer = setTimeout(() => reject(new DoctorTimeoutError), DOCTOR_TIMEOUT_MS);
77407
+ });
77408
+ let results;
77409
+ let systemInfo;
77410
+ let tools;
77411
+ try {
77412
+ [results, systemInfo, tools] = await Promise.race([checksPromise, timeoutPromise]);
77413
+ } catch (error48) {
77414
+ clearTimeout(timer);
77415
+ if (error48 instanceof DoctorTimeoutError) {
77416
+ return buildTimeoutResult(start, options);
77417
+ }
77418
+ throw error48;
77419
+ }
77420
+ clearTimeout(timer);
77057
77421
  const duration3 = performance.now() - start;
77058
77422
  const summary = calculateSummary(results, duration3);
77059
77423
  const exitCode = determineExitCode(results);
@@ -77112,11 +77476,11 @@ async function refreshModelCapabilities(options, deps = {}) {
77112
77476
 
77113
77477
  // src/features/mcp-oauth/storage.ts
77114
77478
  init_shared();
77115
- import { chmodSync, existsSync as existsSync37, mkdirSync as mkdirSync11, readFileSync as readFileSync32, renameSync as renameSync4, unlinkSync as unlinkSync4, writeFileSync as writeFileSync10 } from "fs";
77116
- import { dirname as dirname14, join as join38 } from "path";
77479
+ import { chmodSync as chmodSync2, existsSync as existsSync39, mkdirSync as mkdirSync12, readFileSync as readFileSync33, renameSync as renameSync4, unlinkSync as unlinkSync6, writeFileSync as writeFileSync10 } from "fs";
77480
+ import { dirname as dirname15, join as join41 } from "path";
77117
77481
  var STORAGE_FILE_NAME = "mcp-oauth.json";
77118
77482
  function getMcpOauthStoragePath() {
77119
- return join38(getOpenCodeConfigDir({ binary: "opencode" }), STORAGE_FILE_NAME);
77483
+ return join41(getOpenCodeConfigDir({ binary: "opencode" }), STORAGE_FILE_NAME);
77120
77484
  }
77121
77485
  function normalizeHost(serverHost) {
77122
77486
  let host = serverHost.trim();
@@ -77153,11 +77517,11 @@ function buildKey(serverHost, resource) {
77153
77517
  }
77154
77518
  function readStore() {
77155
77519
  const filePath = getMcpOauthStoragePath();
77156
- if (!existsSync37(filePath)) {
77520
+ if (!existsSync39(filePath)) {
77157
77521
  return null;
77158
77522
  }
77159
77523
  try {
77160
- const content = readFileSync32(filePath, "utf-8");
77524
+ const content = readFileSync33(filePath, "utf-8");
77161
77525
  return JSON.parse(content);
77162
77526
  } catch {
77163
77527
  return null;
@@ -77166,13 +77530,13 @@ function readStore() {
77166
77530
  function writeStore(store2) {
77167
77531
  const filePath = getMcpOauthStoragePath();
77168
77532
  try {
77169
- const dir = dirname14(filePath);
77170
- if (!existsSync37(dir)) {
77171
- mkdirSync11(dir, { recursive: true });
77533
+ const dir = dirname15(filePath);
77534
+ if (!existsSync39(dir)) {
77535
+ mkdirSync12(dir, { recursive: true });
77172
77536
  }
77173
77537
  const tempPath = `${filePath}.tmp.${Date.now()}`;
77174
77538
  writeFileSync10(tempPath, JSON.stringify(store2, null, 2), { encoding: "utf-8", mode: 384 });
77175
- chmodSync(tempPath, 384);
77539
+ chmodSync2(tempPath, 384);
77176
77540
  renameSync4(tempPath, filePath);
77177
77541
  return true;
77178
77542
  } catch {
@@ -77204,8 +77568,8 @@ function deleteToken(serverHost, resource) {
77204
77568
  if (Object.keys(store2).length === 0) {
77205
77569
  try {
77206
77570
  const filePath = getMcpOauthStoragePath();
77207
- if (existsSync37(filePath)) {
77208
- unlinkSync4(filePath);
77571
+ if (existsSync39(filePath)) {
77572
+ unlinkSync6(filePath);
77209
77573
  }
77210
77574
  return true;
77211
77575
  } catch {
@@ -77424,7 +77788,7 @@ function buildAuthorizationUrl(authorizationEndpoint, options) {
77424
77788
  }
77425
77789
  var CALLBACK_TIMEOUT_MS = 5 * 60 * 1000;
77426
77790
  function startCallbackServer(port) {
77427
- return new Promise((resolve2, reject) => {
77791
+ return new Promise((resolve4, reject) => {
77428
77792
  let timeoutId;
77429
77793
  const server2 = createServer((request, response) => {
77430
77794
  clearTimeout(timeoutId);
@@ -77450,7 +77814,7 @@ function startCallbackServer(port) {
77450
77814
  response.writeHead(200, { "content-type": "text/html" });
77451
77815
  response.end("<html><body><h1>Authorization successful. You can close this tab.</h1></body></html>");
77452
77816
  server2.close();
77453
- resolve2({ code, state: state2 });
77817
+ resolve4({ code, state: state2 });
77454
77818
  });
77455
77819
  timeoutId = setTimeout(() => {
77456
77820
  server2.close();
@@ -77787,20 +78151,21 @@ function createMcpOAuthCommand() {
77787
78151
  var VERSION2 = package_default.version;
77788
78152
  var program2 = new Command;
77789
78153
  program2.name("evil-omo").description("The ultimate OpenCode plugin - multi-model orchestration, LSP tools, and more").version(VERSION2, "-v, --version", "Show version number").enablePositionalOptions();
77790
- program2.command("install").description("Install and configure evil-omo with interactive setup").option("--no-tui", "Run in non-interactive mode (requires all options)").option("--claude <value>", "Claude subscription: no, yes, max20").option("--openai <value>", "OpenAI/ChatGPT subscription: no, yes (default: no)").option("--gemini <value>", "Gemini integration: no, yes").option("--copilot <value>", "GitHub Copilot subscription: no, yes").option("--opencode-zen <value>", "OpenCode Zen access: no, yes (default: no)").option("--zai-coding-plan <value>", "Z.ai Coding Plan subscription: no, yes (default: no)").option("--kimi-for-coding <value>", "Kimi For Coding subscription: no, yes (default: no)").option("--opencode-go <value>", "OpenCode Go subscription: no, yes (default: no)").option("--skip-auth", "Skip authentication setup hints").addHelpText("after", `
78154
+ program2.command("install").description("Install and configure evil-omo with interactive setup").option("--no-tui", "Run in non-interactive mode (requires all options)").option("--claude <value>", "Claude subscription: no, yes, max20").option("--openai <value>", "OpenAI/ChatGPT subscription: no, yes (default: no)").option("--gemini <value>", "Gemini integration: no, yes").option("--copilot <value>", "GitHub Copilot subscription: no, yes").option("--opencode-zen <value>", "OpenCode Zen access: no, yes (default: no)").option("--zai-coding-plan <value>", "Z.ai Coding Plan subscription: no, yes (default: no)").option("--kimi-for-coding <value>", "Kimi For Coding subscription: no, yes (default: no)").option("--opencode-go <value>", "OpenCode Go subscription: no, yes (default: no)").option("--vercel-ai-gateway <value>", "Vercel AI Gateway: no, yes (default: no)").option("--skip-auth", "Skip authentication setup hints").addHelpText("after", `
77791
78155
  Examples:
77792
78156
  $ bunx evil-omo install
77793
78157
  $ bunx evil-omo install --no-tui --claude=max20 --openai=yes --gemini=yes --copilot=no
77794
78158
  $ bunx evil-omo install --no-tui --claude=no --gemini=no --copilot=yes --opencode-zen=yes
77795
78159
 
77796
- Model Providers (Priority: Native > Copilot > OpenCode Zen > Z.ai > Kimi):
78160
+ Model Providers (Priority: Native > Copilot > OpenCode Zen > Z.ai > Kimi > Vercel):
77797
78161
  Claude Native anthropic/ models (Opus, Sonnet, Haiku)
77798
78162
  OpenAI Native openai/ models (GPT-5.4 for Oracle)
77799
78163
  Gemini Native google/ models (Gemini 3.1 Pro, Flash)
77800
78164
  Copilot github-copilot/ models (fallback)
77801
78165
  OpenCode Zen opencode/ models (opencode/claude-opus-4-6, etc.)
77802
- Z.ai zai-coding-plan/glm-5 (visual-engineering fallback)
78166
+ Z.ai zai-coding-plan/glm-5 (visual-engineering fallback)
77803
78167
  Kimi kimi-for-coding/k2p5 (Sisyphus/Prometheus fallback)
78168
+ Vercel vercel/ models (universal proxy, always last fallback)
77804
78169
  `).action(async (options) => {
77805
78170
  const args = {
77806
78171
  tui: options.tui !== false,
@@ -77812,6 +78177,7 @@ Model Providers (Priority: Native > Copilot > OpenCode Zen > Z.ai > Kimi):
77812
78177
  zaiCodingPlan: options.zaiCodingPlan,
77813
78178
  kimiForCoding: options.kimiForCoding,
77814
78179
  opencodeGo: options.opencodeGo,
78180
+ vercelAiGateway: options.vercelAiGateway,
77815
78181
  skipAuth: options.skipAuth ?? false
77816
78182
  };
77817
78183
  const exitCode = await install(args);