@reinamaccredy/oh-my-opencode 3.0.0-beta.8 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/README.ja.md +4 -4
  2. package/README.md +5 -5
  3. package/README.zh-cn.md +4 -4
  4. package/dist/agents/types.d.ts +2 -0
  5. package/dist/cli/config-manager.d.ts +3 -17
  6. package/dist/cli/index.js +390 -359
  7. package/dist/cli/types.d.ts +3 -1
  8. package/dist/config/index.d.ts +2 -2
  9. package/dist/config/schema.d.ts +215 -181
  10. package/dist/features/background-agent/index.d.ts +1 -1
  11. package/dist/features/background-agent/manager.d.ts +10 -0
  12. package/dist/features/background-agent/types.d.ts +4 -0
  13. package/dist/features/boulder-state/index.d.ts +1 -0
  14. package/dist/features/boulder-state/unified-state.d.ts +86 -0
  15. package/dist/features/maestro/hooks/index.d.ts +16 -0
  16. package/dist/features/maestro/index.d.ts +4 -0
  17. package/dist/features/maestro/skills/index.d.ts +4 -0
  18. package/dist/features/maestro/types.d.ts +42 -0
  19. package/dist/features/maestro/utils/index.d.ts +4 -0
  20. package/dist/features/workflow-engine/contracts/v1/types.d.ts +9 -0
  21. package/dist/hooks/background-notification/index.d.ts +10 -0
  22. package/dist/hooks/index.d.ts +3 -0
  23. package/dist/hooks/maestro-sisyphus-bridge/constants.d.ts +9 -0
  24. package/dist/hooks/maestro-sisyphus-bridge/index.d.ts +53 -0
  25. package/dist/hooks/tdd-enforcement/constants.d.ts +16 -0
  26. package/dist/hooks/tdd-enforcement/index.d.ts +54 -0
  27. package/dist/index.js +1955 -6035
  28. package/dist/shared/migration.d.ts +13 -0
  29. package/dist/tools/skill/tools.d.ts +1 -7
  30. package/dist/tools/slashcommand/tools.d.ts +1 -7
  31. package/package.json +7 -6
  32. package/dist/auth/antigravity/accounts.d.ts +0 -40
  33. package/dist/auth/antigravity/accounts.test.d.ts +0 -1
  34. package/dist/auth/antigravity/browser.d.ts +0 -27
  35. package/dist/auth/antigravity/browser.test.d.ts +0 -1
  36. package/dist/auth/antigravity/cli.d.ts +0 -2
  37. package/dist/auth/antigravity/cli.test.d.ts +0 -1
  38. package/dist/auth/antigravity/constants.d.ts +0 -98
  39. package/dist/auth/antigravity/constants.test.d.ts +0 -1
  40. package/dist/auth/antigravity/fetch.d.ts +0 -69
  41. package/dist/auth/antigravity/index.d.ts +0 -13
  42. package/dist/auth/antigravity/integration.test.d.ts +0 -10
  43. package/dist/auth/antigravity/message-converter.d.ts +0 -54
  44. package/dist/auth/antigravity/oauth.d.ts +0 -51
  45. package/dist/auth/antigravity/oauth.test.d.ts +0 -1
  46. package/dist/auth/antigravity/plugin.d.ts +0 -54
  47. package/dist/auth/antigravity/project.d.ts +0 -10
  48. package/dist/auth/antigravity/request.d.ts +0 -116
  49. package/dist/auth/antigravity/request.test.d.ts +0 -1
  50. package/dist/auth/antigravity/response.d.ts +0 -137
  51. package/dist/auth/antigravity/storage.d.ts +0 -5
  52. package/dist/auth/antigravity/storage.test.d.ts +0 -1
  53. package/dist/auth/antigravity/thinking.d.ts +0 -278
  54. package/dist/auth/antigravity/thinking.test.d.ts +0 -10
  55. package/dist/auth/antigravity/thought-signature-store.d.ts +0 -52
  56. package/dist/auth/antigravity/token.d.ts +0 -38
  57. package/dist/auth/antigravity/token.test.d.ts +0 -1
  58. package/dist/auth/antigravity/tools.d.ts +0 -119
  59. package/dist/auth/antigravity/types.d.ts +0 -229
  60. package/dist/cli/commands/auth.d.ts +0 -2
  61. package/dist/cli/config-manager.test.d.ts +0 -1
  62. package/dist/google-auth.d.ts +0 -3
  63. package/dist/google-auth.js +0 -3871
package/dist/cli/index.js CHANGED
@@ -2253,7 +2253,7 @@ var require_picocolors = __commonJS((exports, module) => {
2253
2253
  var require_package = __commonJS((exports, module) => {
2254
2254
  module.exports = {
2255
2255
  name: "@reinamaccredy/oh-my-opencode",
2256
- version: "3.0.0-beta.8",
2256
+ version: "3.0.0",
2257
2257
  description: "Fork of oh-my-opencode with Maestro workflow integration - Multi-Model Orchestration, Parallel Background Agents, Design Phases, and TDD Methodology",
2258
2258
  main: "dist/index.js",
2259
2259
  types: "dist/index.d.ts",
@@ -2270,17 +2270,17 @@ var require_package = __commonJS((exports, module) => {
2270
2270
  types: "./dist/index.d.ts",
2271
2271
  import: "./dist/index.js"
2272
2272
  },
2273
- "./google-auth": {
2274
- types: "./dist/google-auth.d.ts",
2275
- import: "./dist/google-auth.js"
2276
- },
2277
2273
  "./schema.json": "./dist/oh-my-opencode.schema.json"
2278
2274
  },
2279
2275
  scripts: {
2280
- build: "bun build src/index.ts src/google-auth.ts --outdir dist --target bun --format esm --external @ast-grep/napi && tsc --emitDeclarationOnly && bun build src/cli/index.ts --outdir dist/cli --target bun --format esm --external @ast-grep/napi && bun run build:schema",
2276
+ build: "bun build src/index.ts --outdir dist --target bun --format esm --external @ast-grep/napi && tsc --emitDeclarationOnly && bun build src/cli/index.ts --outdir dist/cli --target bun --format esm --external @ast-grep/napi && bun run build:schema",
2281
2277
  "build:schema": "bun run script/build-schema.ts",
2282
2278
  clean: "rm -rf dist",
2283
2279
  prepublishOnly: "bun run clean && bun run build",
2280
+ "publish:beta": "./scripts/publish.sh prerelease",
2281
+ "publish:patch": "./scripts/publish.sh patch",
2282
+ "publish:minor": "./scripts/publish.sh minor",
2283
+ "publish:major": "./scripts/publish.sh major",
2284
2284
  typecheck: "tsc --noEmit",
2285
2285
  test: "bun test"
2286
2286
  },
@@ -2317,6 +2317,7 @@ var require_package = __commonJS((exports, module) => {
2317
2317
  "@openauthjs/openauth": "^0.4.3",
2318
2318
  "@opencode-ai/plugin": "^1.1.1",
2319
2319
  "@opencode-ai/sdk": "^1.1.1",
2320
+ "@reinamaccredy/oh-my-opencode": "^3.0.0-beta.13",
2320
2321
  commander: "^14.0.2",
2321
2322
  hono: "^4.10.4",
2322
2323
  "js-yaml": "^4.1.1",
@@ -5610,12 +5611,6 @@ function log(message, data) {
5610
5611
  var DANGEROUS_KEYS = new Set(["__proto__", "constructor", "prototype"]);
5611
5612
  // src/shared/dynamic-truncator.ts
5612
5613
  var ANTHROPIC_ACTUAL_LIMIT = process.env.ANTHROPIC_1M_CONTEXT === "true" || process.env.VERTEX_ANTHROPIC_1M_CONTEXT === "true" ? 1e6 : 200000;
5613
- // src/shared/data-path.ts
5614
- import * as path2 from "path";
5615
- import * as os2 from "os";
5616
- function getDataDir() {
5617
- return process.env.XDG_DATA_HOME ?? path2.join(os2.homedir(), ".local", "share");
5618
- }
5619
5614
  // src/shared/jsonc-parser.ts
5620
5615
  import { existsSync, readFileSync } from "fs";
5621
5616
 
@@ -6486,8 +6481,8 @@ function detectConfigFile(basePath) {
6486
6481
  }
6487
6482
  // src/shared/opencode-config-dir.ts
6488
6483
  import { existsSync as existsSync2 } from "fs";
6489
- import { homedir as homedir2 } from "os";
6490
- import { join as join3 } from "path";
6484
+ import { homedir } from "os";
6485
+ import { join as join2 } from "path";
6491
6486
  var TAURI_APP_IDENTIFIER = "ai.opencode.desktop";
6492
6487
  var TAURI_APP_IDENTIFIER_DEV = "ai.opencode.desktop.dev";
6493
6488
  function isDevBuild(version) {
@@ -6499,35 +6494,35 @@ function getTauriConfigDir(identifier) {
6499
6494
  const platform = process.platform;
6500
6495
  switch (platform) {
6501
6496
  case "darwin":
6502
- return join3(homedir2(), "Library", "Application Support", identifier);
6497
+ return join2(homedir(), "Library", "Application Support", identifier);
6503
6498
  case "win32": {
6504
- const appData = process.env.APPDATA || join3(homedir2(), "AppData", "Roaming");
6505
- return join3(appData, identifier);
6499
+ const appData = process.env.APPDATA || join2(homedir(), "AppData", "Roaming");
6500
+ return join2(appData, identifier);
6506
6501
  }
6507
6502
  case "linux":
6508
6503
  default: {
6509
- const xdgConfig = process.env.XDG_CONFIG_HOME || join3(homedir2(), ".config");
6510
- return join3(xdgConfig, identifier);
6504
+ const xdgConfig = process.env.XDG_CONFIG_HOME || join2(homedir(), ".config");
6505
+ return join2(xdgConfig, identifier);
6511
6506
  }
6512
6507
  }
6513
6508
  }
6514
6509
  function getCliConfigDir() {
6515
6510
  if (process.platform === "win32") {
6516
- const crossPlatformDir = join3(homedir2(), ".config", "opencode");
6517
- const crossPlatformConfig = join3(crossPlatformDir, "opencode.json");
6511
+ const crossPlatformDir = join2(homedir(), ".config", "opencode");
6512
+ const crossPlatformConfig = join2(crossPlatformDir, "opencode.json");
6518
6513
  if (existsSync2(crossPlatformConfig)) {
6519
6514
  return crossPlatformDir;
6520
6515
  }
6521
- const appData = process.env.APPDATA || join3(homedir2(), "AppData", "Roaming");
6522
- const appdataDir = join3(appData, "opencode");
6523
- const appdataConfig = join3(appdataDir, "opencode.json");
6516
+ const appData = process.env.APPDATA || join2(homedir(), "AppData", "Roaming");
6517
+ const appdataDir = join2(appData, "opencode");
6518
+ const appdataConfig = join2(appdataDir, "opencode.json");
6524
6519
  if (existsSync2(appdataConfig)) {
6525
6520
  return appdataDir;
6526
6521
  }
6527
6522
  return crossPlatformDir;
6528
6523
  }
6529
- const xdgConfig = process.env.XDG_CONFIG_HOME || join3(homedir2(), ".config");
6530
- return join3(xdgConfig, "opencode");
6524
+ const xdgConfig = process.env.XDG_CONFIG_HOME || join2(homedir(), ".config");
6525
+ return join2(xdgConfig, "opencode");
6531
6526
  }
6532
6527
  function getOpenCodeConfigDir(options) {
6533
6528
  const { binary: binary2, version, checkExisting = true } = options;
@@ -6538,8 +6533,8 @@ function getOpenCodeConfigDir(options) {
6538
6533
  const tauriDir = getTauriConfigDir(identifier);
6539
6534
  if (checkExisting) {
6540
6535
  const legacyDir = getCliConfigDir();
6541
- const legacyConfig = join3(legacyDir, "opencode.json");
6542
- const legacyConfigC = join3(legacyDir, "opencode.jsonc");
6536
+ const legacyConfig = join2(legacyDir, "opencode.json");
6537
+ const legacyConfigC = join2(legacyDir, "opencode.jsonc");
6543
6538
  if (existsSync2(legacyConfig) || existsSync2(legacyConfigC)) {
6544
6539
  return legacyDir;
6545
6540
  }
@@ -6550,10 +6545,10 @@ function getOpenCodeConfigPaths(options) {
6550
6545
  const configDir = getOpenCodeConfigDir(options);
6551
6546
  return {
6552
6547
  configDir,
6553
- configJson: join3(configDir, "opencode.json"),
6554
- configJsonc: join3(configDir, "opencode.jsonc"),
6555
- packageJson: join3(configDir, "package.json"),
6556
- omoConfig: join3(configDir, "oh-my-opencode.json")
6548
+ configJson: join2(configDir, "opencode.json"),
6549
+ configJsonc: join2(configDir, "opencode.jsonc"),
6550
+ packageJson: join2(configDir, "package.json"),
6551
+ omoConfig: join2(configDir, "oh-my-opencode.json")
6557
6552
  };
6558
6553
  }
6559
6554
  // src/shared/opencode-version.ts
@@ -6638,26 +6633,26 @@ function detectConfigFormat() {
6638
6633
  function isEmptyOrWhitespace(content) {
6639
6634
  return content.trim().length === 0;
6640
6635
  }
6641
- function parseConfigWithError(path3) {
6636
+ function parseConfigWithError(path2) {
6642
6637
  try {
6643
- const stat = statSync(path3);
6638
+ const stat = statSync(path2);
6644
6639
  if (stat.size === 0) {
6645
- return { config: null, error: `Config file is empty: ${path3}. Delete it or add valid JSON content.` };
6640
+ return { config: null, error: `Config file is empty: ${path2}. Delete it or add valid JSON content.` };
6646
6641
  }
6647
- const content = readFileSync2(path3, "utf-8");
6642
+ const content = readFileSync2(path2, "utf-8");
6648
6643
  if (isEmptyOrWhitespace(content)) {
6649
- return { config: null, error: `Config file contains only whitespace: ${path3}. Delete it or add valid JSON content.` };
6644
+ return { config: null, error: `Config file contains only whitespace: ${path2}. Delete it or add valid JSON content.` };
6650
6645
  }
6651
6646
  const config = parseJsonc(content);
6652
6647
  if (config === null || config === undefined) {
6653
- return { config: null, error: `Config file parsed to null/undefined: ${path3}. Ensure it contains valid JSON.` };
6648
+ return { config: null, error: `Config file parsed to null/undefined: ${path2}. Ensure it contains valid JSON.` };
6654
6649
  }
6655
6650
  if (typeof config !== "object" || Array.isArray(config)) {
6656
- return { config: null, error: `Config file must contain a JSON object, not ${Array.isArray(config) ? "an array" : typeof config}: ${path3}` };
6651
+ return { config: null, error: `Config file must contain a JSON object, not ${Array.isArray(config) ? "an array" : typeof config}: ${path2}` };
6657
6652
  }
6658
6653
  return { config };
6659
6654
  } catch (err) {
6660
- return { config: null, error: formatErrorWithSuggestion(err, `parse config file ${path3}`) };
6655
+ return { config: null, error: formatErrorWithSuggestion(err, `parse config file ${path2}`) };
6661
6656
  }
6662
6657
  }
6663
6658
  function ensureConfigDir() {
@@ -6672,27 +6667,27 @@ function addPluginToOpenCodeConfig() {
6672
6667
  } catch (err) {
6673
6668
  return { success: false, configPath: getConfigDir(), error: formatErrorWithSuggestion(err, "create config directory") };
6674
6669
  }
6675
- const { format: format2, path: path3 } = detectConfigFormat();
6670
+ const { format: format2, path: path2 } = detectConfigFormat();
6676
6671
  const pluginName = "oh-my-opencode";
6677
6672
  try {
6678
6673
  if (format2 === "none") {
6679
6674
  const config2 = { plugin: [pluginName] };
6680
- writeFileSync(path3, JSON.stringify(config2, null, 2) + `
6675
+ writeFileSync(path2, JSON.stringify(config2, null, 2) + `
6681
6676
  `);
6682
- return { success: true, configPath: path3 };
6677
+ return { success: true, configPath: path2 };
6683
6678
  }
6684
- const parseResult = parseConfigWithError(path3);
6679
+ const parseResult = parseConfigWithError(path2);
6685
6680
  if (!parseResult.config) {
6686
- return { success: false, configPath: path3, error: parseResult.error ?? "Failed to parse config file" };
6681
+ return { success: false, configPath: path2, error: parseResult.error ?? "Failed to parse config file" };
6687
6682
  }
6688
6683
  const config = parseResult.config;
6689
6684
  const plugins = config.plugin ?? [];
6690
6685
  if (plugins.some((p2) => p2.startsWith(pluginName))) {
6691
- return { success: true, configPath: path3 };
6686
+ return { success: true, configPath: path2 };
6692
6687
  }
6693
6688
  config.plugin = [...plugins, pluginName];
6694
6689
  if (format2 === "jsonc") {
6695
- const content = readFileSync2(path3, "utf-8");
6690
+ const content = readFileSync2(path2, "utf-8");
6696
6691
  const pluginArrayRegex = /"plugin"\s*:\s*\[([\s\S]*?)\]/;
6697
6692
  const match = content.match(pluginArrayRegex);
6698
6693
  if (match) {
@@ -6702,19 +6697,19 @@ function addPluginToOpenCodeConfig() {
6702
6697
  const newContent = content.replace(pluginArrayRegex, `"plugin": [
6703
6698
  ${newArrayContent}
6704
6699
  ]`);
6705
- writeFileSync(path3, newContent);
6700
+ writeFileSync(path2, newContent);
6706
6701
  } else {
6707
6702
  const newContent = content.replace(/^(\s*\{)/, `$1
6708
6703
  "plugin": ["${pluginName}"],`);
6709
- writeFileSync(path3, newContent);
6704
+ writeFileSync(path2, newContent);
6710
6705
  }
6711
6706
  } else {
6712
- writeFileSync(path3, JSON.stringify(config, null, 2) + `
6707
+ writeFileSync(path2, JSON.stringify(config, null, 2) + `
6713
6708
  `);
6714
6709
  }
6715
- return { success: true, configPath: path3 };
6710
+ return { success: true, configPath: path2 };
6716
6711
  } catch (err) {
6717
- return { success: false, configPath: path3, error: formatErrorWithSuggestion(err, "update opencode config") };
6712
+ return { success: false, configPath: path2, error: formatErrorWithSuggestion(err, "update opencode config") };
6718
6713
  }
6719
6714
  }
6720
6715
  function deepMerge(target, source) {
@@ -6732,13 +6727,23 @@ function deepMerge(target, source) {
6732
6727
  }
6733
6728
  function generateOmoConfig(installConfig) {
6734
6729
  const config = {
6735
- $schema: "https://raw.githubusercontent.com/code-yeongyu/oh-my-opencode/master/assets/oh-my-opencode.schema.json"
6730
+ $schema: "https://raw.githubusercontent.com/ReinaMacCredy/oh-my-opencode/main/assets/oh-my-opencode.schema.json"
6736
6731
  };
6737
- if (installConfig.hasGemini) {
6738
- config.google_auth = false;
6739
- }
6732
+ if (installConfig.hasProxyPal || installConfig.hasGemini) {}
6740
6733
  const agents = {};
6741
- if (installConfig.hasGemini) {
6734
+ if (installConfig.hasProxyPal) {
6735
+ agents["Sisyphus"] = { model: "proxypal/gemini-claude-opus-4-5-thinking" };
6736
+ agents["librarian"] = { model: "proxypal/gemini-claude-opus-4-5-thinking" };
6737
+ agents["explore"] = { model: "proxypal/gemini-3-flash-preview" };
6738
+ agents["frontend-ui-ux-engineer"] = { model: "proxypal/gemini-3-pro-preview" };
6739
+ agents["document-writer"] = { model: "proxypal/gemini-3-flash-preview" };
6740
+ agents["multimodal-looker"] = { model: "proxypal/gemini-3-flash-preview" };
6741
+ agents["orchestrator-sisyphus"] = { model: "proxypal/gemini-claude-sonnet-4-5-thinking" };
6742
+ agents["Prometheus (Planner)"] = { model: "proxypal/gemini-claude-opus-4-5-thinking" };
6743
+ agents["Metis (Plan Consultant)"] = { model: "proxypal/gemini-claude-opus-4-5-thinking" };
6744
+ agents["oracle"] = { model: "proxypal/gpt-5.2-codex" };
6745
+ agents["Momus (Plan Reviewer)"] = { model: "proxypal/gpt-5.2-codex" };
6746
+ } else if (installConfig.hasGemini) {
6742
6747
  agents["Sisyphus"] = { model: "proxypal/gemini-claude-opus-4-5-thinking" };
6743
6748
  agents["librarian"] = { model: "proxypal/gemini-claude-opus-4-5-thinking" };
6744
6749
  agents["explore"] = { model: "proxypal/gemini-3-flash-preview" };
@@ -6763,22 +6768,34 @@ function generateOmoConfig(installConfig) {
6763
6768
  agents["document-writer"] = { model: "opencode/glm-4.7-free" };
6764
6769
  agents["multimodal-looker"] = { model: "opencode/glm-4.7-free" };
6765
6770
  }
6766
- if (installConfig.hasChatGPT) {
6767
- agents["oracle"] = { model: "openai/gpt-5.2" };
6768
- agents["Momus (Plan Reviewer)"] = { model: "openai/gpt-5.2" };
6769
- } else if (installConfig.hasClaude) {
6770
- agents["oracle"] = { model: "anthropic/claude-opus-4-5" };
6771
- agents["Momus (Plan Reviewer)"] = { model: "anthropic/claude-opus-4-5" };
6772
- } else {
6773
- agents["oracle"] = { model: "opencode/glm-4.7-free" };
6771
+ if (!installConfig.hasProxyPal) {
6772
+ if (installConfig.hasChatGPT) {
6773
+ agents["oracle"] = { model: "proxypal/gpt-5.2-codex" };
6774
+ agents["Momus (Plan Reviewer)"] = { model: "proxypal/gpt-5.2-codex" };
6775
+ } else if (installConfig.hasClaude) {
6776
+ agents["oracle"] = { model: "anthropic/claude-opus-4-5" };
6777
+ agents["Momus (Plan Reviewer)"] = { model: "anthropic/claude-opus-4-5" };
6778
+ } else {
6779
+ agents["oracle"] = { model: "opencode/glm-4.7-free" };
6780
+ }
6774
6781
  }
6775
6782
  if (Object.keys(agents).length > 0) {
6776
6783
  config.agents = agents;
6777
6784
  }
6778
- if (installConfig.hasGemini) {
6785
+ if (installConfig.hasProxyPal) {
6779
6786
  config.categories = {
6780
6787
  "visual-engineering": { model: "proxypal/gemini-3-pro-preview" },
6781
- ultrabrain: { model: "openai/gpt-5.2" },
6788
+ ultrabrain: { model: "proxypal/gpt-5.2-codex" },
6789
+ artistry: { model: "proxypal/gemini-3-pro-preview" },
6790
+ quick: { model: "proxypal/gemini-3-flash-preview" },
6791
+ "most-capable": { model: "proxypal/gemini-claude-opus-4-5-thinking" },
6792
+ writing: { model: "proxypal/gemini-3-flash-preview" },
6793
+ general: { model: "proxypal/gemini-claude-opus-4-5-thinking" }
6794
+ };
6795
+ } else if (installConfig.hasGemini) {
6796
+ config.categories = {
6797
+ "visual-engineering": { model: "proxypal/gemini-3-pro-preview" },
6798
+ ultrabrain: { model: "proxypal/gpt-5.2-codex" },
6782
6799
  artistry: { model: "proxypal/gemini-3-pro-preview" },
6783
6800
  quick: { model: "proxypal/gemini-3-flash-preview" },
6784
6801
  "most-capable": { model: "proxypal/gemini-claude-opus-4-5-thinking" },
@@ -6787,7 +6804,7 @@ function generateOmoConfig(installConfig) {
6787
6804
  };
6788
6805
  } else if (installConfig.hasChatGPT) {
6789
6806
  config.categories = {
6790
- ultrabrain: { model: "openai/gpt-5.2" }
6807
+ ultrabrain: { model: "proxypal/gpt-5.2-codex" }
6791
6808
  };
6792
6809
  }
6793
6810
  return config;
@@ -6871,11 +6888,11 @@ async function addAuthPlugins(config) {
6871
6888
  } catch (err) {
6872
6889
  return { success: false, configPath: getConfigDir(), error: formatErrorWithSuggestion(err, "create config directory") };
6873
6890
  }
6874
- const { format: format2, path: path3 } = detectConfigFormat();
6891
+ const { format: format2, path: path2 } = detectConfigFormat();
6875
6892
  try {
6876
6893
  let existingConfig = null;
6877
6894
  if (format2 !== "none") {
6878
- const parseResult = parseConfigWithError(path3);
6895
+ const parseResult = parseConfigWithError(path2);
6879
6896
  if (parseResult.error && !parseResult.config) {
6880
6897
  existingConfig = {};
6881
6898
  } else {
@@ -6884,9 +6901,9 @@ async function addAuthPlugins(config) {
6884
6901
  }
6885
6902
  const plugins = existingConfig?.plugin ?? [];
6886
6903
  if (config.hasGemini) {
6887
- const version = await fetchLatestVersion("opencode-antigravity-auth");
6888
- const pluginEntry = version ? `opencode-antigravity-auth@${version}` : "opencode-antigravity-auth";
6889
- if (!plugins.some((p2) => p2.startsWith("opencode-antigravity-auth"))) {
6904
+ const version = await fetchLatestVersion("opencode-proxypal-auth");
6905
+ const pluginEntry = version ? `opencode-proxypal-auth@${version}` : "opencode-proxypal-auth";
6906
+ if (!plugins.some((p2) => p2.startsWith("opencode-proxypal-auth"))) {
6890
6907
  plugins.push(pluginEntry);
6891
6908
  }
6892
6909
  }
@@ -6896,33 +6913,105 @@ async function addAuthPlugins(config) {
6896
6913
  }
6897
6914
  }
6898
6915
  const newConfig = { ...existingConfig ?? {}, plugin: plugins };
6899
- writeFileSync(path3, JSON.stringify(newConfig, null, 2) + `
6916
+ writeFileSync(path2, JSON.stringify(newConfig, null, 2) + `
6900
6917
  `);
6901
- return { success: true, configPath: path3 };
6918
+ return { success: true, configPath: path2 };
6902
6919
  } catch (err) {
6903
- return { success: false, configPath: path3, error: formatErrorWithSuggestion(err, "add auth plugins to config") };
6920
+ return { success: false, configPath: path2, error: formatErrorWithSuggestion(err, "add auth plugins to config") };
6904
6921
  }
6905
6922
  }
6923
+ var PROXYPAL_PROVIDER_CONFIG = {
6924
+ proxypal: {
6925
+ name: "ProxyPal",
6926
+ npm: "@ai-sdk/anthropic",
6927
+ options: {
6928
+ apiKey: "proxypal-local",
6929
+ baseURL: "http://127.0.0.1:8317/v1",
6930
+ includeUsage: true
6931
+ },
6932
+ models: {
6933
+ "gemini-claude-opus-4-5-thinking": {
6934
+ name: "Gemini Claude Opus 4 5 Thinking",
6935
+ limit: { context: 168000, output: 64000 },
6936
+ options: { thinking: { budgetTokens: 32768, type: "enabled" } },
6937
+ reasoning: true
6938
+ },
6939
+ "gemini-claude-sonnet-4-5-thinking": {
6940
+ name: "Gemini Claude Sonnet 4 5 Thinking",
6941
+ limit: { context: 168000, output: 64000 },
6942
+ options: { thinking: { budgetTokens: 32768, type: "enabled" } },
6943
+ reasoning: true
6944
+ },
6945
+ "gemini-claude-sonnet-4-5": {
6946
+ name: "Gemini Claude Sonnet 4 5",
6947
+ limit: { context: 168000, output: 64000 }
6948
+ },
6949
+ "gemini-3-pro-preview": {
6950
+ name: "Gemini 3 Pro Preview",
6951
+ limit: { context: 880964, output: 65536 }
6952
+ },
6953
+ "gemini-3-flash-preview": {
6954
+ name: "Gemini 3 Flash Preview",
6955
+ limit: { context: 880964, output: 65536 }
6956
+ },
6957
+ "gemini-2.5-flash": {
6958
+ name: "Gemini 2 5 Flash",
6959
+ limit: { context: 880964, output: 65536 }
6960
+ },
6961
+ "gpt-5.2-codex": {
6962
+ name: "Gpt 5 2 Codex",
6963
+ limit: { context: 336000, output: 32768 },
6964
+ options: { reasoningEffort: "xhigh" },
6965
+ reasoning: true
6966
+ },
6967
+ "gpt-5.2": {
6968
+ name: "Gpt 5 2",
6969
+ limit: { context: 336000, output: 32768 },
6970
+ options: { reasoningEffort: "xhigh" },
6971
+ reasoning: true
6972
+ },
6973
+ "gpt-5.1-codex-max": {
6974
+ name: "Gpt 5 1 Codex Max",
6975
+ limit: { context: 336000, output: 32768 },
6976
+ options: { reasoningEffort: "xhigh" },
6977
+ reasoning: true
6978
+ },
6979
+ "gemini-3-pro-high": {
6980
+ name: "Gemini 3 Pro High (ProxyPal)",
6981
+ thinking: true,
6982
+ attachment: true,
6983
+ limit: { context: 1048576, output: 65535 },
6984
+ modalities: { input: ["text", "image", "pdf"], output: ["text"] }
6985
+ },
6986
+ "gemini-3-flash": {
6987
+ name: "Gemini 3 Flash (ProxyPal)",
6988
+ attachment: true,
6989
+ limit: { context: 1048576, output: 65536 },
6990
+ modalities: { input: ["text", "image", "pdf"], output: ["text"] }
6991
+ }
6992
+ }
6993
+ }
6994
+ };
6906
6995
  var ANTIGRAVITY_PROVIDER_CONFIG = {
6907
6996
  google: {
6908
6997
  name: "Google",
6909
6998
  models: {
6910
- "antigravity-gemini-3-pro-high": {
6911
- name: "Gemini 3 Pro High (Antigravity)",
6999
+ "gemini-3-pro-high": {
7000
+ name: "Gemini 3 Pro High (ProxyPal)",
6912
7001
  thinking: true,
6913
7002
  attachment: true,
6914
7003
  limit: { context: 1048576, output: 65535 },
6915
7004
  modalities: { input: ["text", "image", "pdf"], output: ["text"] }
6916
7005
  },
6917
- "antigravity-gemini-3-pro-low": {
6918
- name: "Gemini 3 Pro Low (Antigravity)",
7006
+ "gemini-3-pro-low": {
7007
+ name: "Gemini 3 Pro Low (ProxyPal)",
6919
7008
  thinking: true,
6920
7009
  attachment: true,
6921
7010
  limit: { context: 1048576, output: 65535 },
6922
7011
  modalities: { input: ["text", "image", "pdf"], output: ["text"] }
6923
7012
  },
6924
- "antigravity-gemini-3-flash": {
6925
- name: "Gemini 3 Flash (Antigravity)",
7013
+ "gemini-3-flash": {
7014
+ name: "Gemini 3 Flash (ProxyPal)",
6926
7015
  attachment: true,
6927
7016
  limit: { context: 1048576, output: 65536 },
6928
7017
  modalities: { input: ["text", "image", "pdf"], output: ["text"] }
@@ -6984,11 +7073,11 @@ function addProviderConfig(config) {
6984
7073
  } catch (err) {
6985
7074
  return { success: false, configPath: getConfigDir(), error: formatErrorWithSuggestion(err, "create config directory") };
6986
7075
  }
6987
- const { format: format2, path: path3 } = detectConfigFormat();
7076
+ const { format: format2, path: path2 } = detectConfigFormat();
6988
7077
  try {
6989
7078
  let existingConfig = null;
6990
7079
  if (format2 !== "none") {
6991
- const parseResult = parseConfigWithError(path3);
7080
+ const parseResult = parseConfigWithError(path2);
6992
7081
  if (parseResult.error && !parseResult.config) {
6993
7082
  existingConfig = {};
6994
7083
  } else {
@@ -6997,6 +7086,9 @@ function addProviderConfig(config) {
6997
7086
  }
6998
7087
  const newConfig = { ...existingConfig ?? {} };
6999
7088
  const providers = newConfig.provider ?? {};
7089
+ if (config.hasProxyPal) {
7090
+ providers.proxypal = PROXYPAL_PROVIDER_CONFIG.proxypal;
7091
+ }
7000
7092
  if (config.hasGemini) {
7001
7093
  providers.google = ANTIGRAVITY_PROVIDER_CONFIG.google;
7002
7094
  }
@@ -7006,26 +7098,27 @@ function addProviderConfig(config) {
7006
7098
  if (Object.keys(providers).length > 0) {
7007
7099
  newConfig.provider = providers;
7008
7100
  }
7009
- writeFileSync(path3, JSON.stringify(newConfig, null, 2) + `
7101
+ writeFileSync(path2, JSON.stringify(newConfig, null, 2) + `
7010
7102
  `);
7011
- return { success: true, configPath: path3 };
7103
+ return { success: true, configPath: path2 };
7012
7104
  } catch (err) {
7013
- return { success: false, configPath: path3, error: formatErrorWithSuggestion(err, "add provider config") };
7105
+ return { success: false, configPath: path2, error: formatErrorWithSuggestion(err, "add provider config") };
7014
7106
  }
7015
7107
  }
7016
7108
  function detectCurrentConfig() {
7017
7109
  const result = {
7018
7110
  isInstalled: false,
7111
+ hasProxyPal: false,
7019
7112
  hasClaude: true,
7020
7113
  isMax20: true,
7021
7114
  hasChatGPT: true,
7022
7115
  hasGemini: false
7023
7116
  };
7024
- const { format: format2, path: path3 } = detectConfigFormat();
7117
+ const { format: format2, path: path2 } = detectConfigFormat();
7025
7118
  if (format2 === "none") {
7026
7119
  return result;
7027
7120
  }
7028
- const parseResult = parseConfigWithError(path3);
7121
+ const parseResult = parseConfigWithError(path2);
7029
7122
  if (!parseResult.config) {
7030
7123
  return result;
7031
7124
  }
@@ -7035,7 +7128,7 @@ function detectCurrentConfig() {
7035
7128
  if (!result.isInstalled) {
7036
7129
  return result;
7037
7130
  }
7038
- result.hasGemini = plugins.some((p2) => p2.startsWith("opencode-antigravity-auth"));
7131
+ result.hasGemini = plugins.some((p2) => p2.startsWith("opencode-proxypal-auth"));
7039
7132
  result.hasChatGPT = plugins.some((p2) => p2.startsWith("opencode-openai-codex-auth"));
7040
7133
  const omoConfigPath = getOmoConfig();
7041
7134
  if (!existsSync3(omoConfigPath)) {
@@ -7055,6 +7148,14 @@ function detectCurrentConfig() {
7055
7148
  return result;
7056
7149
  }
7057
7150
  const agents = omoConfig.agents ?? {};
7151
+ if (agents["Sisyphus"]?.model?.startsWith("proxypal/")) {
7152
+ result.hasProxyPal = true;
7153
+ result.hasClaude = false;
7154
+ result.isMax20 = false;
7155
+ result.hasChatGPT = false;
7156
+ result.hasGemini = false;
7157
+ return result;
7158
+ }
7058
7159
  if (agents["Sisyphus"]?.model === "opencode/glm-4.7-free") {
7059
7160
  result.hasClaude = false;
7060
7161
  result.isMax20 = false;
@@ -7067,9 +7168,6 @@ function detectCurrentConfig() {
7067
7168
  } else if (agents["oracle"]?.model === "opencode/glm-4.7-free") {
7068
7169
  result.hasChatGPT = false;
7069
7170
  }
7070
- if (omoConfig.google_auth === false) {
7071
- result.hasGemini = plugins.some((p2) => p2.startsWith("opencode-antigravity-auth"));
7072
- }
7073
7171
  } catch {}
7074
7172
  return result;
7075
7173
  }
@@ -7094,19 +7192,41 @@ function formatConfigSummary(config) {
7094
7192
  const lines = [];
7095
7193
  lines.push(import_picocolors2.default.bold(import_picocolors2.default.white("Configuration Summary")));
7096
7194
  lines.push("");
7097
- const claudeDetail = config.hasClaude ? config.isMax20 ? "max20" : "standard" : undefined;
7098
- lines.push(formatProvider("Claude", config.hasClaude, claudeDetail));
7099
- lines.push(formatProvider("ChatGPT", config.hasChatGPT));
7100
- lines.push(formatProvider("Gemini", config.hasGemini));
7195
+ if (config.hasProxyPal) {
7196
+ lines.push(formatProvider("ProxyPal", true, "all models via proxy"));
7197
+ lines.push(formatProvider("Claude", false));
7198
+ lines.push(formatProvider("ChatGPT", false));
7199
+ lines.push(formatProvider("Gemini", false));
7200
+ } else {
7201
+ lines.push(formatProvider("ProxyPal", false));
7202
+ const claudeDetail = config.hasClaude ? config.isMax20 ? "max20" : "standard" : undefined;
7203
+ lines.push(formatProvider("Claude", config.hasClaude, claudeDetail));
7204
+ lines.push(formatProvider("ChatGPT", config.hasChatGPT));
7205
+ }
7101
7206
  lines.push("");
7102
7207
  lines.push(import_picocolors2.default.dim("\u2500".repeat(40)));
7103
7208
  lines.push("");
7104
7209
  lines.push(import_picocolors2.default.bold(import_picocolors2.default.white("Agent Configuration")));
7105
7210
  lines.push("");
7106
- const sisyphusModel = config.hasClaude ? "claude-opus-4-5" : "glm-4.7-free";
7107
- const oracleModel = config.hasChatGPT ? "gpt-5.2" : config.hasClaude ? "claude-opus-4-5" : "glm-4.7-free";
7108
- const librarianModel = "glm-4.7-free";
7109
- const frontendModel = config.hasGemini ? "antigravity-gemini-3-pro-high" : config.hasClaude ? "claude-opus-4-5" : "glm-4.7-free";
7211
+ let sisyphusModel;
7212
+ let oracleModel;
7213
+ let librarianModel;
7214
+ let frontendModel;
7215
+ if (config.hasProxyPal) {
7216
+ sisyphusModel = "gemini-claude-opus-4-5-thinking";
7217
+ oracleModel = "gpt-5.2-codex";
7218
+ librarianModel = "gemini-claude-opus-4-5-thinking";
7219
+ frontendModel = "gemini-3-pro-preview";
7220
+ sisyphusModel = "claude-opus-4-5";
7221
+ oracleModel = config.hasChatGPT ? "gpt-5.2-codex" : "claude-opus-4-5";
7222
+ librarianModel = "claude-sonnet-4-5";
7223
+ frontendModel = "claude-opus-4-5";
7224
+ } else {
7225
+ sisyphusModel = "glm-4.7-free";
7226
+ oracleModel = config.hasChatGPT ? "gpt-5.2-codex" : "glm-4.7-free";
7227
+ librarianModel = "glm-4.7-free";
7228
+ frontendModel = "glm-4.7-free";
7229
+ }
7110
7230
  lines.push(` ${SYMBOLS.bullet} Sisyphus ${SYMBOLS.arrow} ${import_picocolors2.default.cyan(sisyphusModel)}`);
7111
7231
  lines.push(` ${SYMBOLS.bullet} Oracle ${SYMBOLS.arrow} ${import_picocolors2.default.cyan(oracleModel)}`);
7112
7232
  lines.push(` ${SYMBOLS.bullet} Librarian ${SYMBOLS.arrow} ${import_picocolors2.default.cyan(librarianModel)}`);
@@ -7157,6 +7277,12 @@ function printBox(content, title) {
7157
7277
  }
7158
7278
  function validateNonTuiArgs(args) {
7159
7279
  const errors = [];
7280
+ if (args.proxypal !== undefined && !["no", "yes"].includes(args.proxypal)) {
7281
+ errors.push(`Invalid --proxypal value: ${args.proxypal} (expected: no, yes)`);
7282
+ }
7283
+ if (args.proxypal === "yes") {
7284
+ return { valid: errors.length === 0, errors };
7285
+ }
7160
7286
  if (args.claude === undefined) {
7161
7287
  errors.push("--claude is required (values: no, yes, max20)");
7162
7288
  } else if (!["no", "yes", "max20"].includes(args.claude)) {
@@ -7167,19 +7293,24 @@ function validateNonTuiArgs(args) {
7167
7293
  } else if (!["no", "yes"].includes(args.chatgpt)) {
7168
7294
  errors.push(`Invalid --chatgpt value: ${args.chatgpt} (expected: no, yes)`);
7169
7295
  }
7170
- if (args.gemini === undefined) {
7171
- errors.push("--gemini is required (values: no, yes)");
7172
- } else if (!["no", "yes"].includes(args.gemini)) {
7173
- errors.push(`Invalid --gemini value: ${args.gemini} (expected: no, yes)`);
7174
- }
7175
7296
  return { valid: errors.length === 0, errors };
7176
7297
  }
7177
7298
  function argsToConfig(args) {
7299
+ if (args.proxypal === "yes") {
7300
+ return {
7301
+ hasProxyPal: true,
7302
+ hasClaude: false,
7303
+ isMax20: false,
7304
+ hasChatGPT: false,
7305
+ hasGemini: false
7306
+ };
7307
+ }
7178
7308
  return {
7309
+ hasProxyPal: false,
7179
7310
  hasClaude: args.claude !== "no",
7180
7311
  isMax20: args.claude === "max20",
7181
7312
  hasChatGPT: args.chatgpt === "yes",
7182
- hasGemini: args.gemini === "yes"
7313
+ hasGemini: false
7183
7314
  };
7184
7315
  }
7185
7316
  function detectedToInitialValues(detected) {
@@ -7188,13 +7319,34 @@ function detectedToInitialValues(detected) {
7188
7319
  claude = detected.isMax20 ? "max20" : "yes";
7189
7320
  }
7190
7321
  return {
7322
+ proxypal: detected.hasProxyPal ? "yes" : "no",
7191
7323
  claude,
7192
- chatgpt: detected.hasChatGPT ? "yes" : "no",
7193
- gemini: detected.hasGemini ? "yes" : "no"
7324
+ chatgpt: detected.hasChatGPT ? "yes" : "no"
7194
7325
  };
7195
7326
  }
7196
7327
  async function runTuiMode(detected) {
7197
7328
  const initial = detectedToInitialValues(detected);
7329
+ const proxypal = await ve({
7330
+ message: "Are you using ProxyPal? (github.com/heyhuynhgiabuu/proxypal)",
7331
+ options: [
7332
+ { value: "yes", label: "Yes", hint: "All models via ProxyPal proxy - skip other questions" },
7333
+ { value: "no", label: "No", hint: "Configure individual providers" }
7334
+ ],
7335
+ initialValue: initial.proxypal
7336
+ });
7337
+ if (pD(proxypal)) {
7338
+ xe("Installation cancelled.");
7339
+ return null;
7340
+ }
7341
+ if (proxypal === "yes") {
7342
+ return {
7343
+ hasProxyPal: true,
7344
+ hasClaude: false,
7345
+ isMax20: false,
7346
+ hasChatGPT: false,
7347
+ hasGemini: false
7348
+ };
7349
+ }
7198
7350
  const claude = await ve({
7199
7351
  message: "Do you have a Claude Pro/Max subscription?",
7200
7352
  options: [
@@ -7220,23 +7372,12 @@ async function runTuiMode(detected) {
7220
7372
  xe("Installation cancelled.");
7221
7373
  return null;
7222
7374
  }
7223
- const gemini = await ve({
7224
- message: "Will you integrate Google Gemini?",
7225
- options: [
7226
- { value: "no", label: "No", hint: "Frontend/docs agents will use fallback" },
7227
- { value: "yes", label: "Yes", hint: "Beautiful UI generation with Gemini 3 Pro" }
7228
- ],
7229
- initialValue: initial.gemini
7230
- });
7231
- if (pD(gemini)) {
7232
- xe("Installation cancelled.");
7233
- return null;
7234
- }
7235
7375
  return {
7376
+ hasProxyPal: false,
7236
7377
  hasClaude: claude !== "no",
7237
7378
  isMax20: claude === "max20",
7238
7379
  hasChatGPT: chatgpt === "yes",
7239
- hasGemini: gemini === "yes"
7380
+ hasGemini: false
7240
7381
  };
7241
7382
  }
7242
7383
  async function runNonTuiInstall(args) {
@@ -7248,7 +7389,8 @@ async function runNonTuiInstall(args) {
7248
7389
  console.log(` ${SYMBOLS.bullet} ${err}`);
7249
7390
  }
7250
7391
  console.log();
7251
- printInfo("Usage: bunx oh-my-opencode install --no-tui --claude=<no|yes|max20> --chatgpt=<no|yes> --gemini=<no|yes>");
7392
+ printInfo("Usage: bunx oh-my-opencode install --no-tui --proxypal=yes");
7393
+ printInfo(" or: bunx oh-my-opencode install --no-tui --claude=<no|yes|max20> --chatgpt=<no|yes>");
7252
7394
  console.log();
7253
7395
  return 1;
7254
7396
  }
@@ -7268,7 +7410,11 @@ async function runNonTuiInstall(args) {
7268
7410
  printSuccess(`OpenCode ${version ?? ""} detected`);
7269
7411
  if (isUpdate) {
7270
7412
  const initial = detectedToInitialValues(detected);
7271
- printInfo(`Current config: Claude=${initial.claude}, ChatGPT=${initial.chatgpt}, Gemini=${initial.gemini}`);
7413
+ if (initial.proxypal === "yes") {
7414
+ printInfo(`Current config: ProxyPal=yes`);
7415
+ } else {
7416
+ printInfo(`Current config: Claude=${initial.claude}, ChatGPT=${initial.chatgpt}`);
7417
+ }
7272
7418
  }
7273
7419
  const config = argsToConfig(args);
7274
7420
  printStep(step++, totalSteps, "Adding oh-my-opencode plugin...");
@@ -7278,7 +7424,16 @@ async function runNonTuiInstall(args) {
7278
7424
  return 1;
7279
7425
  }
7280
7426
  printSuccess(`Plugin ${isUpdate ? "verified" : "added"} ${SYMBOLS.arrow} ${import_picocolors2.default.dim(pluginResult.configPath)}`);
7281
- if (config.hasGemini || config.hasChatGPT) {
7427
+ if (config.hasProxyPal) {
7428
+ printStep(step++, totalSteps, "Adding ProxyPal provider configuration...");
7429
+ const providerResult = addProviderConfig(config);
7430
+ if (!providerResult.success) {
7431
+ printError(`Failed: ${providerResult.error}`);
7432
+ return 1;
7433
+ }
7434
+ printSuccess(`ProxyPal configured ${SYMBOLS.arrow} ${import_picocolors2.default.dim(providerResult.configPath)}`);
7435
+ step += 1;
7436
+ } else if (config.hasChatGPT) {
7282
7437
  printStep(step++, totalSteps, "Adding auth plugins...");
7283
7438
  const authResult = await addAuthPlugins(config);
7284
7439
  if (!authResult.success) {
@@ -7304,10 +7459,16 @@ async function runNonTuiInstall(args) {
7304
7459
  }
7305
7460
  printSuccess(`Config written ${SYMBOLS.arrow} ${import_picocolors2.default.dim(omoResult.configPath)}`);
7306
7461
  printBox(formatConfigSummary(config), isUpdate ? "Updated Configuration" : "Installation Complete");
7307
- if (!config.hasClaude && !config.hasChatGPT && !config.hasGemini) {
7462
+ if (!config.hasProxyPal && !config.hasClaude && !config.hasChatGPT) {
7308
7463
  printWarning("No model providers configured. Using opencode/glm-4.7-free as fallback.");
7309
7464
  }
7310
- if ((config.hasClaude || config.hasChatGPT || config.hasGemini) && !args.skipAuth) {
7465
+ if (config.hasProxyPal && !args.skipAuth) {
7466
+ console.log(import_picocolors2.default.bold("Next Steps - Configure ProxyPal:"));
7467
+ console.log();
7468
+ console.log(` ${SYMBOLS.arrow} Start ProxyPal and ensure proxy is running on ${import_picocolors2.default.cyan("http://localhost:8317")}`);
7469
+ console.log(` ${SYMBOLS.arrow} Authenticate your providers in ProxyPal app`);
7470
+ console.log();
7471
+ } else if ((config.hasClaude || config.hasChatGPT) && !args.skipAuth) {
7311
7472
  console.log(import_picocolors2.default.bold("Next Steps - Authenticate your providers:"));
7312
7473
  console.log();
7313
7474
  if (config.hasClaude) {
@@ -7316,9 +7477,6 @@ async function runNonTuiInstall(args) {
7316
7477
  if (config.hasChatGPT) {
7317
7478
  console.log(` ${SYMBOLS.arrow} ${import_picocolors2.default.dim("opencode auth login")} ${import_picocolors2.default.gray("(select OpenAI \u2192 ChatGPT Plus/Pro)")}`);
7318
7479
  }
7319
- if (config.hasGemini) {
7320
- console.log(` ${SYMBOLS.arrow} ${import_picocolors2.default.dim("opencode auth login")} ${import_picocolors2.default.gray("(select Google \u2192 OAuth with Antigravity)")}`);
7321
- }
7322
7480
  console.log();
7323
7481
  }
7324
7482
  console.log(`${SYMBOLS.star} ${import_picocolors2.default.bold(import_picocolors2.default.green(isUpdate ? "Configuration updated!" : "Installation complete!"))}`);
@@ -7343,7 +7501,11 @@ async function install(args) {
7343
7501
  Ie(import_picocolors2.default.bgMagenta(import_picocolors2.default.white(isUpdate ? " oMoMoMoMo... Update " : " oMoMoMoMo... ")));
7344
7502
  if (isUpdate) {
7345
7503
  const initial = detectedToInitialValues(detected);
7346
- M2.info(`Existing configuration detected: Claude=${initial.claude}, ChatGPT=${initial.chatgpt}, Gemini=${initial.gemini}`);
7504
+ if (initial.proxypal === "yes") {
7505
+ M2.info(`Existing configuration detected: ProxyPal=yes`);
7506
+ } else {
7507
+ M2.info(`Existing configuration detected: Claude=${initial.claude}, ChatGPT=${initial.chatgpt}`);
7508
+ }
7347
7509
  }
7348
7510
  const s = Y2();
7349
7511
  s.start("Checking OpenCode installation");
@@ -7368,7 +7530,16 @@ async function install(args) {
7368
7530
  return 1;
7369
7531
  }
7370
7532
  s.stop(`Plugin added to ${import_picocolors2.default.cyan(pluginResult.configPath)}`);
7371
- if (config.hasGemini || config.hasChatGPT) {
7533
+ if (config.hasProxyPal) {
7534
+ s.start("Adding ProxyPal provider configuration");
7535
+ const providerResult = addProviderConfig(config);
7536
+ if (!providerResult.success) {
7537
+ s.stop(`Failed to add provider config: ${providerResult.error}`);
7538
+ Se(import_picocolors2.default.red("Installation failed."));
7539
+ return 1;
7540
+ }
7541
+ s.stop(`ProxyPal configured to ${import_picocolors2.default.cyan(providerResult.configPath)}`);
7542
+ } else if (config.hasChatGPT) {
7372
7543
  s.start("Adding auth plugins (fetching latest versions)");
7373
7544
  const authResult = await addAuthPlugins(config);
7374
7545
  if (!authResult.success) {
@@ -7394,11 +7565,18 @@ async function install(args) {
7394
7565
  return 1;
7395
7566
  }
7396
7567
  s.stop(`Config written to ${import_picocolors2.default.cyan(omoResult.configPath)}`);
7397
- if (!config.hasClaude && !config.hasChatGPT && !config.hasGemini) {
7568
+ if (!config.hasProxyPal && !config.hasClaude && !config.hasChatGPT) {
7398
7569
  M2.warn("No model providers configured. Using opencode/glm-4.7-free as fallback.");
7399
7570
  }
7400
7571
  Me(formatConfigSummary(config), isUpdate ? "Updated Configuration" : "Installation Complete");
7401
- if ((config.hasClaude || config.hasChatGPT || config.hasGemini) && !args.skipAuth) {
7572
+ if (config.hasProxyPal && !args.skipAuth) {
7573
+ const steps = [
7574
+ `Start ProxyPal and ensure proxy is running on ${import_picocolors2.default.cyan("http://localhost:8317")}`,
7575
+ `Authenticate your providers in the ProxyPal app`
7576
+ ];
7577
+ Me(steps.join(`
7578
+ `), "Next Steps - Configure ProxyPal");
7579
+ } else if ((config.hasClaude || config.hasChatGPT) && !args.skipAuth) {
7402
7580
  const steps = [];
7403
7581
  if (config.hasClaude) {
7404
7582
  steps.push(`${import_picocolors2.default.dim("opencode auth login")} ${import_picocolors2.default.gray("(select Anthropic \u2192 Claude Pro/Max)")}`);
@@ -7406,9 +7584,6 @@ async function install(args) {
7406
7584
  if (config.hasChatGPT) {
7407
7585
  steps.push(`${import_picocolors2.default.dim("opencode auth login")} ${import_picocolors2.default.gray("(select OpenAI \u2192 ChatGPT Plus/Pro)")}`);
7408
7586
  }
7409
- if (config.hasGemini) {
7410
- steps.push(`${import_picocolors2.default.dim("opencode auth login")} ${import_picocolors2.default.gray("(select Google \u2192 OAuth with Antigravity)")}`);
7411
- }
7412
7587
  Me(steps.join(`
7413
7588
  `), "Next Steps - Authenticate your providers");
7414
7589
  }
@@ -7656,7 +7831,7 @@ var serializeObjectParam = ({ allowReserved, explode, name, style, value, valueO
7656
7831
 
7657
7832
  // node_modules/@opencode-ai/sdk/dist/gen/core/utils.gen.js
7658
7833
  var PATH_PARAM_RE = /\{[^{}]+\}/g;
7659
- var defaultPathSerializer = ({ path: path3, url: _url }) => {
7834
+ var defaultPathSerializer = ({ path: path2, url: _url }) => {
7660
7835
  let url = _url;
7661
7836
  const matches = _url.match(PATH_PARAM_RE);
7662
7837
  if (matches) {
@@ -7675,7 +7850,7 @@ var defaultPathSerializer = ({ path: path3, url: _url }) => {
7675
7850
  name = name.substring(1);
7676
7851
  style = "matrix";
7677
7852
  }
7678
- const value = path3[name];
7853
+ const value = path2[name];
7679
7854
  if (value === undefined || value === null) {
7680
7855
  continue;
7681
7856
  }
@@ -7706,11 +7881,11 @@ var defaultPathSerializer = ({ path: path3, url: _url }) => {
7706
7881
  }
7707
7882
  return url;
7708
7883
  };
7709
- var getUrl = ({ baseUrl, path: path3, query, querySerializer, url: _url }) => {
7884
+ var getUrl = ({ baseUrl, path: path2, query, querySerializer, url: _url }) => {
7710
7885
  const pathUrl = _url.startsWith("/") ? _url : `/${_url}`;
7711
7886
  let url = (baseUrl ?? "") + pathUrl;
7712
- if (path3) {
7713
- url = defaultPathSerializer({ path: path3, url });
7887
+ if (path2) {
7888
+ url = defaultPathSerializer({ path: path2, url });
7714
7889
  }
7715
7890
  let search = query ? querySerializer(query) : "";
7716
7891
  if (search.startsWith("?")) {
@@ -9222,49 +9397,49 @@ All tasks completed.`));
9222
9397
  }
9223
9398
  // src/hooks/auto-update-checker/checker.ts
9224
9399
  import * as fs3 from "fs";
9225
- import * as path4 from "path";
9400
+ import * as path3 from "path";
9226
9401
  import { fileURLToPath } from "url";
9227
9402
 
9228
9403
  // src/hooks/auto-update-checker/constants.ts
9229
- import * as path3 from "path";
9230
- import * as os3 from "os";
9404
+ import * as path2 from "path";
9405
+ import * as os2 from "os";
9231
9406
  import * as fs2 from "fs";
9232
9407
  var PACKAGE_NAME = "oh-my-opencode";
9233
9408
  var NPM_REGISTRY_URL = `https://registry.npmjs.org/-/package/${PACKAGE_NAME}/dist-tags`;
9234
9409
  var NPM_FETCH_TIMEOUT = 5000;
9235
9410
  function getCacheDir() {
9236
9411
  if (process.platform === "win32") {
9237
- return path3.join(process.env.LOCALAPPDATA ?? os3.homedir(), "opencode");
9412
+ return path2.join(process.env.LOCALAPPDATA ?? os2.homedir(), "opencode");
9238
9413
  }
9239
- return path3.join(os3.homedir(), ".cache", "opencode");
9414
+ return path2.join(os2.homedir(), ".cache", "opencode");
9240
9415
  }
9241
9416
  var CACHE_DIR = getCacheDir();
9242
- var VERSION_FILE = path3.join(CACHE_DIR, "version");
9243
- var INSTALLED_PACKAGE_JSON = path3.join(CACHE_DIR, "node_modules", PACKAGE_NAME, "package.json");
9417
+ var VERSION_FILE = path2.join(CACHE_DIR, "version");
9418
+ var INSTALLED_PACKAGE_JSON = path2.join(CACHE_DIR, "node_modules", PACKAGE_NAME, "package.json");
9244
9419
  function getUserConfigDir() {
9245
9420
  if (process.platform === "win32") {
9246
- const crossPlatformDir = path3.join(os3.homedir(), ".config");
9247
- const appdataDir = process.env.APPDATA ?? path3.join(os3.homedir(), "AppData", "Roaming");
9248
- const crossPlatformConfig = path3.join(crossPlatformDir, "opencode", "opencode.json");
9249
- const crossPlatformConfigJsonc = path3.join(crossPlatformDir, "opencode", "opencode.jsonc");
9421
+ const crossPlatformDir = path2.join(os2.homedir(), ".config");
9422
+ const appdataDir = process.env.APPDATA ?? path2.join(os2.homedir(), "AppData", "Roaming");
9423
+ const crossPlatformConfig = path2.join(crossPlatformDir, "opencode", "opencode.json");
9424
+ const crossPlatformConfigJsonc = path2.join(crossPlatformDir, "opencode", "opencode.jsonc");
9250
9425
  if (fs2.existsSync(crossPlatformConfig) || fs2.existsSync(crossPlatformConfigJsonc)) {
9251
9426
  return crossPlatformDir;
9252
9427
  }
9253
9428
  return appdataDir;
9254
9429
  }
9255
- return process.env.XDG_CONFIG_HOME ?? path3.join(os3.homedir(), ".config");
9430
+ return process.env.XDG_CONFIG_HOME ?? path2.join(os2.homedir(), ".config");
9256
9431
  }
9257
9432
  function getWindowsAppdataDir() {
9258
9433
  if (process.platform !== "win32")
9259
9434
  return null;
9260
- return process.env.APPDATA ?? path3.join(os3.homedir(), "AppData", "Roaming");
9435
+ return process.env.APPDATA ?? path2.join(os2.homedir(), "AppData", "Roaming");
9261
9436
  }
9262
9437
  var USER_CONFIG_DIR = getUserConfigDir();
9263
- var USER_OPENCODE_CONFIG = path3.join(USER_CONFIG_DIR, "opencode", "opencode.json");
9264
- var USER_OPENCODE_CONFIG_JSONC = path3.join(USER_CONFIG_DIR, "opencode", "opencode.jsonc");
9438
+ var USER_OPENCODE_CONFIG = path2.join(USER_CONFIG_DIR, "opencode", "opencode.json");
9439
+ var USER_OPENCODE_CONFIG_JSONC = path2.join(USER_CONFIG_DIR, "opencode", "opencode.jsonc");
9265
9440
 
9266
9441
  // src/hooks/auto-update-checker/checker.ts
9267
- import * as os4 from "os";
9442
+ import * as os3 from "os";
9268
9443
  function isLocalDevMode(directory) {
9269
9444
  return getLocalDevPath(directory) !== null;
9270
9445
  }
@@ -9273,18 +9448,18 @@ function stripJsonComments(json2) {
9273
9448
  }
9274
9449
  function getConfigPaths(directory) {
9275
9450
  const paths = [
9276
- path4.join(directory, ".opencode", "opencode.json"),
9277
- path4.join(directory, ".opencode", "opencode.jsonc"),
9451
+ path3.join(directory, ".opencode", "opencode.json"),
9452
+ path3.join(directory, ".opencode", "opencode.jsonc"),
9278
9453
  USER_OPENCODE_CONFIG,
9279
9454
  USER_OPENCODE_CONFIG_JSONC
9280
9455
  ];
9281
9456
  if (process.platform === "win32") {
9282
- const crossPlatformDir = path4.join(os4.homedir(), ".config");
9457
+ const crossPlatformDir = path3.join(os3.homedir(), ".config");
9283
9458
  const appdataDir = getWindowsAppdataDir();
9284
9459
  if (appdataDir) {
9285
9460
  const alternateDir = USER_CONFIG_DIR === crossPlatformDir ? appdataDir : crossPlatformDir;
9286
- const alternateConfig = path4.join(alternateDir, "opencode", "opencode.json");
9287
- const alternateConfigJsonc = path4.join(alternateDir, "opencode", "opencode.jsonc");
9461
+ const alternateConfig = path3.join(alternateDir, "opencode", "opencode.json");
9462
+ const alternateConfigJsonc = path3.join(alternateDir, "opencode", "opencode.jsonc");
9288
9463
  if (!paths.includes(alternateConfig)) {
9289
9464
  paths.push(alternateConfig);
9290
9465
  }
@@ -9321,9 +9496,9 @@ function getLocalDevPath(directory) {
9321
9496
  function findPackageJsonUp(startPath) {
9322
9497
  try {
9323
9498
  const stat = fs3.statSync(startPath);
9324
- let dir = stat.isDirectory() ? startPath : path4.dirname(startPath);
9499
+ let dir = stat.isDirectory() ? startPath : path3.dirname(startPath);
9325
9500
  for (let i2 = 0;i2 < 10; i2++) {
9326
- const pkgPath = path4.join(dir, "package.json");
9501
+ const pkgPath = path3.join(dir, "package.json");
9327
9502
  if (fs3.existsSync(pkgPath)) {
9328
9503
  try {
9329
9504
  const content = fs3.readFileSync(pkgPath, "utf-8");
@@ -9332,7 +9507,7 @@ function findPackageJsonUp(startPath) {
9332
9507
  return pkgPath;
9333
9508
  } catch {}
9334
9509
  }
9335
- const parent = path4.dirname(dir);
9510
+ const parent = path3.dirname(dir);
9336
9511
  if (parent === dir)
9337
9512
  break;
9338
9513
  dir = parent;
@@ -9374,7 +9549,7 @@ function getCachedVersion() {
9374
9549
  }
9375
9550
  } catch {}
9376
9551
  try {
9377
- const currentDir = path4.dirname(fileURLToPath(import.meta.url));
9552
+ const currentDir = path3.dirname(fileURLToPath(import.meta.url));
9378
9553
  const pkgPath = findPackageJsonUp(currentDir);
9379
9554
  if (pkgPath) {
9380
9555
  const content = fs3.readFileSync(pkgPath, "utf-8");
@@ -9831,8 +10006,8 @@ function getPluginCheckDefinition() {
9831
10006
 
9832
10007
  // src/cli/doctor/checks/config.ts
9833
10008
  import { existsSync as existsSync7, readFileSync as readFileSync5 } from "fs";
9834
- import { homedir as homedir5 } from "os";
9835
- import { join as join6 } from "path";
10009
+ import { homedir as homedir4 } from "os";
10010
+ import { join as join5 } from "path";
9836
10011
 
9837
10012
  // node_modules/zod/v4/classic/external.js
9838
10013
  var exports_external = {};
@@ -10563,10 +10738,10 @@ function mergeDefs(...defs) {
10563
10738
  function cloneDef(schema2) {
10564
10739
  return mergeDefs(schema2._zod.def);
10565
10740
  }
10566
- function getElementAtPath(obj, path5) {
10567
- if (!path5)
10741
+ function getElementAtPath(obj, path4) {
10742
+ if (!path4)
10568
10743
  return obj;
10569
- return path5.reduce((acc, key) => acc?.[key], obj);
10744
+ return path4.reduce((acc, key) => acc?.[key], obj);
10570
10745
  }
10571
10746
  function promiseAllObject(promisesObj) {
10572
10747
  const keys = Object.keys(promisesObj);
@@ -10925,11 +11100,11 @@ function aborted(x2, startIndex = 0) {
10925
11100
  }
10926
11101
  return false;
10927
11102
  }
10928
- function prefixIssues(path5, issues) {
11103
+ function prefixIssues(path4, issues) {
10929
11104
  return issues.map((iss) => {
10930
11105
  var _a;
10931
11106
  (_a = iss).path ?? (_a.path = []);
10932
- iss.path.unshift(path5);
11107
+ iss.path.unshift(path4);
10933
11108
  return iss;
10934
11109
  });
10935
11110
  }
@@ -11097,7 +11272,7 @@ function treeifyError(error, _mapper) {
11097
11272
  return issue2.message;
11098
11273
  };
11099
11274
  const result = { errors: [] };
11100
- const processError = (error2, path5 = []) => {
11275
+ const processError = (error2, path4 = []) => {
11101
11276
  var _a, _b;
11102
11277
  for (const issue2 of error2.issues) {
11103
11278
  if (issue2.code === "invalid_union" && issue2.errors.length) {
@@ -11107,7 +11282,7 @@ function treeifyError(error, _mapper) {
11107
11282
  } else if (issue2.code === "invalid_element") {
11108
11283
  processError({ issues: issue2.issues }, issue2.path);
11109
11284
  } else {
11110
- const fullpath = [...path5, ...issue2.path];
11285
+ const fullpath = [...path4, ...issue2.path];
11111
11286
  if (fullpath.length === 0) {
11112
11287
  result.errors.push(mapper(issue2));
11113
11288
  continue;
@@ -11139,8 +11314,8 @@ function treeifyError(error, _mapper) {
11139
11314
  }
11140
11315
  function toDotPath(_path) {
11141
11316
  const segs = [];
11142
- const path5 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
11143
- for (const seg of path5) {
11317
+ const path4 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
11318
+ for (const seg of path4) {
11144
11319
  if (typeof seg === "number")
11145
11320
  segs.push(`[${seg}]`);
11146
11321
  else if (typeof seg === "symbol")
@@ -22230,7 +22405,9 @@ var HookNameSchema = exports_external.enum([
22230
22405
  "edit-error-recovery",
22231
22406
  "prometheus-md-only",
22232
22407
  "start-work",
22233
- "sisyphus-orchestrator"
22408
+ "sisyphus-orchestrator",
22409
+ "maestro-sisyphus-bridge",
22410
+ "tdd-enforcement"
22234
22411
  ]);
22235
22412
  var BuiltinCommandNameSchema = exports_external.enum([
22236
22413
  "init-deep",
@@ -22400,6 +22577,18 @@ var GitMasterConfigSchema = exports_external.object({
22400
22577
  commit_footer: exports_external.boolean().default(true),
22401
22578
  include_co_authored_by: exports_external.boolean().default(true)
22402
22579
  });
22580
+ var MaestroConfigSchema = exports_external.object({
22581
+ autoExecute: exports_external.boolean().default(false),
22582
+ useDesignPhases: exports_external.boolean().default(true),
22583
+ useTracking: exports_external.boolean().default(true),
22584
+ preferredExecutionMode: exports_external.enum(["maestro", "sisyphus"]).default("maestro"),
22585
+ enforceTdd: exports_external.boolean().default(false),
22586
+ tddGates: exports_external.object({
22587
+ requireFailingTest: exports_external.boolean().default(true),
22588
+ requirePassingTest: exports_external.boolean().default(true),
22589
+ runFullSuiteAfterRefactor: exports_external.boolean().default(true)
22590
+ }).optional()
22591
+ });
22403
22592
  var OhMyOpenCodeConfigSchema = exports_external.object({
22404
22593
  $schema: exports_external.string().optional(),
22405
22594
  disabled_mcps: exports_external.array(AnyMcpNameSchema).optional(),
@@ -22410,7 +22599,6 @@ var OhMyOpenCodeConfigSchema = exports_external.object({
22410
22599
  agents: AgentOverridesSchema.optional(),
22411
22600
  categories: CategoriesConfigSchema.optional(),
22412
22601
  claude_code: ClaudeCodeConfigSchema.optional(),
22413
- google_auth: exports_external.boolean().optional(),
22414
22602
  sisyphus_agent: SisyphusAgentConfigSchema.optional(),
22415
22603
  comment_checker: CommentCheckerConfigSchema.optional(),
22416
22604
  experimental: ExperimentalConfigSchema.optional(),
@@ -22419,12 +22607,13 @@ var OhMyOpenCodeConfigSchema = exports_external.object({
22419
22607
  ralph_loop: RalphLoopConfigSchema.optional(),
22420
22608
  background_task: BackgroundTaskConfigSchema.optional(),
22421
22609
  notification: NotificationConfigSchema.optional(),
22422
- git_master: GitMasterConfigSchema.optional()
22610
+ git_master: GitMasterConfigSchema.optional(),
22611
+ maestro: MaestroConfigSchema.optional()
22423
22612
  });
22424
22613
  // src/cli/doctor/checks/config.ts
22425
- var USER_CONFIG_DIR2 = join6(homedir5(), ".config", "opencode");
22426
- var USER_CONFIG_BASE = join6(USER_CONFIG_DIR2, `${PACKAGE_NAME2}`);
22427
- var PROJECT_CONFIG_BASE = join6(process.cwd(), ".opencode", PACKAGE_NAME2);
22614
+ var USER_CONFIG_DIR2 = join5(homedir4(), ".config", "opencode");
22615
+ var USER_CONFIG_BASE = join5(USER_CONFIG_DIR2, `${PACKAGE_NAME2}`);
22616
+ var PROJECT_CONFIG_BASE = join5(process.cwd(), ".opencode", PACKAGE_NAME2);
22428
22617
  function findConfigPath() {
22429
22618
  const projectDetected = detectConfigFile(PROJECT_CONFIG_BASE);
22430
22619
  if (projectDetected.format !== "none") {
@@ -22522,15 +22711,15 @@ function getConfigCheckDefinition() {
22522
22711
 
22523
22712
  // src/cli/doctor/checks/auth.ts
22524
22713
  import { existsSync as existsSync8, readFileSync as readFileSync6 } from "fs";
22525
- import { homedir as homedir6 } from "os";
22526
- import { join as join7 } from "path";
22527
- var OPENCODE_CONFIG_DIR = join7(homedir6(), ".config", "opencode");
22528
- var OPENCODE_JSON = join7(OPENCODE_CONFIG_DIR, "opencode.json");
22529
- var OPENCODE_JSONC = join7(OPENCODE_CONFIG_DIR, "opencode.jsonc");
22714
+ import { homedir as homedir5 } from "os";
22715
+ import { join as join6 } from "path";
22716
+ var OPENCODE_CONFIG_DIR = join6(homedir5(), ".config", "opencode");
22717
+ var OPENCODE_JSON = join6(OPENCODE_CONFIG_DIR, "opencode.json");
22718
+ var OPENCODE_JSONC = join6(OPENCODE_CONFIG_DIR, "opencode.jsonc");
22530
22719
  var AUTH_PLUGINS = {
22531
22720
  anthropic: { plugin: "builtin", name: "Anthropic (Claude)" },
22532
22721
  openai: { plugin: "opencode-openai-codex-auth", name: "OpenAI (ChatGPT)" },
22533
- google: { plugin: "opencode-antigravity-auth", name: "Google (Gemini)" }
22722
+ google: { plugin: "opencode-proxypal-auth", name: "Google (Gemini)" }
22534
22723
  };
22535
22724
  function getOpenCodeConfig() {
22536
22725
  const configPath = existsSync8(OPENCODE_JSONC) ? OPENCODE_JSONC : OPENCODE_JSON;
@@ -22967,13 +23156,13 @@ function getLspCheckDefinition() {
22967
23156
 
22968
23157
  // src/cli/doctor/checks/mcp.ts
22969
23158
  import { existsSync as existsSync9, readFileSync as readFileSync7 } from "fs";
22970
- import { homedir as homedir7 } from "os";
22971
- import { join as join8 } from "path";
23159
+ import { homedir as homedir6 } from "os";
23160
+ import { join as join7 } from "path";
22972
23161
  var BUILTIN_MCP_SERVERS = ["context7", "grep_app"];
22973
23162
  var MCP_CONFIG_PATHS = [
22974
- join8(homedir7(), ".claude", ".mcp.json"),
22975
- join8(process.cwd(), ".mcp.json"),
22976
- join8(process.cwd(), ".claude", ".mcp.json")
23163
+ join7(homedir6(), ".claude", ".mcp.json"),
23164
+ join7(process.cwd(), ".mcp.json"),
23165
+ join7(process.cwd(), ".claude", ".mcp.json")
22977
23166
  ];
22978
23167
  function loadUserMcpConfig() {
22979
23168
  const servers = {};
@@ -23372,161 +23561,29 @@ async function doctor(options = {}) {
23372
23561
  return result.exitCode;
23373
23562
  }
23374
23563
 
23375
- // src/auth/antigravity/storage.ts
23376
- import { promises as fs4 } from "fs";
23377
- import { join as join9, dirname as dirname2 } from "path";
23378
- function getDataDir2() {
23379
- return join9(getDataDir(), "opencode");
23380
- }
23381
- function getStoragePath() {
23382
- return join9(getDataDir2(), "oh-my-opencode-accounts.json");
23383
- }
23384
- async function loadAccounts(path5) {
23385
- const storagePath = path5 ?? getStoragePath();
23386
- try {
23387
- const content = await fs4.readFile(storagePath, "utf-8");
23388
- const data = JSON.parse(content);
23389
- if (!isValidAccountStorage(data)) {
23390
- return null;
23391
- }
23392
- return data;
23393
- } catch (error45) {
23394
- const errorCode = error45.code;
23395
- if (errorCode === "ENOENT") {
23396
- return null;
23397
- }
23398
- if (error45 instanceof SyntaxError) {
23399
- return null;
23400
- }
23401
- throw error45;
23402
- }
23403
- }
23404
- async function saveAccounts(storage, path5) {
23405
- const storagePath = path5 ?? getStoragePath();
23406
- await fs4.mkdir(dirname2(storagePath), { recursive: true });
23407
- const content = JSON.stringify(storage, null, 2);
23408
- const tempPath = `${storagePath}.tmp.${process.pid}.${Date.now()}`;
23409
- await fs4.writeFile(tempPath, content, { encoding: "utf-8", mode: 384 });
23410
- try {
23411
- await fs4.rename(tempPath, storagePath);
23412
- } catch (error45) {
23413
- await fs4.unlink(tempPath).catch(() => {});
23414
- throw error45;
23415
- }
23416
- }
23417
- function isValidAccountStorage(data) {
23418
- if (typeof data !== "object" || data === null) {
23419
- return false;
23420
- }
23421
- const obj = data;
23422
- if (typeof obj.version !== "number") {
23423
- return false;
23424
- }
23425
- if (!Array.isArray(obj.accounts)) {
23426
- return false;
23427
- }
23428
- if (typeof obj.activeIndex !== "number") {
23429
- return false;
23430
- }
23431
- return true;
23432
- }
23433
-
23434
- // src/cli/commands/auth.ts
23435
- async function listAccounts() {
23436
- const accounts = await loadAccounts();
23437
- if (!accounts || accounts.accounts.length === 0) {
23438
- console.log("No accounts found.");
23439
- console.log("Run 'opencode auth login' and select Google (Antigravity) to add accounts.");
23440
- return 0;
23441
- }
23442
- console.log(`
23443
- Google Antigravity Accounts (${accounts.accounts.length}/10):
23444
- `);
23445
- for (let i2 = 0;i2 < accounts.accounts.length; i2++) {
23446
- const acc = accounts.accounts[i2];
23447
- const isActive = i2 === accounts.activeIndex;
23448
- const activeMarker = isActive ? "* " : " ";
23449
- console.log(`${activeMarker}[${i2}] ${acc.email || "Unknown"}`);
23450
- console.log(` Tier: ${acc.tier || "free"}`);
23451
- const rateLimits = acc.rateLimits || {};
23452
- const now = Date.now();
23453
- const limited = [];
23454
- if (rateLimits.claude && rateLimits.claude > now) {
23455
- const mins = Math.ceil((rateLimits.claude - now) / 60000);
23456
- limited.push(`claude (${mins}m)`);
23457
- }
23458
- if (rateLimits["gemini-flash"] && rateLimits["gemini-flash"] > now) {
23459
- const mins = Math.ceil((rateLimits["gemini-flash"] - now) / 60000);
23460
- limited.push(`gemini-flash (${mins}m)`);
23461
- }
23462
- if (rateLimits["gemini-pro"] && rateLimits["gemini-pro"] > now) {
23463
- const mins = Math.ceil((rateLimits["gemini-pro"] - now) / 60000);
23464
- limited.push(`gemini-pro (${mins}m)`);
23465
- }
23466
- if (limited.length > 0) {
23467
- console.log(` Rate limited: ${limited.join(", ")}`);
23468
- }
23469
- console.log();
23470
- }
23471
- return 0;
23472
- }
23473
- async function removeAccount(indexOrEmail) {
23474
- const accounts = await loadAccounts();
23475
- if (!accounts || accounts.accounts.length === 0) {
23476
- console.error("No accounts found.");
23477
- return 1;
23478
- }
23479
- let index;
23480
- const parsedIndex = Number(indexOrEmail);
23481
- if (Number.isInteger(parsedIndex) && String(parsedIndex) === indexOrEmail) {
23482
- index = parsedIndex;
23483
- } else {
23484
- index = accounts.accounts.findIndex((acc) => acc.email === indexOrEmail);
23485
- if (index === -1) {
23486
- console.error(`Account not found: ${indexOrEmail}`);
23487
- return 1;
23488
- }
23489
- }
23490
- if (index < 0 || index >= accounts.accounts.length) {
23491
- console.error(`Invalid index: ${index}. Valid range: 0-${accounts.accounts.length - 1}`);
23492
- return 1;
23493
- }
23494
- const removed = accounts.accounts[index];
23495
- accounts.accounts.splice(index, 1);
23496
- if (accounts.accounts.length === 0) {
23497
- accounts.activeIndex = -1;
23498
- } else if (accounts.activeIndex >= accounts.accounts.length) {
23499
- accounts.activeIndex = accounts.accounts.length - 1;
23500
- } else if (accounts.activeIndex > index) {
23501
- accounts.activeIndex--;
23502
- }
23503
- await saveAccounts(accounts);
23504
- console.log(`Removed account: ${removed.email || "Unknown"} (index ${index})`);
23505
- console.log(`Remaining accounts: ${accounts.accounts.length}`);
23506
- return 0;
23507
- }
23508
-
23509
23564
  // src/cli/index.ts
23510
23565
  var packageJson = await Promise.resolve().then(() => __toESM(require_package(), 1));
23511
23566
  var VERSION = packageJson.version;
23512
23567
  var program2 = new Command;
23513
23568
  program2.name("oh-my-opencode").description("The ultimate OpenCode plugin - multi-model orchestration, LSP tools, and more").version(VERSION, "-v, --version", "Show version number");
23514
- program2.command("install").description("Install and configure oh-my-opencode with interactive setup").option("--no-tui", "Run in non-interactive mode (requires all options)").option("--claude <value>", "Claude subscription: no, yes, max20").option("--chatgpt <value>", "ChatGPT subscription: no, yes").option("--gemini <value>", "Gemini integration: no, yes").option("--skip-auth", "Skip authentication setup hints").addHelpText("after", `
23569
+ program2.command("install").description("Install and configure oh-my-opencode with interactive setup").option("--no-tui", "Run in non-interactive mode (requires all options)").option("--proxypal <value>", "ProxyPal proxy: no, yes (if yes, skips claude/chatgpt)").option("--claude <value>", "Claude subscription: no, yes, max20").option("--chatgpt <value>", "ChatGPT subscription: no, yes").option("--skip-auth", "Skip authentication setup hints").addHelpText("after", `
23515
23570
  Examples:
23516
23571
  $ bunx oh-my-opencode install
23517
- $ bunx oh-my-opencode install --no-tui --claude=max20 --chatgpt=yes --gemini=yes
23518
- $ bunx oh-my-opencode install --no-tui --claude=no --chatgpt=no --gemini=no
23572
+ $ bunx oh-my-opencode install --no-tui --proxypal=yes
23573
+ $ bunx oh-my-opencode install --no-tui --claude=max20 --chatgpt=yes
23574
+ $ bunx oh-my-opencode install --no-tui --claude=no --chatgpt=no
23519
23575
 
23520
23576
  Model Providers:
23577
+ ProxyPal Use ProxyPal proxy for all models (github.com/heyhuynhgiabuu/proxypal)
23521
23578
  Claude Required for Sisyphus (main orchestrator) and Librarian agents
23522
23579
  ChatGPT Powers the Oracle agent for debugging and architecture
23523
23580
  Gemini Powers frontend, documentation, and multimodal agents
23524
23581
  `).action(async (options) => {
23525
23582
  const args = {
23526
23583
  tui: options.tui !== false,
23584
+ proxypal: options.proxypal,
23527
23585
  claude: options.claude,
23528
23586
  chatgpt: options.chatgpt,
23529
- gemini: options.gemini,
23530
23587
  skipAuth: options.skipAuth ?? false
23531
23588
  };
23532
23589
  const exitCode = await install(args);
@@ -23593,32 +23650,6 @@ Categories:
23593
23650
  const exitCode = await doctor(doctorOptions);
23594
23651
  process.exit(exitCode);
23595
23652
  });
23596
- var authCommand = program2.command("auth").description("Manage Google Antigravity accounts");
23597
- authCommand.command("list").description("List all Google Antigravity accounts").addHelpText("after", `
23598
- Examples:
23599
- $ bunx oh-my-opencode auth list
23600
-
23601
- Shows:
23602
- - Account index and email
23603
- - Account tier (free/paid)
23604
- - Active account (marked with *)
23605
- - Rate limit status per model family
23606
- `).action(async () => {
23607
- const exitCode = await listAccounts();
23608
- process.exit(exitCode);
23609
- });
23610
- authCommand.command("remove <index-or-email>").description("Remove an account by index or email").addHelpText("after", `
23611
- Examples:
23612
- $ bunx oh-my-opencode auth remove 0
23613
- $ bunx oh-my-opencode auth remove user@example.com
23614
-
23615
- Note:
23616
- - Use 'auth list' to see account indices
23617
- - Removing the active account will switch to the next available account
23618
- `).action(async (indexOrEmail) => {
23619
- const exitCode = await removeAccount(indexOrEmail);
23620
- process.exit(exitCode);
23621
- });
23622
23653
  program2.command("version").description("Show version information").action(() => {
23623
23654
  console.log(`oh-my-opencode v${VERSION}`);
23624
23655
  });