oh-my-opencode 2.13.2 → 3.0.0-beta.1

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 (93) hide show
  1. package/README.ja.md +71 -14
  2. package/README.md +169 -37
  3. package/README.zh-cn.md +68 -14
  4. package/dist/agents/metis.d.ts +18 -0
  5. package/dist/agents/momus.d.ts +6 -0
  6. package/dist/agents/orchestrator-sisyphus.d.ts +19 -0
  7. package/dist/agents/plan-prompt.d.ts +8 -5
  8. package/dist/agents/prometheus-prompt.d.ts +27 -0
  9. package/dist/agents/sisyphus-junior.d.ts +3 -0
  10. package/dist/agents/types.d.ts +1 -1
  11. package/dist/agents/utils.d.ts +4 -1
  12. package/dist/auth/antigravity/accounts.d.ts +40 -0
  13. package/dist/auth/antigravity/accounts.test.d.ts +1 -0
  14. package/dist/auth/antigravity/browser.d.ts +27 -0
  15. package/dist/auth/antigravity/browser.test.d.ts +1 -0
  16. package/dist/auth/antigravity/cli.d.ts +2 -0
  17. package/dist/auth/antigravity/cli.test.d.ts +1 -0
  18. package/dist/auth/antigravity/constants.d.ts +63 -1
  19. package/dist/auth/antigravity/constants.test.d.ts +1 -0
  20. package/dist/auth/antigravity/fetch.d.ts +2 -1
  21. package/dist/auth/antigravity/integration.test.d.ts +10 -0
  22. package/dist/auth/antigravity/oauth.d.ts +6 -40
  23. package/dist/auth/antigravity/oauth.test.d.ts +1 -0
  24. package/dist/auth/antigravity/request.d.ts +12 -0
  25. package/dist/auth/antigravity/request.test.d.ts +1 -0
  26. package/dist/auth/antigravity/storage.d.ts +5 -0
  27. package/dist/auth/antigravity/storage.test.d.ts +1 -0
  28. package/dist/auth/antigravity/thinking.d.ts +45 -1
  29. package/dist/auth/antigravity/thinking.test.d.ts +10 -0
  30. package/dist/auth/antigravity/token.test.d.ts +1 -0
  31. package/dist/auth/antigravity/types.d.ts +29 -5
  32. package/dist/cli/commands/auth.d.ts +2 -0
  33. package/dist/cli/index.js +341 -116
  34. package/dist/config/schema.d.ts +281 -7
  35. package/dist/features/background-agent/concurrency.d.ts +10 -0
  36. package/dist/features/background-agent/concurrency.test.d.ts +1 -0
  37. package/dist/features/background-agent/index.d.ts +1 -0
  38. package/dist/features/background-agent/manager.d.ts +16 -2
  39. package/dist/features/background-agent/types.d.ts +26 -0
  40. package/dist/features/boulder-state/constants.d.ts +10 -0
  41. package/dist/features/boulder-state/index.d.ts +3 -0
  42. package/dist/features/boulder-state/storage.d.ts +28 -0
  43. package/dist/features/boulder-state/storage.test.d.ts +1 -0
  44. package/dist/features/boulder-state/types.d.ts +24 -0
  45. package/dist/features/builtin-commands/templates/init-deep.d.ts +1 -1
  46. package/dist/features/builtin-commands/templates/refactor.d.ts +1 -1
  47. package/dist/features/builtin-commands/templates/start-work.d.ts +1 -0
  48. package/dist/features/builtin-commands/types.d.ts +1 -1
  49. package/dist/features/hook-message-injector/injector.d.ts +2 -2
  50. package/dist/features/hook-message-injector/types.d.ts +3 -2
  51. package/dist/features/opencode-skill-loader/index.d.ts +1 -0
  52. package/dist/features/opencode-skill-loader/skill-content.d.ts +5 -0
  53. package/dist/features/opencode-skill-loader/skill-content.test.d.ts +1 -0
  54. package/dist/features/task-toast-manager/index.d.ts +2 -0
  55. package/dist/features/task-toast-manager/manager.d.ts +56 -0
  56. package/dist/features/task-toast-manager/manager.test.d.ts +1 -0
  57. package/dist/features/task-toast-manager/types.d.ts +16 -0
  58. package/dist/google-auth.js +2167 -161
  59. package/dist/hooks/agent-usage-reminder/constants.d.ts +1 -1
  60. package/dist/hooks/auto-slash-command/executor.d.ts +5 -1
  61. package/dist/hooks/auto-slash-command/index.d.ts +5 -1
  62. package/dist/hooks/claude-code-hooks/index.d.ts +2 -1
  63. package/dist/hooks/claude-code-hooks/types.d.ts +1 -0
  64. package/dist/hooks/index.d.ts +4 -0
  65. package/dist/hooks/keyword-detector/index.test.d.ts +1 -0
  66. package/dist/hooks/prometheus-md-only/constants.d.ts +6 -0
  67. package/dist/hooks/prometheus-md-only/index.d.ts +12 -0
  68. package/dist/hooks/prometheus-md-only/index.test.d.ts +1 -0
  69. package/dist/hooks/sisyphus-orchestrator/index.d.ts +35 -0
  70. package/dist/hooks/sisyphus-orchestrator/index.test.d.ts +1 -0
  71. package/dist/hooks/start-work/index.d.ts +16 -0
  72. package/dist/hooks/start-work/index.test.d.ts +1 -0
  73. package/dist/hooks/task-resume-info/index.d.ts +11 -0
  74. package/dist/hooks/todo-continuation-enforcer.d.ts +1 -0
  75. package/dist/index.js +23047 -14427
  76. package/dist/mcp/index.d.ts +4 -2
  77. package/dist/mcp/types.d.ts +1 -0
  78. package/dist/mcp/websearch.d.ts +8 -0
  79. package/dist/shared/external-plugin-detector.d.ts +18 -0
  80. package/dist/shared/external-plugin-detector.test.d.ts +1 -0
  81. package/dist/shared/index.d.ts +1 -0
  82. package/dist/shared/migration.d.ts +6 -0
  83. package/dist/tools/background-task/index.d.ts +1 -1
  84. package/dist/tools/call-omo-agent/constants.d.ts +1 -1
  85. package/dist/tools/index.d.ts +1 -0
  86. package/dist/tools/sisyphus-task/constants.d.ts +12 -0
  87. package/dist/tools/sisyphus-task/index.d.ts +3 -0
  88. package/dist/tools/sisyphus-task/tools.d.ts +16 -0
  89. package/dist/tools/sisyphus-task/tools.test.d.ts +1 -0
  90. package/dist/tools/sisyphus-task/types.d.ts +9 -0
  91. package/dist/tools/slashcommand/types.d.ts +2 -1
  92. package/package.json +3 -2
  93. package/README.ko.md +0 -1040
package/dist/cli/index.js CHANGED
@@ -2657,8 +2657,8 @@ var require_napi = __commonJS((exports, module) => {
2657
2657
  var require_package = __commonJS((exports, module) => {
2658
2658
  module.exports = {
2659
2659
  name: "oh-my-opencode",
2660
- version: "2.13.1",
2661
- description: "OpenCode plugin - custom agents (oracle, librarian) and enhanced features",
2660
+ version: "2.14.0",
2661
+ description: "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
2662
2662
  main: "dist/index.js",
2663
2663
  types: "dist/index.d.ts",
2664
2664
  type: "module",
@@ -2719,6 +2719,7 @@ var require_package = __commonJS((exports, module) => {
2719
2719
  hono: "^4.10.4",
2720
2720
  "js-yaml": "^4.1.1",
2721
2721
  "jsonc-parser": "^3.3.1",
2722
+ open: "^11.0.0",
2722
2723
  picocolors: "^1.1.1",
2723
2724
  picomatch: "^4.0.2",
2724
2725
  "xdg-basedir": "^5.1.0",
@@ -6007,6 +6008,12 @@ function log(message, data) {
6007
6008
  var DANGEROUS_KEYS = new Set(["__proto__", "constructor", "prototype"]);
6008
6009
  // src/shared/dynamic-truncator.ts
6009
6010
  var ANTHROPIC_ACTUAL_LIMIT = process.env.ANTHROPIC_1M_CONTEXT === "true" || process.env.VERTEX_ANTHROPIC_1M_CONTEXT === "true" ? 1e6 : 200000;
6011
+ // src/shared/data-path.ts
6012
+ import * as path2 from "path";
6013
+ import * as os2 from "os";
6014
+ function getDataDir() {
6015
+ return process.env.XDG_DATA_HOME ?? path2.join(os2.homedir(), ".local", "share");
6016
+ }
6010
6017
  // src/shared/jsonc-parser.ts
6011
6018
  import { existsSync, readFileSync } from "fs";
6012
6019
 
@@ -6877,8 +6884,8 @@ function detectConfigFile(basePath) {
6877
6884
  }
6878
6885
  // src/shared/opencode-config-dir.ts
6879
6886
  import { existsSync as existsSync2 } from "fs";
6880
- import { homedir } from "os";
6881
- import { join as join2 } from "path";
6887
+ import { homedir as homedir2 } from "os";
6888
+ import { join as join3 } from "path";
6882
6889
  var TAURI_APP_IDENTIFIER = "ai.opencode.desktop";
6883
6890
  var TAURI_APP_IDENTIFIER_DEV = "ai.opencode.desktop.dev";
6884
6891
  function isDevBuild(version) {
@@ -6890,35 +6897,35 @@ function getTauriConfigDir(identifier) {
6890
6897
  const platform = process.platform;
6891
6898
  switch (platform) {
6892
6899
  case "darwin":
6893
- return join2(homedir(), "Library", "Application Support", identifier);
6900
+ return join3(homedir2(), "Library", "Application Support", identifier);
6894
6901
  case "win32": {
6895
- const appData = process.env.APPDATA || join2(homedir(), "AppData", "Roaming");
6896
- return join2(appData, identifier);
6902
+ const appData = process.env.APPDATA || join3(homedir2(), "AppData", "Roaming");
6903
+ return join3(appData, identifier);
6897
6904
  }
6898
6905
  case "linux":
6899
6906
  default: {
6900
- const xdgConfig = process.env.XDG_CONFIG_HOME || join2(homedir(), ".config");
6901
- return join2(xdgConfig, identifier);
6907
+ const xdgConfig = process.env.XDG_CONFIG_HOME || join3(homedir2(), ".config");
6908
+ return join3(xdgConfig, identifier);
6902
6909
  }
6903
6910
  }
6904
6911
  }
6905
6912
  function getCliConfigDir() {
6906
6913
  if (process.platform === "win32") {
6907
- const crossPlatformDir = join2(homedir(), ".config", "opencode");
6908
- const crossPlatformConfig = join2(crossPlatformDir, "opencode.json");
6914
+ const crossPlatformDir = join3(homedir2(), ".config", "opencode");
6915
+ const crossPlatformConfig = join3(crossPlatformDir, "opencode.json");
6909
6916
  if (existsSync2(crossPlatformConfig)) {
6910
6917
  return crossPlatformDir;
6911
6918
  }
6912
- const appData = process.env.APPDATA || join2(homedir(), "AppData", "Roaming");
6913
- const appdataDir = join2(appData, "opencode");
6914
- const appdataConfig = join2(appdataDir, "opencode.json");
6919
+ const appData = process.env.APPDATA || join3(homedir2(), "AppData", "Roaming");
6920
+ const appdataDir = join3(appData, "opencode");
6921
+ const appdataConfig = join3(appdataDir, "opencode.json");
6915
6922
  if (existsSync2(appdataConfig)) {
6916
6923
  return appdataDir;
6917
6924
  }
6918
6925
  return crossPlatformDir;
6919
6926
  }
6920
- const xdgConfig = process.env.XDG_CONFIG_HOME || join2(homedir(), ".config");
6921
- return join2(xdgConfig, "opencode");
6927
+ const xdgConfig = process.env.XDG_CONFIG_HOME || join3(homedir2(), ".config");
6928
+ return join3(xdgConfig, "opencode");
6922
6929
  }
6923
6930
  function getOpenCodeConfigDir(options) {
6924
6931
  const { binary: binary2, version, checkExisting = true } = options;
@@ -6929,8 +6936,8 @@ function getOpenCodeConfigDir(options) {
6929
6936
  const tauriDir = getTauriConfigDir(identifier);
6930
6937
  if (checkExisting) {
6931
6938
  const legacyDir = getCliConfigDir();
6932
- const legacyConfig = join2(legacyDir, "opencode.json");
6933
- const legacyConfigC = join2(legacyDir, "opencode.jsonc");
6939
+ const legacyConfig = join3(legacyDir, "opencode.json");
6940
+ const legacyConfigC = join3(legacyDir, "opencode.jsonc");
6934
6941
  if (existsSync2(legacyConfig) || existsSync2(legacyConfigC)) {
6935
6942
  return legacyDir;
6936
6943
  }
@@ -6941,10 +6948,10 @@ function getOpenCodeConfigPaths(options) {
6941
6948
  const configDir = getOpenCodeConfigDir(options);
6942
6949
  return {
6943
6950
  configDir,
6944
- configJson: join2(configDir, "opencode.json"),
6945
- configJsonc: join2(configDir, "opencode.jsonc"),
6946
- packageJson: join2(configDir, "package.json"),
6947
- omoConfig: join2(configDir, "oh-my-opencode.json")
6951
+ configJson: join3(configDir, "opencode.json"),
6952
+ configJsonc: join3(configDir, "opencode.jsonc"),
6953
+ packageJson: join3(configDir, "package.json"),
6954
+ omoConfig: join3(configDir, "oh-my-opencode.json")
6948
6955
  };
6949
6956
  }
6950
6957
  // src/shared/opencode-version.ts
@@ -7029,26 +7036,26 @@ function detectConfigFormat() {
7029
7036
  function isEmptyOrWhitespace(content) {
7030
7037
  return content.trim().length === 0;
7031
7038
  }
7032
- function parseConfigWithError(path2) {
7039
+ function parseConfigWithError(path3) {
7033
7040
  try {
7034
- const stat = statSync(path2);
7041
+ const stat = statSync(path3);
7035
7042
  if (stat.size === 0) {
7036
- return { config: null, error: `Config file is empty: ${path2}. Delete it or add valid JSON content.` };
7043
+ return { config: null, error: `Config file is empty: ${path3}. Delete it or add valid JSON content.` };
7037
7044
  }
7038
- const content = readFileSync2(path2, "utf-8");
7045
+ const content = readFileSync2(path3, "utf-8");
7039
7046
  if (isEmptyOrWhitespace(content)) {
7040
- return { config: null, error: `Config file contains only whitespace: ${path2}. Delete it or add valid JSON content.` };
7047
+ return { config: null, error: `Config file contains only whitespace: ${path3}. Delete it or add valid JSON content.` };
7041
7048
  }
7042
7049
  const config = parseJsonc(content);
7043
7050
  if (config === null || config === undefined) {
7044
- return { config: null, error: `Config file parsed to null/undefined: ${path2}. Ensure it contains valid JSON.` };
7051
+ return { config: null, error: `Config file parsed to null/undefined: ${path3}. Ensure it contains valid JSON.` };
7045
7052
  }
7046
7053
  if (typeof config !== "object" || Array.isArray(config)) {
7047
- return { config: null, error: `Config file must contain a JSON object, not ${Array.isArray(config) ? "an array" : typeof config}: ${path2}` };
7054
+ return { config: null, error: `Config file must contain a JSON object, not ${Array.isArray(config) ? "an array" : typeof config}: ${path3}` };
7048
7055
  }
7049
7056
  return { config };
7050
7057
  } catch (err) {
7051
- return { config: null, error: formatErrorWithSuggestion(err, `parse config file ${path2}`) };
7058
+ return { config: null, error: formatErrorWithSuggestion(err, `parse config file ${path3}`) };
7052
7059
  }
7053
7060
  }
7054
7061
  function ensureConfigDir() {
@@ -7063,27 +7070,27 @@ function addPluginToOpenCodeConfig() {
7063
7070
  } catch (err) {
7064
7071
  return { success: false, configPath: getConfigDir(), error: formatErrorWithSuggestion(err, "create config directory") };
7065
7072
  }
7066
- const { format: format2, path: path2 } = detectConfigFormat();
7073
+ const { format: format2, path: path3 } = detectConfigFormat();
7067
7074
  const pluginName = "oh-my-opencode";
7068
7075
  try {
7069
7076
  if (format2 === "none") {
7070
7077
  const config2 = { plugin: [pluginName] };
7071
- writeFileSync(path2, JSON.stringify(config2, null, 2) + `
7078
+ writeFileSync(path3, JSON.stringify(config2, null, 2) + `
7072
7079
  `);
7073
- return { success: true, configPath: path2 };
7080
+ return { success: true, configPath: path3 };
7074
7081
  }
7075
- const parseResult = parseConfigWithError(path2);
7082
+ const parseResult = parseConfigWithError(path3);
7076
7083
  if (!parseResult.config) {
7077
- return { success: false, configPath: path2, error: parseResult.error ?? "Failed to parse config file" };
7084
+ return { success: false, configPath: path3, error: parseResult.error ?? "Failed to parse config file" };
7078
7085
  }
7079
7086
  const config = parseResult.config;
7080
7087
  const plugins = config.plugin ?? [];
7081
7088
  if (plugins.some((p2) => p2.startsWith(pluginName))) {
7082
- return { success: true, configPath: path2 };
7089
+ return { success: true, configPath: path3 };
7083
7090
  }
7084
7091
  config.plugin = [...plugins, pluginName];
7085
7092
  if (format2 === "jsonc") {
7086
- const content = readFileSync2(path2, "utf-8");
7093
+ const content = readFileSync2(path3, "utf-8");
7087
7094
  const pluginArrayRegex = /"plugin"\s*:\s*\[([\s\S]*?)\]/;
7088
7095
  const match = content.match(pluginArrayRegex);
7089
7096
  if (match) {
@@ -7093,19 +7100,19 @@ function addPluginToOpenCodeConfig() {
7093
7100
  const newContent = content.replace(pluginArrayRegex, `"plugin": [
7094
7101
  ${newArrayContent}
7095
7102
  ]`);
7096
- writeFileSync(path2, newContent);
7103
+ writeFileSync(path3, newContent);
7097
7104
  } else {
7098
7105
  const newContent = content.replace(/^(\s*\{)/, `$1
7099
7106
  "plugin": ["${pluginName}"],`);
7100
- writeFileSync(path2, newContent);
7107
+ writeFileSync(path3, newContent);
7101
7108
  }
7102
7109
  } else {
7103
- writeFileSync(path2, JSON.stringify(config, null, 2) + `
7110
+ writeFileSync(path3, JSON.stringify(config, null, 2) + `
7104
7111
  `);
7105
7112
  }
7106
- return { success: true, configPath: path2 };
7113
+ return { success: true, configPath: path3 };
7107
7114
  } catch (err) {
7108
- return { success: false, configPath: path2, error: formatErrorWithSuggestion(err, "update opencode config") };
7115
+ return { success: false, configPath: path3, error: formatErrorWithSuggestion(err, "update opencode config") };
7109
7116
  }
7110
7117
  }
7111
7118
  function deepMerge(target, source) {
@@ -7158,6 +7165,13 @@ function generateOmoConfig(installConfig) {
7158
7165
  if (Object.keys(agents).length > 0) {
7159
7166
  config.agents = agents;
7160
7167
  }
7168
+ if (installConfig.hasGemini) {
7169
+ config.categories = {
7170
+ "visual-engineering": { model: "google/gemini-3-pro-high" },
7171
+ artistry: { model: "google/gemini-3-pro-high" },
7172
+ writing: { model: "google/gemini-3-flash-high" }
7173
+ };
7174
+ }
7161
7175
  return config;
7162
7176
  }
7163
7177
  function writeOmoConfig(installConfig) {
@@ -7239,11 +7253,11 @@ async function addAuthPlugins(config) {
7239
7253
  } catch (err) {
7240
7254
  return { success: false, configPath: getConfigDir(), error: formatErrorWithSuggestion(err, "create config directory") };
7241
7255
  }
7242
- const { format: format2, path: path2 } = detectConfigFormat();
7256
+ const { format: format2, path: path3 } = detectConfigFormat();
7243
7257
  try {
7244
7258
  let existingConfig = null;
7245
7259
  if (format2 !== "none") {
7246
- const parseResult = parseConfigWithError(path2);
7260
+ const parseResult = parseConfigWithError(path3);
7247
7261
  if (parseResult.error && !parseResult.config) {
7248
7262
  existingConfig = {};
7249
7263
  } else {
@@ -7264,11 +7278,11 @@ async function addAuthPlugins(config) {
7264
7278
  }
7265
7279
  }
7266
7280
  const newConfig = { ...existingConfig ?? {}, plugin: plugins };
7267
- writeFileSync(path2, JSON.stringify(newConfig, null, 2) + `
7281
+ writeFileSync(path3, JSON.stringify(newConfig, null, 2) + `
7268
7282
  `);
7269
- return { success: true, configPath: path2 };
7283
+ return { success: true, configPath: path3 };
7270
7284
  } catch (err) {
7271
- return { success: false, configPath: path2, error: formatErrorWithSuggestion(err, "add auth plugins to config") };
7285
+ return { success: false, configPath: path3, error: formatErrorWithSuggestion(err, "add auth plugins to config") };
7272
7286
  }
7273
7287
  }
7274
7288
  var ANTIGRAVITY_PROVIDER_CONFIG = {
@@ -7352,11 +7366,11 @@ function addProviderConfig(config) {
7352
7366
  } catch (err) {
7353
7367
  return { success: false, configPath: getConfigDir(), error: formatErrorWithSuggestion(err, "create config directory") };
7354
7368
  }
7355
- const { format: format2, path: path2 } = detectConfigFormat();
7369
+ const { format: format2, path: path3 } = detectConfigFormat();
7356
7370
  try {
7357
7371
  let existingConfig = null;
7358
7372
  if (format2 !== "none") {
7359
- const parseResult = parseConfigWithError(path2);
7373
+ const parseResult = parseConfigWithError(path3);
7360
7374
  if (parseResult.error && !parseResult.config) {
7361
7375
  existingConfig = {};
7362
7376
  } else {
@@ -7374,11 +7388,11 @@ function addProviderConfig(config) {
7374
7388
  if (Object.keys(providers).length > 0) {
7375
7389
  newConfig.provider = providers;
7376
7390
  }
7377
- writeFileSync(path2, JSON.stringify(newConfig, null, 2) + `
7391
+ writeFileSync(path3, JSON.stringify(newConfig, null, 2) + `
7378
7392
  `);
7379
- return { success: true, configPath: path2 };
7393
+ return { success: true, configPath: path3 };
7380
7394
  } catch (err) {
7381
- return { success: false, configPath: path2, error: formatErrorWithSuggestion(err, "add provider config") };
7395
+ return { success: false, configPath: path3, error: formatErrorWithSuggestion(err, "add provider config") };
7382
7396
  }
7383
7397
  }
7384
7398
  function detectCurrentConfig() {
@@ -7389,11 +7403,11 @@ function detectCurrentConfig() {
7389
7403
  hasChatGPT: true,
7390
7404
  hasGemini: false
7391
7405
  };
7392
- const { format: format2, path: path2 } = detectConfigFormat();
7406
+ const { format: format2, path: path3 } = detectConfigFormat();
7393
7407
  if (format2 === "none") {
7394
7408
  return result;
7395
7409
  }
7396
- const parseResult = parseConfigWithError(path2);
7410
+ const parseResult = parseConfigWithError(path3);
7397
7411
  if (!parseResult.config) {
7398
7412
  return result;
7399
7413
  }
@@ -8024,7 +8038,7 @@ var serializeObjectParam = ({ allowReserved, explode, name, style, value, valueO
8024
8038
 
8025
8039
  // node_modules/@opencode-ai/sdk/dist/gen/core/utils.gen.js
8026
8040
  var PATH_PARAM_RE = /\{[^{}]+\}/g;
8027
- var defaultPathSerializer = ({ path: path2, url: _url }) => {
8041
+ var defaultPathSerializer = ({ path: path3, url: _url }) => {
8028
8042
  let url = _url;
8029
8043
  const matches = _url.match(PATH_PARAM_RE);
8030
8044
  if (matches) {
@@ -8043,7 +8057,7 @@ var defaultPathSerializer = ({ path: path2, url: _url }) => {
8043
8057
  name = name.substring(1);
8044
8058
  style = "matrix";
8045
8059
  }
8046
- const value = path2[name];
8060
+ const value = path3[name];
8047
8061
  if (value === undefined || value === null) {
8048
8062
  continue;
8049
8063
  }
@@ -8074,11 +8088,11 @@ var defaultPathSerializer = ({ path: path2, url: _url }) => {
8074
8088
  }
8075
8089
  return url;
8076
8090
  };
8077
- var getUrl = ({ baseUrl, path: path2, query, querySerializer, url: _url }) => {
8091
+ var getUrl = ({ baseUrl, path: path3, query, querySerializer, url: _url }) => {
8078
8092
  const pathUrl = _url.startsWith("/") ? _url : `/${_url}`;
8079
8093
  let url = (baseUrl ?? "") + pathUrl;
8080
- if (path2) {
8081
- url = defaultPathSerializer({ path: path2, url });
8094
+ if (path3) {
8095
+ url = defaultPathSerializer({ path: path3, url });
8082
8096
  }
8083
8097
  let search = query ? querySerializer(query) : "";
8084
8098
  if (search.startsWith("?")) {
@@ -9590,49 +9604,49 @@ All tasks completed.`));
9590
9604
  }
9591
9605
  // src/hooks/auto-update-checker/checker.ts
9592
9606
  import * as fs3 from "fs";
9593
- import * as path3 from "path";
9607
+ import * as path4 from "path";
9594
9608
  import { fileURLToPath } from "url";
9595
9609
 
9596
9610
  // src/hooks/auto-update-checker/constants.ts
9597
- import * as path2 from "path";
9598
- import * as os2 from "os";
9611
+ import * as path3 from "path";
9612
+ import * as os3 from "os";
9599
9613
  import * as fs2 from "fs";
9600
9614
  var PACKAGE_NAME = "oh-my-opencode";
9601
9615
  var NPM_REGISTRY_URL = `https://registry.npmjs.org/-/package/${PACKAGE_NAME}/dist-tags`;
9602
9616
  var NPM_FETCH_TIMEOUT = 5000;
9603
9617
  function getCacheDir() {
9604
9618
  if (process.platform === "win32") {
9605
- return path2.join(process.env.LOCALAPPDATA ?? os2.homedir(), "opencode");
9619
+ return path3.join(process.env.LOCALAPPDATA ?? os3.homedir(), "opencode");
9606
9620
  }
9607
- return path2.join(os2.homedir(), ".cache", "opencode");
9621
+ return path3.join(os3.homedir(), ".cache", "opencode");
9608
9622
  }
9609
9623
  var CACHE_DIR = getCacheDir();
9610
- var VERSION_FILE = path2.join(CACHE_DIR, "version");
9611
- var INSTALLED_PACKAGE_JSON = path2.join(CACHE_DIR, "node_modules", PACKAGE_NAME, "package.json");
9624
+ var VERSION_FILE = path3.join(CACHE_DIR, "version");
9625
+ var INSTALLED_PACKAGE_JSON = path3.join(CACHE_DIR, "node_modules", PACKAGE_NAME, "package.json");
9612
9626
  function getUserConfigDir() {
9613
9627
  if (process.platform === "win32") {
9614
- const crossPlatformDir = path2.join(os2.homedir(), ".config");
9615
- const appdataDir = process.env.APPDATA ?? path2.join(os2.homedir(), "AppData", "Roaming");
9616
- const crossPlatformConfig = path2.join(crossPlatformDir, "opencode", "opencode.json");
9617
- const crossPlatformConfigJsonc = path2.join(crossPlatformDir, "opencode", "opencode.jsonc");
9628
+ const crossPlatformDir = path3.join(os3.homedir(), ".config");
9629
+ const appdataDir = process.env.APPDATA ?? path3.join(os3.homedir(), "AppData", "Roaming");
9630
+ const crossPlatformConfig = path3.join(crossPlatformDir, "opencode", "opencode.json");
9631
+ const crossPlatformConfigJsonc = path3.join(crossPlatformDir, "opencode", "opencode.jsonc");
9618
9632
  if (fs2.existsSync(crossPlatformConfig) || fs2.existsSync(crossPlatformConfigJsonc)) {
9619
9633
  return crossPlatformDir;
9620
9634
  }
9621
9635
  return appdataDir;
9622
9636
  }
9623
- return process.env.XDG_CONFIG_HOME ?? path2.join(os2.homedir(), ".config");
9637
+ return process.env.XDG_CONFIG_HOME ?? path3.join(os3.homedir(), ".config");
9624
9638
  }
9625
9639
  function getWindowsAppdataDir() {
9626
9640
  if (process.platform !== "win32")
9627
9641
  return null;
9628
- return process.env.APPDATA ?? path2.join(os2.homedir(), "AppData", "Roaming");
9642
+ return process.env.APPDATA ?? path3.join(os3.homedir(), "AppData", "Roaming");
9629
9643
  }
9630
9644
  var USER_CONFIG_DIR = getUserConfigDir();
9631
- var USER_OPENCODE_CONFIG = path2.join(USER_CONFIG_DIR, "opencode", "opencode.json");
9632
- var USER_OPENCODE_CONFIG_JSONC = path2.join(USER_CONFIG_DIR, "opencode", "opencode.jsonc");
9645
+ var USER_OPENCODE_CONFIG = path3.join(USER_CONFIG_DIR, "opencode", "opencode.json");
9646
+ var USER_OPENCODE_CONFIG_JSONC = path3.join(USER_CONFIG_DIR, "opencode", "opencode.jsonc");
9633
9647
 
9634
9648
  // src/hooks/auto-update-checker/checker.ts
9635
- import * as os3 from "os";
9649
+ import * as os4 from "os";
9636
9650
  function isLocalDevMode(directory) {
9637
9651
  return getLocalDevPath(directory) !== null;
9638
9652
  }
@@ -9641,18 +9655,18 @@ function stripJsonComments(json2) {
9641
9655
  }
9642
9656
  function getConfigPaths(directory) {
9643
9657
  const paths = [
9644
- path3.join(directory, ".opencode", "opencode.json"),
9645
- path3.join(directory, ".opencode", "opencode.jsonc"),
9658
+ path4.join(directory, ".opencode", "opencode.json"),
9659
+ path4.join(directory, ".opencode", "opencode.jsonc"),
9646
9660
  USER_OPENCODE_CONFIG,
9647
9661
  USER_OPENCODE_CONFIG_JSONC
9648
9662
  ];
9649
9663
  if (process.platform === "win32") {
9650
- const crossPlatformDir = path3.join(os3.homedir(), ".config");
9664
+ const crossPlatformDir = path4.join(os4.homedir(), ".config");
9651
9665
  const appdataDir = getWindowsAppdataDir();
9652
9666
  if (appdataDir) {
9653
9667
  const alternateDir = USER_CONFIG_DIR === crossPlatformDir ? appdataDir : crossPlatformDir;
9654
- const alternateConfig = path3.join(alternateDir, "opencode", "opencode.json");
9655
- const alternateConfigJsonc = path3.join(alternateDir, "opencode", "opencode.jsonc");
9668
+ const alternateConfig = path4.join(alternateDir, "opencode", "opencode.json");
9669
+ const alternateConfigJsonc = path4.join(alternateDir, "opencode", "opencode.jsonc");
9656
9670
  if (!paths.includes(alternateConfig)) {
9657
9671
  paths.push(alternateConfig);
9658
9672
  }
@@ -9689,9 +9703,9 @@ function getLocalDevPath(directory) {
9689
9703
  function findPackageJsonUp(startPath) {
9690
9704
  try {
9691
9705
  const stat = fs3.statSync(startPath);
9692
- let dir = stat.isDirectory() ? startPath : path3.dirname(startPath);
9706
+ let dir = stat.isDirectory() ? startPath : path4.dirname(startPath);
9693
9707
  for (let i2 = 0;i2 < 10; i2++) {
9694
- const pkgPath = path3.join(dir, "package.json");
9708
+ const pkgPath = path4.join(dir, "package.json");
9695
9709
  if (fs3.existsSync(pkgPath)) {
9696
9710
  try {
9697
9711
  const content = fs3.readFileSync(pkgPath, "utf-8");
@@ -9700,7 +9714,7 @@ function findPackageJsonUp(startPath) {
9700
9714
  return pkgPath;
9701
9715
  } catch {}
9702
9716
  }
9703
- const parent = path3.dirname(dir);
9717
+ const parent = path4.dirname(dir);
9704
9718
  if (parent === dir)
9705
9719
  break;
9706
9720
  dir = parent;
@@ -9742,7 +9756,7 @@ function getCachedVersion() {
9742
9756
  }
9743
9757
  } catch {}
9744
9758
  try {
9745
- const currentDir = path3.dirname(fileURLToPath(import.meta.url));
9759
+ const currentDir = path4.dirname(fileURLToPath(import.meta.url));
9746
9760
  const pkgPath = findPackageJsonUp(currentDir);
9747
9761
  if (pkgPath) {
9748
9762
  const content = fs3.readFileSync(pkgPath, "utf-8");
@@ -10199,8 +10213,8 @@ function getPluginCheckDefinition() {
10199
10213
 
10200
10214
  // src/cli/doctor/checks/config.ts
10201
10215
  import { existsSync as existsSync7, readFileSync as readFileSync5 } from "fs";
10202
- import { homedir as homedir4 } from "os";
10203
- import { join as join5 } from "path";
10216
+ import { homedir as homedir5 } from "os";
10217
+ import { join as join6 } from "path";
10204
10218
 
10205
10219
  // node_modules/zod/v4/classic/external.js
10206
10220
  var exports_external = {};
@@ -10931,10 +10945,10 @@ function mergeDefs(...defs) {
10931
10945
  function cloneDef(schema2) {
10932
10946
  return mergeDefs(schema2._zod.def);
10933
10947
  }
10934
- function getElementAtPath(obj, path4) {
10935
- if (!path4)
10948
+ function getElementAtPath(obj, path5) {
10949
+ if (!path5)
10936
10950
  return obj;
10937
- return path4.reduce((acc, key) => acc?.[key], obj);
10951
+ return path5.reduce((acc, key) => acc?.[key], obj);
10938
10952
  }
10939
10953
  function promiseAllObject(promisesObj) {
10940
10954
  const keys = Object.keys(promisesObj);
@@ -11293,11 +11307,11 @@ function aborted(x2, startIndex = 0) {
11293
11307
  }
11294
11308
  return false;
11295
11309
  }
11296
- function prefixIssues(path4, issues) {
11310
+ function prefixIssues(path5, issues) {
11297
11311
  return issues.map((iss) => {
11298
11312
  var _a;
11299
11313
  (_a = iss).path ?? (_a.path = []);
11300
- iss.path.unshift(path4);
11314
+ iss.path.unshift(path5);
11301
11315
  return iss;
11302
11316
  });
11303
11317
  }
@@ -11465,7 +11479,7 @@ function treeifyError(error, _mapper) {
11465
11479
  return issue2.message;
11466
11480
  };
11467
11481
  const result = { errors: [] };
11468
- const processError = (error2, path4 = []) => {
11482
+ const processError = (error2, path5 = []) => {
11469
11483
  var _a, _b;
11470
11484
  for (const issue2 of error2.issues) {
11471
11485
  if (issue2.code === "invalid_union" && issue2.errors.length) {
@@ -11475,7 +11489,7 @@ function treeifyError(error, _mapper) {
11475
11489
  } else if (issue2.code === "invalid_element") {
11476
11490
  processError({ issues: issue2.issues }, issue2.path);
11477
11491
  } else {
11478
- const fullpath = [...path4, ...issue2.path];
11492
+ const fullpath = [...path5, ...issue2.path];
11479
11493
  if (fullpath.length === 0) {
11480
11494
  result.errors.push(mapper(issue2));
11481
11495
  continue;
@@ -11507,8 +11521,8 @@ function treeifyError(error, _mapper) {
11507
11521
  }
11508
11522
  function toDotPath(_path) {
11509
11523
  const segs = [];
11510
- const path4 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
11511
- for (const seg of path4) {
11524
+ const path5 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
11525
+ for (const seg of path5) {
11512
11526
  if (typeof seg === "number")
11513
11527
  segs.push(`[${seg}]`);
11514
11528
  else if (typeof seg === "symbol")
@@ -22518,7 +22532,7 @@ function date4(params) {
22518
22532
  // node_modules/zod/v4/classic/external.js
22519
22533
  config(en_default());
22520
22534
  // src/mcp/types.ts
22521
- var McpNameSchema = exports_external.enum(["context7", "grep_app"]);
22535
+ var McpNameSchema = exports_external.enum(["websearch", "context7", "grep_app"]);
22522
22536
  var AnyMcpNameSchema = exports_external.string().min(1);
22523
22537
 
22524
22538
  // src/config/schema.ts
@@ -22541,17 +22555,21 @@ var BuiltinAgentNameSchema = exports_external.enum([
22541
22555
  "explore",
22542
22556
  "frontend-ui-ux-engineer",
22543
22557
  "document-writer",
22544
- "multimodal-looker"
22558
+ "multimodal-looker",
22559
+ "Metis (Plan Consultant)"
22545
22560
  ]);
22546
22561
  var BuiltinSkillNameSchema = exports_external.enum([
22547
- "playwright"
22562
+ "playwright",
22563
+ "frontend-ui-ux",
22564
+ "git-master"
22548
22565
  ]);
22549
22566
  var OverridableAgentNameSchema = exports_external.enum([
22550
22567
  "build",
22551
22568
  "plan",
22552
22569
  "Sisyphus",
22553
22570
  "OpenCode-Builder",
22554
- "Planner-Sisyphus",
22571
+ "Prometheus (Planner)",
22572
+ "Metis (Plan Consultant)",
22555
22573
  "oracle",
22556
22574
  "librarian",
22557
22575
  "explore",
@@ -22587,13 +22605,19 @@ var HookNameSchema = exports_external.enum([
22587
22605
  "compaction-context-injector",
22588
22606
  "claude-code-hooks",
22589
22607
  "auto-slash-command",
22590
- "edit-error-recovery"
22608
+ "edit-error-recovery",
22609
+ "prometheus-md-only",
22610
+ "start-work",
22611
+ "sisyphus-orchestrator"
22591
22612
  ]);
22592
22613
  var BuiltinCommandNameSchema = exports_external.enum([
22593
- "init-deep"
22614
+ "init-deep",
22615
+ "start-work"
22594
22616
  ]);
22595
22617
  var AgentOverrideConfigSchema = exports_external.object({
22596
22618
  model: exports_external.string().optional(),
22619
+ category: exports_external.string().optional(),
22620
+ skills: exports_external.array(exports_external.string()).optional(),
22597
22621
  temperature: exports_external.number().min(0).max(2).optional(),
22598
22622
  top_p: exports_external.number().min(0).max(1).optional(),
22599
22623
  prompt: exports_external.string().optional(),
@@ -22610,7 +22634,8 @@ var AgentOverridesSchema = exports_external.object({
22610
22634
  plan: AgentOverrideConfigSchema.optional(),
22611
22635
  Sisyphus: AgentOverrideConfigSchema.optional(),
22612
22636
  "OpenCode-Builder": AgentOverrideConfigSchema.optional(),
22613
- "Planner-Sisyphus": AgentOverrideConfigSchema.optional(),
22637
+ "Prometheus (Planner)": AgentOverrideConfigSchema.optional(),
22638
+ "Metis (Plan Consultant)": AgentOverrideConfigSchema.optional(),
22614
22639
  oracle: AgentOverrideConfigSchema.optional(),
22615
22640
  librarian: AgentOverrideConfigSchema.optional(),
22616
22641
  explore: AgentOverrideConfigSchema.optional(),
@@ -22633,6 +22658,30 @@ var SisyphusAgentConfigSchema = exports_external.object({
22633
22658
  planner_enabled: exports_external.boolean().optional(),
22634
22659
  replace_plan: exports_external.boolean().optional()
22635
22660
  });
22661
+ var CategoryConfigSchema = exports_external.object({
22662
+ model: exports_external.string(),
22663
+ temperature: exports_external.number().min(0).max(2).optional(),
22664
+ top_p: exports_external.number().min(0).max(1).optional(),
22665
+ maxTokens: exports_external.number().optional(),
22666
+ thinking: exports_external.object({
22667
+ type: exports_external.enum(["enabled", "disabled"]),
22668
+ budgetTokens: exports_external.number().optional()
22669
+ }).optional(),
22670
+ reasoningEffort: exports_external.enum(["low", "medium", "high"]).optional(),
22671
+ textVerbosity: exports_external.enum(["low", "medium", "high"]).optional(),
22672
+ tools: exports_external.record(exports_external.string(), exports_external.boolean()).optional(),
22673
+ prompt_append: exports_external.string().optional()
22674
+ });
22675
+ var BuiltinCategoryNameSchema = exports_external.enum([
22676
+ "visual-engineering",
22677
+ "ultrabrain",
22678
+ "artistry",
22679
+ "quick",
22680
+ "most-capable",
22681
+ "writing",
22682
+ "general"
22683
+ ]);
22684
+ var CategoriesConfigSchema = exports_external.record(exports_external.string(), CategoryConfigSchema);
22636
22685
  var CommentCheckerConfigSchema = exports_external.object({
22637
22686
  custom_prompt: exports_external.string().optional()
22638
22687
  });
@@ -22715,6 +22764,18 @@ var RalphLoopConfigSchema = exports_external.object({
22715
22764
  default_max_iterations: exports_external.number().min(1).max(1000).default(100),
22716
22765
  state_dir: exports_external.string().optional()
22717
22766
  });
22767
+ var BackgroundTaskConfigSchema = exports_external.object({
22768
+ defaultConcurrency: exports_external.number().min(1).optional(),
22769
+ providerConcurrency: exports_external.record(exports_external.string(), exports_external.number().min(1)).optional(),
22770
+ modelConcurrency: exports_external.record(exports_external.string(), exports_external.number().min(1)).optional()
22771
+ });
22772
+ var NotificationConfigSchema = exports_external.object({
22773
+ force_enable: exports_external.boolean().optional()
22774
+ });
22775
+ var GitMasterConfigSchema = exports_external.object({
22776
+ commit_footer: exports_external.boolean().default(true),
22777
+ include_co_authored_by: exports_external.boolean().default(true)
22778
+ });
22718
22779
  var OhMyOpenCodeConfigSchema = exports_external.object({
22719
22780
  $schema: exports_external.string().optional(),
22720
22781
  disabled_mcps: exports_external.array(AnyMcpNameSchema).optional(),
@@ -22723,6 +22784,7 @@ var OhMyOpenCodeConfigSchema = exports_external.object({
22723
22784
  disabled_hooks: exports_external.array(HookNameSchema).optional(),
22724
22785
  disabled_commands: exports_external.array(BuiltinCommandNameSchema).optional(),
22725
22786
  agents: AgentOverridesSchema.optional(),
22787
+ categories: CategoriesConfigSchema.optional(),
22726
22788
  claude_code: ClaudeCodeConfigSchema.optional(),
22727
22789
  google_auth: exports_external.boolean().optional(),
22728
22790
  sisyphus_agent: SisyphusAgentConfigSchema.optional(),
@@ -22730,12 +22792,15 @@ var OhMyOpenCodeConfigSchema = exports_external.object({
22730
22792
  experimental: ExperimentalConfigSchema.optional(),
22731
22793
  auto_update: exports_external.boolean().optional(),
22732
22794
  skills: SkillsConfigSchema.optional(),
22733
- ralph_loop: RalphLoopConfigSchema.optional()
22795
+ ralph_loop: RalphLoopConfigSchema.optional(),
22796
+ background_task: BackgroundTaskConfigSchema.optional(),
22797
+ notification: NotificationConfigSchema.optional(),
22798
+ git_master: GitMasterConfigSchema.optional()
22734
22799
  });
22735
22800
  // src/cli/doctor/checks/config.ts
22736
- var USER_CONFIG_DIR2 = join5(homedir4(), ".config", "opencode");
22737
- var USER_CONFIG_BASE = join5(USER_CONFIG_DIR2, `${PACKAGE_NAME2}`);
22738
- var PROJECT_CONFIG_BASE = join5(process.cwd(), ".opencode", PACKAGE_NAME2);
22801
+ var USER_CONFIG_DIR2 = join6(homedir5(), ".config", "opencode");
22802
+ var USER_CONFIG_BASE = join6(USER_CONFIG_DIR2, `${PACKAGE_NAME2}`);
22803
+ var PROJECT_CONFIG_BASE = join6(process.cwd(), ".opencode", PACKAGE_NAME2);
22739
22804
  function findConfigPath() {
22740
22805
  const projectDetected = detectConfigFile(PROJECT_CONFIG_BASE);
22741
22806
  if (projectDetected.format !== "none") {
@@ -22833,11 +22898,11 @@ function getConfigCheckDefinition() {
22833
22898
 
22834
22899
  // src/cli/doctor/checks/auth.ts
22835
22900
  import { existsSync as existsSync8, readFileSync as readFileSync6 } from "fs";
22836
- import { homedir as homedir5 } from "os";
22837
- import { join as join6 } from "path";
22838
- var OPENCODE_CONFIG_DIR = join6(homedir5(), ".config", "opencode");
22839
- var OPENCODE_JSON = join6(OPENCODE_CONFIG_DIR, "opencode.json");
22840
- var OPENCODE_JSONC = join6(OPENCODE_CONFIG_DIR, "opencode.jsonc");
22901
+ import { homedir as homedir6 } from "os";
22902
+ import { join as join7 } from "path";
22903
+ var OPENCODE_CONFIG_DIR = join7(homedir6(), ".config", "opencode");
22904
+ var OPENCODE_JSON = join7(OPENCODE_CONFIG_DIR, "opencode.json");
22905
+ var OPENCODE_JSONC = join7(OPENCODE_CONFIG_DIR, "opencode.jsonc");
22841
22906
  var AUTH_PLUGINS = {
22842
22907
  anthropic: { plugin: "builtin", name: "Anthropic (Claude)" },
22843
22908
  openai: { plugin: "opencode-openai-codex-auth", name: "OpenAI (ChatGPT)" },
@@ -23278,13 +23343,13 @@ function getLspCheckDefinition() {
23278
23343
 
23279
23344
  // src/cli/doctor/checks/mcp.ts
23280
23345
  import { existsSync as existsSync9, readFileSync as readFileSync7 } from "fs";
23281
- import { homedir as homedir6 } from "os";
23282
- import { join as join7 } from "path";
23346
+ import { homedir as homedir7 } from "os";
23347
+ import { join as join8 } from "path";
23283
23348
  var BUILTIN_MCP_SERVERS = ["context7", "grep_app"];
23284
23349
  var MCP_CONFIG_PATHS = [
23285
- join7(homedir6(), ".claude", ".mcp.json"),
23286
- join7(process.cwd(), ".mcp.json"),
23287
- join7(process.cwd(), ".claude", ".mcp.json")
23350
+ join8(homedir7(), ".claude", ".mcp.json"),
23351
+ join8(process.cwd(), ".mcp.json"),
23352
+ join8(process.cwd(), ".claude", ".mcp.json")
23288
23353
  ];
23289
23354
  function loadUserMcpConfig() {
23290
23355
  const servers = {};
@@ -23683,6 +23748,140 @@ async function doctor(options = {}) {
23683
23748
  return result.exitCode;
23684
23749
  }
23685
23750
 
23751
+ // src/auth/antigravity/storage.ts
23752
+ import { promises as fs4 } from "fs";
23753
+ import { join as join9, dirname as dirname2 } from "path";
23754
+ function getDataDir2() {
23755
+ return join9(getDataDir(), "opencode");
23756
+ }
23757
+ function getStoragePath() {
23758
+ return join9(getDataDir2(), "oh-my-opencode-accounts.json");
23759
+ }
23760
+ async function loadAccounts(path5) {
23761
+ const storagePath = path5 ?? getStoragePath();
23762
+ try {
23763
+ const content = await fs4.readFile(storagePath, "utf-8");
23764
+ const data = JSON.parse(content);
23765
+ if (!isValidAccountStorage(data)) {
23766
+ return null;
23767
+ }
23768
+ return data;
23769
+ } catch (error45) {
23770
+ const errorCode = error45.code;
23771
+ if (errorCode === "ENOENT") {
23772
+ return null;
23773
+ }
23774
+ if (error45 instanceof SyntaxError) {
23775
+ return null;
23776
+ }
23777
+ throw error45;
23778
+ }
23779
+ }
23780
+ async function saveAccounts(storage, path5) {
23781
+ const storagePath = path5 ?? getStoragePath();
23782
+ await fs4.mkdir(dirname2(storagePath), { recursive: true });
23783
+ const content = JSON.stringify(storage, null, 2);
23784
+ const tempPath = `${storagePath}.tmp.${process.pid}.${Date.now()}`;
23785
+ await fs4.writeFile(tempPath, content, { encoding: "utf-8", mode: 384 });
23786
+ try {
23787
+ await fs4.rename(tempPath, storagePath);
23788
+ } catch (error45) {
23789
+ await fs4.unlink(tempPath).catch(() => {});
23790
+ throw error45;
23791
+ }
23792
+ }
23793
+ function isValidAccountStorage(data) {
23794
+ if (typeof data !== "object" || data === null) {
23795
+ return false;
23796
+ }
23797
+ const obj = data;
23798
+ if (typeof obj.version !== "number") {
23799
+ return false;
23800
+ }
23801
+ if (!Array.isArray(obj.accounts)) {
23802
+ return false;
23803
+ }
23804
+ if (typeof obj.activeIndex !== "number") {
23805
+ return false;
23806
+ }
23807
+ return true;
23808
+ }
23809
+
23810
+ // src/cli/commands/auth.ts
23811
+ async function listAccounts() {
23812
+ const accounts = await loadAccounts();
23813
+ if (!accounts || accounts.accounts.length === 0) {
23814
+ console.log("No accounts found.");
23815
+ console.log("Run 'opencode auth login' and select Google (Antigravity) to add accounts.");
23816
+ return 0;
23817
+ }
23818
+ console.log(`
23819
+ Google Antigravity Accounts (${accounts.accounts.length}/10):
23820
+ `);
23821
+ for (let i2 = 0;i2 < accounts.accounts.length; i2++) {
23822
+ const acc = accounts.accounts[i2];
23823
+ const isActive = i2 === accounts.activeIndex;
23824
+ const activeMarker = isActive ? "* " : " ";
23825
+ console.log(`${activeMarker}[${i2}] ${acc.email || "Unknown"}`);
23826
+ console.log(` Tier: ${acc.tier || "free"}`);
23827
+ const rateLimits = acc.rateLimits || {};
23828
+ const now = Date.now();
23829
+ const limited = [];
23830
+ if (rateLimits.claude && rateLimits.claude > now) {
23831
+ const mins = Math.ceil((rateLimits.claude - now) / 60000);
23832
+ limited.push(`claude (${mins}m)`);
23833
+ }
23834
+ if (rateLimits["gemini-flash"] && rateLimits["gemini-flash"] > now) {
23835
+ const mins = Math.ceil((rateLimits["gemini-flash"] - now) / 60000);
23836
+ limited.push(`gemini-flash (${mins}m)`);
23837
+ }
23838
+ if (rateLimits["gemini-pro"] && rateLimits["gemini-pro"] > now) {
23839
+ const mins = Math.ceil((rateLimits["gemini-pro"] - now) / 60000);
23840
+ limited.push(`gemini-pro (${mins}m)`);
23841
+ }
23842
+ if (limited.length > 0) {
23843
+ console.log(` Rate limited: ${limited.join(", ")}`);
23844
+ }
23845
+ console.log();
23846
+ }
23847
+ return 0;
23848
+ }
23849
+ async function removeAccount(indexOrEmail) {
23850
+ const accounts = await loadAccounts();
23851
+ if (!accounts || accounts.accounts.length === 0) {
23852
+ console.error("No accounts found.");
23853
+ return 1;
23854
+ }
23855
+ let index;
23856
+ const parsedIndex = Number(indexOrEmail);
23857
+ if (Number.isInteger(parsedIndex) && String(parsedIndex) === indexOrEmail) {
23858
+ index = parsedIndex;
23859
+ } else {
23860
+ index = accounts.accounts.findIndex((acc) => acc.email === indexOrEmail);
23861
+ if (index === -1) {
23862
+ console.error(`Account not found: ${indexOrEmail}`);
23863
+ return 1;
23864
+ }
23865
+ }
23866
+ if (index < 0 || index >= accounts.accounts.length) {
23867
+ console.error(`Invalid index: ${index}. Valid range: 0-${accounts.accounts.length - 1}`);
23868
+ return 1;
23869
+ }
23870
+ const removed = accounts.accounts[index];
23871
+ accounts.accounts.splice(index, 1);
23872
+ if (accounts.accounts.length === 0) {
23873
+ accounts.activeIndex = -1;
23874
+ } else if (accounts.activeIndex >= accounts.accounts.length) {
23875
+ accounts.activeIndex = accounts.accounts.length - 1;
23876
+ } else if (accounts.activeIndex > index) {
23877
+ accounts.activeIndex--;
23878
+ }
23879
+ await saveAccounts(accounts);
23880
+ console.log(`Removed account: ${removed.email || "Unknown"} (index ${index})`);
23881
+ console.log(`Remaining accounts: ${accounts.accounts.length}`);
23882
+ return 0;
23883
+ }
23884
+
23686
23885
  // src/cli/index.ts
23687
23886
  var packageJson = await Promise.resolve().then(() => __toESM(require_package(), 1));
23688
23887
  var VERSION = packageJson.version;
@@ -23770,6 +23969,32 @@ Categories:
23770
23969
  const exitCode = await doctor(doctorOptions);
23771
23970
  process.exit(exitCode);
23772
23971
  });
23972
+ var authCommand = program2.command("auth").description("Manage Google Antigravity accounts");
23973
+ authCommand.command("list").description("List all Google Antigravity accounts").addHelpText("after", `
23974
+ Examples:
23975
+ $ bunx oh-my-opencode auth list
23976
+
23977
+ Shows:
23978
+ - Account index and email
23979
+ - Account tier (free/paid)
23980
+ - Active account (marked with *)
23981
+ - Rate limit status per model family
23982
+ `).action(async () => {
23983
+ const exitCode = await listAccounts();
23984
+ process.exit(exitCode);
23985
+ });
23986
+ authCommand.command("remove <index-or-email>").description("Remove an account by index or email").addHelpText("after", `
23987
+ Examples:
23988
+ $ bunx oh-my-opencode auth remove 0
23989
+ $ bunx oh-my-opencode auth remove user@example.com
23990
+
23991
+ Note:
23992
+ - Use 'auth list' to see account indices
23993
+ - Removing the active account will switch to the next available account
23994
+ `).action(async (indexOrEmail) => {
23995
+ const exitCode = await removeAccount(indexOrEmail);
23996
+ process.exit(exitCode);
23997
+ });
23773
23998
  program2.command("version").description("Show version information").action(() => {
23774
23999
  console.log(`oh-my-opencode v${VERSION}`);
23775
24000
  });