@reinamaccredy/oh-my-opencode 3.0.0-beta.9 → 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 (60) hide show
  1. package/dist/agents/types.d.ts +2 -0
  2. package/dist/cli/config-manager.d.ts +3 -17
  3. package/dist/cli/index.js +384 -357
  4. package/dist/cli/types.d.ts +3 -1
  5. package/dist/config/index.d.ts +2 -2
  6. package/dist/config/schema.d.ts +215 -181
  7. package/dist/features/background-agent/index.d.ts +1 -1
  8. package/dist/features/background-agent/manager.d.ts +10 -0
  9. package/dist/features/background-agent/types.d.ts +4 -0
  10. package/dist/features/boulder-state/index.d.ts +1 -0
  11. package/dist/features/boulder-state/unified-state.d.ts +86 -0
  12. package/dist/features/maestro/hooks/index.d.ts +16 -0
  13. package/dist/features/maestro/index.d.ts +4 -0
  14. package/dist/features/maestro/skills/index.d.ts +4 -0
  15. package/dist/features/maestro/types.d.ts +42 -0
  16. package/dist/features/maestro/utils/index.d.ts +4 -0
  17. package/dist/features/workflow-engine/contracts/v1/types.d.ts +9 -0
  18. package/dist/hooks/background-notification/index.d.ts +10 -0
  19. package/dist/hooks/index.d.ts +3 -0
  20. package/dist/hooks/maestro-sisyphus-bridge/constants.d.ts +9 -0
  21. package/dist/hooks/maestro-sisyphus-bridge/index.d.ts +53 -0
  22. package/dist/hooks/tdd-enforcement/constants.d.ts +16 -0
  23. package/dist/hooks/tdd-enforcement/index.d.ts +54 -0
  24. package/dist/index.js +1952 -6032
  25. package/dist/shared/migration.d.ts +13 -0
  26. package/dist/tools/skill/tools.d.ts +1 -7
  27. package/dist/tools/slashcommand/tools.d.ts +1 -7
  28. package/package.json +3 -6
  29. package/dist/auth/antigravity/accounts.d.ts +0 -40
  30. package/dist/auth/antigravity/accounts.test.d.ts +0 -1
  31. package/dist/auth/antigravity/browser.d.ts +0 -27
  32. package/dist/auth/antigravity/browser.test.d.ts +0 -1
  33. package/dist/auth/antigravity/cli.d.ts +0 -2
  34. package/dist/auth/antigravity/cli.test.d.ts +0 -1
  35. package/dist/auth/antigravity/constants.d.ts +0 -98
  36. package/dist/auth/antigravity/constants.test.d.ts +0 -1
  37. package/dist/auth/antigravity/fetch.d.ts +0 -69
  38. package/dist/auth/antigravity/index.d.ts +0 -13
  39. package/dist/auth/antigravity/integration.test.d.ts +0 -10
  40. package/dist/auth/antigravity/message-converter.d.ts +0 -54
  41. package/dist/auth/antigravity/oauth.d.ts +0 -51
  42. package/dist/auth/antigravity/oauth.test.d.ts +0 -1
  43. package/dist/auth/antigravity/plugin.d.ts +0 -54
  44. package/dist/auth/antigravity/project.d.ts +0 -10
  45. package/dist/auth/antigravity/request.d.ts +0 -116
  46. package/dist/auth/antigravity/request.test.d.ts +0 -1
  47. package/dist/auth/antigravity/response.d.ts +0 -137
  48. package/dist/auth/antigravity/storage.d.ts +0 -5
  49. package/dist/auth/antigravity/storage.test.d.ts +0 -1
  50. package/dist/auth/antigravity/thinking.d.ts +0 -278
  51. package/dist/auth/antigravity/thinking.test.d.ts +0 -10
  52. package/dist/auth/antigravity/thought-signature-store.d.ts +0 -52
  53. package/dist/auth/antigravity/token.d.ts +0 -38
  54. package/dist/auth/antigravity/token.test.d.ts +0 -1
  55. package/dist/auth/antigravity/tools.d.ts +0 -119
  56. package/dist/auth/antigravity/types.d.ts +0 -229
  57. package/dist/cli/commands/auth.d.ts +0 -2
  58. package/dist/cli/config-manager.test.d.ts +0 -1
  59. package/dist/google-auth.d.ts +0 -3
  60. 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.9",
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,14 +2270,10 @@ 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",
@@ -2321,6 +2317,7 @@ var require_package = __commonJS((exports, module) => {
2321
2317
  "@openauthjs/openauth": "^0.4.3",
2322
2318
  "@opencode-ai/plugin": "^1.1.1",
2323
2319
  "@opencode-ai/sdk": "^1.1.1",
2320
+ "@reinamaccredy/oh-my-opencode": "^3.0.0-beta.13",
2324
2321
  commander: "^14.0.2",
2325
2322
  hono: "^4.10.4",
2326
2323
  "js-yaml": "^4.1.1",
@@ -5614,12 +5611,6 @@ function log(message, data) {
5614
5611
  var DANGEROUS_KEYS = new Set(["__proto__", "constructor", "prototype"]);
5615
5612
  // src/shared/dynamic-truncator.ts
5616
5613
  var ANTHROPIC_ACTUAL_LIMIT = process.env.ANTHROPIC_1M_CONTEXT === "true" || process.env.VERTEX_ANTHROPIC_1M_CONTEXT === "true" ? 1e6 : 200000;
5617
- // src/shared/data-path.ts
5618
- import * as path2 from "path";
5619
- import * as os2 from "os";
5620
- function getDataDir() {
5621
- return process.env.XDG_DATA_HOME ?? path2.join(os2.homedir(), ".local", "share");
5622
- }
5623
5614
  // src/shared/jsonc-parser.ts
5624
5615
  import { existsSync, readFileSync } from "fs";
5625
5616
 
@@ -6490,8 +6481,8 @@ function detectConfigFile(basePath) {
6490
6481
  }
6491
6482
  // src/shared/opencode-config-dir.ts
6492
6483
  import { existsSync as existsSync2 } from "fs";
6493
- import { homedir as homedir2 } from "os";
6494
- import { join as join3 } from "path";
6484
+ import { homedir } from "os";
6485
+ import { join as join2 } from "path";
6495
6486
  var TAURI_APP_IDENTIFIER = "ai.opencode.desktop";
6496
6487
  var TAURI_APP_IDENTIFIER_DEV = "ai.opencode.desktop.dev";
6497
6488
  function isDevBuild(version) {
@@ -6503,35 +6494,35 @@ function getTauriConfigDir(identifier) {
6503
6494
  const platform = process.platform;
6504
6495
  switch (platform) {
6505
6496
  case "darwin":
6506
- return join3(homedir2(), "Library", "Application Support", identifier);
6497
+ return join2(homedir(), "Library", "Application Support", identifier);
6507
6498
  case "win32": {
6508
- const appData = process.env.APPDATA || join3(homedir2(), "AppData", "Roaming");
6509
- return join3(appData, identifier);
6499
+ const appData = process.env.APPDATA || join2(homedir(), "AppData", "Roaming");
6500
+ return join2(appData, identifier);
6510
6501
  }
6511
6502
  case "linux":
6512
6503
  default: {
6513
- const xdgConfig = process.env.XDG_CONFIG_HOME || join3(homedir2(), ".config");
6514
- return join3(xdgConfig, identifier);
6504
+ const xdgConfig = process.env.XDG_CONFIG_HOME || join2(homedir(), ".config");
6505
+ return join2(xdgConfig, identifier);
6515
6506
  }
6516
6507
  }
6517
6508
  }
6518
6509
  function getCliConfigDir() {
6519
6510
  if (process.platform === "win32") {
6520
- const crossPlatformDir = join3(homedir2(), ".config", "opencode");
6521
- const crossPlatformConfig = join3(crossPlatformDir, "opencode.json");
6511
+ const crossPlatformDir = join2(homedir(), ".config", "opencode");
6512
+ const crossPlatformConfig = join2(crossPlatformDir, "opencode.json");
6522
6513
  if (existsSync2(crossPlatformConfig)) {
6523
6514
  return crossPlatformDir;
6524
6515
  }
6525
- const appData = process.env.APPDATA || join3(homedir2(), "AppData", "Roaming");
6526
- const appdataDir = join3(appData, "opencode");
6527
- 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");
6528
6519
  if (existsSync2(appdataConfig)) {
6529
6520
  return appdataDir;
6530
6521
  }
6531
6522
  return crossPlatformDir;
6532
6523
  }
6533
- const xdgConfig = process.env.XDG_CONFIG_HOME || join3(homedir2(), ".config");
6534
- return join3(xdgConfig, "opencode");
6524
+ const xdgConfig = process.env.XDG_CONFIG_HOME || join2(homedir(), ".config");
6525
+ return join2(xdgConfig, "opencode");
6535
6526
  }
6536
6527
  function getOpenCodeConfigDir(options) {
6537
6528
  const { binary: binary2, version, checkExisting = true } = options;
@@ -6542,8 +6533,8 @@ function getOpenCodeConfigDir(options) {
6542
6533
  const tauriDir = getTauriConfigDir(identifier);
6543
6534
  if (checkExisting) {
6544
6535
  const legacyDir = getCliConfigDir();
6545
- const legacyConfig = join3(legacyDir, "opencode.json");
6546
- const legacyConfigC = join3(legacyDir, "opencode.jsonc");
6536
+ const legacyConfig = join2(legacyDir, "opencode.json");
6537
+ const legacyConfigC = join2(legacyDir, "opencode.jsonc");
6547
6538
  if (existsSync2(legacyConfig) || existsSync2(legacyConfigC)) {
6548
6539
  return legacyDir;
6549
6540
  }
@@ -6554,10 +6545,10 @@ function getOpenCodeConfigPaths(options) {
6554
6545
  const configDir = getOpenCodeConfigDir(options);
6555
6546
  return {
6556
6547
  configDir,
6557
- configJson: join3(configDir, "opencode.json"),
6558
- configJsonc: join3(configDir, "opencode.jsonc"),
6559
- packageJson: join3(configDir, "package.json"),
6560
- 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")
6561
6552
  };
6562
6553
  }
6563
6554
  // src/shared/opencode-version.ts
@@ -6642,26 +6633,26 @@ function detectConfigFormat() {
6642
6633
  function isEmptyOrWhitespace(content) {
6643
6634
  return content.trim().length === 0;
6644
6635
  }
6645
- function parseConfigWithError(path3) {
6636
+ function parseConfigWithError(path2) {
6646
6637
  try {
6647
- const stat = statSync(path3);
6638
+ const stat = statSync(path2);
6648
6639
  if (stat.size === 0) {
6649
- 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.` };
6650
6641
  }
6651
- const content = readFileSync2(path3, "utf-8");
6642
+ const content = readFileSync2(path2, "utf-8");
6652
6643
  if (isEmptyOrWhitespace(content)) {
6653
- 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.` };
6654
6645
  }
6655
6646
  const config = parseJsonc(content);
6656
6647
  if (config === null || config === undefined) {
6657
- 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.` };
6658
6649
  }
6659
6650
  if (typeof config !== "object" || Array.isArray(config)) {
6660
- 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}` };
6661
6652
  }
6662
6653
  return { config };
6663
6654
  } catch (err) {
6664
- return { config: null, error: formatErrorWithSuggestion(err, `parse config file ${path3}`) };
6655
+ return { config: null, error: formatErrorWithSuggestion(err, `parse config file ${path2}`) };
6665
6656
  }
6666
6657
  }
6667
6658
  function ensureConfigDir() {
@@ -6676,27 +6667,27 @@ function addPluginToOpenCodeConfig() {
6676
6667
  } catch (err) {
6677
6668
  return { success: false, configPath: getConfigDir(), error: formatErrorWithSuggestion(err, "create config directory") };
6678
6669
  }
6679
- const { format: format2, path: path3 } = detectConfigFormat();
6670
+ const { format: format2, path: path2 } = detectConfigFormat();
6680
6671
  const pluginName = "oh-my-opencode";
6681
6672
  try {
6682
6673
  if (format2 === "none") {
6683
6674
  const config2 = { plugin: [pluginName] };
6684
- writeFileSync(path3, JSON.stringify(config2, null, 2) + `
6675
+ writeFileSync(path2, JSON.stringify(config2, null, 2) + `
6685
6676
  `);
6686
- return { success: true, configPath: path3 };
6677
+ return { success: true, configPath: path2 };
6687
6678
  }
6688
- const parseResult = parseConfigWithError(path3);
6679
+ const parseResult = parseConfigWithError(path2);
6689
6680
  if (!parseResult.config) {
6690
- 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" };
6691
6682
  }
6692
6683
  const config = parseResult.config;
6693
6684
  const plugins = config.plugin ?? [];
6694
6685
  if (plugins.some((p2) => p2.startsWith(pluginName))) {
6695
- return { success: true, configPath: path3 };
6686
+ return { success: true, configPath: path2 };
6696
6687
  }
6697
6688
  config.plugin = [...plugins, pluginName];
6698
6689
  if (format2 === "jsonc") {
6699
- const content = readFileSync2(path3, "utf-8");
6690
+ const content = readFileSync2(path2, "utf-8");
6700
6691
  const pluginArrayRegex = /"plugin"\s*:\s*\[([\s\S]*?)\]/;
6701
6692
  const match = content.match(pluginArrayRegex);
6702
6693
  if (match) {
@@ -6706,19 +6697,19 @@ function addPluginToOpenCodeConfig() {
6706
6697
  const newContent = content.replace(pluginArrayRegex, `"plugin": [
6707
6698
  ${newArrayContent}
6708
6699
  ]`);
6709
- writeFileSync(path3, newContent);
6700
+ writeFileSync(path2, newContent);
6710
6701
  } else {
6711
6702
  const newContent = content.replace(/^(\s*\{)/, `$1
6712
6703
  "plugin": ["${pluginName}"],`);
6713
- writeFileSync(path3, newContent);
6704
+ writeFileSync(path2, newContent);
6714
6705
  }
6715
6706
  } else {
6716
- writeFileSync(path3, JSON.stringify(config, null, 2) + `
6707
+ writeFileSync(path2, JSON.stringify(config, null, 2) + `
6717
6708
  `);
6718
6709
  }
6719
- return { success: true, configPath: path3 };
6710
+ return { success: true, configPath: path2 };
6720
6711
  } catch (err) {
6721
- return { success: false, configPath: path3, error: formatErrorWithSuggestion(err, "update opencode config") };
6712
+ return { success: false, configPath: path2, error: formatErrorWithSuggestion(err, "update opencode config") };
6722
6713
  }
6723
6714
  }
6724
6715
  function deepMerge(target, source) {
@@ -6736,13 +6727,23 @@ function deepMerge(target, source) {
6736
6727
  }
6737
6728
  function generateOmoConfig(installConfig) {
6738
6729
  const config = {
6739
- $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"
6740
6731
  };
6741
- if (installConfig.hasGemini) {
6742
- config.google_auth = false;
6743
- }
6732
+ if (installConfig.hasProxyPal || installConfig.hasGemini) {}
6744
6733
  const agents = {};
6745
- 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) {
6746
6747
  agents["Sisyphus"] = { model: "proxypal/gemini-claude-opus-4-5-thinking" };
6747
6748
  agents["librarian"] = { model: "proxypal/gemini-claude-opus-4-5-thinking" };
6748
6749
  agents["explore"] = { model: "proxypal/gemini-3-flash-preview" };
@@ -6767,19 +6768,31 @@ function generateOmoConfig(installConfig) {
6767
6768
  agents["document-writer"] = { model: "opencode/glm-4.7-free" };
6768
6769
  agents["multimodal-looker"] = { model: "opencode/glm-4.7-free" };
6769
6770
  }
6770
- if (installConfig.hasChatGPT) {
6771
- agents["oracle"] = { model: "proxypal/gpt-5.2-codex" };
6772
- agents["Momus (Plan Reviewer)"] = { model: "proxypal/gpt-5.2-codex" };
6773
- } else if (installConfig.hasClaude) {
6774
- agents["oracle"] = { model: "anthropic/claude-opus-4-5" };
6775
- agents["Momus (Plan Reviewer)"] = { model: "anthropic/claude-opus-4-5" };
6776
- } else {
6777
- 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
+ }
6778
6781
  }
6779
6782
  if (Object.keys(agents).length > 0) {
6780
6783
  config.agents = agents;
6781
6784
  }
6782
- if (installConfig.hasGemini) {
6785
+ if (installConfig.hasProxyPal) {
6786
+ config.categories = {
6787
+ "visual-engineering": { model: "proxypal/gemini-3-pro-preview" },
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) {
6783
6796
  config.categories = {
6784
6797
  "visual-engineering": { model: "proxypal/gemini-3-pro-preview" },
6785
6798
  ultrabrain: { model: "proxypal/gpt-5.2-codex" },
@@ -6875,11 +6888,11 @@ async function addAuthPlugins(config) {
6875
6888
  } catch (err) {
6876
6889
  return { success: false, configPath: getConfigDir(), error: formatErrorWithSuggestion(err, "create config directory") };
6877
6890
  }
6878
- const { format: format2, path: path3 } = detectConfigFormat();
6891
+ const { format: format2, path: path2 } = detectConfigFormat();
6879
6892
  try {
6880
6893
  let existingConfig = null;
6881
6894
  if (format2 !== "none") {
6882
- const parseResult = parseConfigWithError(path3);
6895
+ const parseResult = parseConfigWithError(path2);
6883
6896
  if (parseResult.error && !parseResult.config) {
6884
6897
  existingConfig = {};
6885
6898
  } else {
@@ -6888,9 +6901,9 @@ async function addAuthPlugins(config) {
6888
6901
  }
6889
6902
  const plugins = existingConfig?.plugin ?? [];
6890
6903
  if (config.hasGemini) {
6891
- const version = await fetchLatestVersion("opencode-antigravity-auth");
6892
- const pluginEntry = version ? `opencode-antigravity-auth@${version}` : "opencode-antigravity-auth";
6893
- 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"))) {
6894
6907
  plugins.push(pluginEntry);
6895
6908
  }
6896
6909
  }
@@ -6900,33 +6913,105 @@ async function addAuthPlugins(config) {
6900
6913
  }
6901
6914
  }
6902
6915
  const newConfig = { ...existingConfig ?? {}, plugin: plugins };
6903
- writeFileSync(path3, JSON.stringify(newConfig, null, 2) + `
6916
+ writeFileSync(path2, JSON.stringify(newConfig, null, 2) + `
6904
6917
  `);
6905
- return { success: true, configPath: path3 };
6918
+ return { success: true, configPath: path2 };
6906
6919
  } catch (err) {
6907
- 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") };
6908
6921
  }
6909
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
+ };
6910
6995
  var ANTIGRAVITY_PROVIDER_CONFIG = {
6911
6996
  google: {
6912
6997
  name: "Google",
6913
6998
  models: {
6914
- "antigravity-gemini-3-pro-high": {
6915
- name: "Gemini 3 Pro High (Antigravity)",
6999
+ "gemini-3-pro-high": {
7000
+ name: "Gemini 3 Pro High (ProxyPal)",
6916
7001
  thinking: true,
6917
7002
  attachment: true,
6918
7003
  limit: { context: 1048576, output: 65535 },
6919
7004
  modalities: { input: ["text", "image", "pdf"], output: ["text"] }
6920
7005
  },
6921
- "antigravity-gemini-3-pro-low": {
6922
- name: "Gemini 3 Pro Low (Antigravity)",
7006
+ "gemini-3-pro-low": {
7007
+ name: "Gemini 3 Pro Low (ProxyPal)",
6923
7008
  thinking: true,
6924
7009
  attachment: true,
6925
7010
  limit: { context: 1048576, output: 65535 },
6926
7011
  modalities: { input: ["text", "image", "pdf"], output: ["text"] }
6927
7012
  },
6928
- "antigravity-gemini-3-flash": {
6929
- name: "Gemini 3 Flash (Antigravity)",
7013
+ "gemini-3-flash": {
7014
+ name: "Gemini 3 Flash (ProxyPal)",
6930
7015
  attachment: true,
6931
7016
  limit: { context: 1048576, output: 65536 },
6932
7017
  modalities: { input: ["text", "image", "pdf"], output: ["text"] }
@@ -6988,11 +7073,11 @@ function addProviderConfig(config) {
6988
7073
  } catch (err) {
6989
7074
  return { success: false, configPath: getConfigDir(), error: formatErrorWithSuggestion(err, "create config directory") };
6990
7075
  }
6991
- const { format: format2, path: path3 } = detectConfigFormat();
7076
+ const { format: format2, path: path2 } = detectConfigFormat();
6992
7077
  try {
6993
7078
  let existingConfig = null;
6994
7079
  if (format2 !== "none") {
6995
- const parseResult = parseConfigWithError(path3);
7080
+ const parseResult = parseConfigWithError(path2);
6996
7081
  if (parseResult.error && !parseResult.config) {
6997
7082
  existingConfig = {};
6998
7083
  } else {
@@ -7001,6 +7086,9 @@ function addProviderConfig(config) {
7001
7086
  }
7002
7087
  const newConfig = { ...existingConfig ?? {} };
7003
7088
  const providers = newConfig.provider ?? {};
7089
+ if (config.hasProxyPal) {
7090
+ providers.proxypal = PROXYPAL_PROVIDER_CONFIG.proxypal;
7091
+ }
7004
7092
  if (config.hasGemini) {
7005
7093
  providers.google = ANTIGRAVITY_PROVIDER_CONFIG.google;
7006
7094
  }
@@ -7010,26 +7098,27 @@ function addProviderConfig(config) {
7010
7098
  if (Object.keys(providers).length > 0) {
7011
7099
  newConfig.provider = providers;
7012
7100
  }
7013
- writeFileSync(path3, JSON.stringify(newConfig, null, 2) + `
7101
+ writeFileSync(path2, JSON.stringify(newConfig, null, 2) + `
7014
7102
  `);
7015
- return { success: true, configPath: path3 };
7103
+ return { success: true, configPath: path2 };
7016
7104
  } catch (err) {
7017
- return { success: false, configPath: path3, error: formatErrorWithSuggestion(err, "add provider config") };
7105
+ return { success: false, configPath: path2, error: formatErrorWithSuggestion(err, "add provider config") };
7018
7106
  }
7019
7107
  }
7020
7108
  function detectCurrentConfig() {
7021
7109
  const result = {
7022
7110
  isInstalled: false,
7111
+ hasProxyPal: false,
7023
7112
  hasClaude: true,
7024
7113
  isMax20: true,
7025
7114
  hasChatGPT: true,
7026
7115
  hasGemini: false
7027
7116
  };
7028
- const { format: format2, path: path3 } = detectConfigFormat();
7117
+ const { format: format2, path: path2 } = detectConfigFormat();
7029
7118
  if (format2 === "none") {
7030
7119
  return result;
7031
7120
  }
7032
- const parseResult = parseConfigWithError(path3);
7121
+ const parseResult = parseConfigWithError(path2);
7033
7122
  if (!parseResult.config) {
7034
7123
  return result;
7035
7124
  }
@@ -7039,7 +7128,7 @@ function detectCurrentConfig() {
7039
7128
  if (!result.isInstalled) {
7040
7129
  return result;
7041
7130
  }
7042
- result.hasGemini = plugins.some((p2) => p2.startsWith("opencode-antigravity-auth"));
7131
+ result.hasGemini = plugins.some((p2) => p2.startsWith("opencode-proxypal-auth"));
7043
7132
  result.hasChatGPT = plugins.some((p2) => p2.startsWith("opencode-openai-codex-auth"));
7044
7133
  const omoConfigPath = getOmoConfig();
7045
7134
  if (!existsSync3(omoConfigPath)) {
@@ -7059,6 +7148,14 @@ function detectCurrentConfig() {
7059
7148
  return result;
7060
7149
  }
7061
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
+ }
7062
7159
  if (agents["Sisyphus"]?.model === "opencode/glm-4.7-free") {
7063
7160
  result.hasClaude = false;
7064
7161
  result.isMax20 = false;
@@ -7071,9 +7168,6 @@ function detectCurrentConfig() {
7071
7168
  } else if (agents["oracle"]?.model === "opencode/glm-4.7-free") {
7072
7169
  result.hasChatGPT = false;
7073
7170
  }
7074
- if (omoConfig.google_auth === false) {
7075
- result.hasGemini = plugins.some((p2) => p2.startsWith("opencode-antigravity-auth"));
7076
- }
7077
7171
  } catch {}
7078
7172
  return result;
7079
7173
  }
@@ -7098,19 +7192,41 @@ function formatConfigSummary(config) {
7098
7192
  const lines = [];
7099
7193
  lines.push(import_picocolors2.default.bold(import_picocolors2.default.white("Configuration Summary")));
7100
7194
  lines.push("");
7101
- const claudeDetail = config.hasClaude ? config.isMax20 ? "max20" : "standard" : undefined;
7102
- lines.push(formatProvider("Claude", config.hasClaude, claudeDetail));
7103
- lines.push(formatProvider("ChatGPT", config.hasChatGPT));
7104
- 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
+ }
7105
7206
  lines.push("");
7106
7207
  lines.push(import_picocolors2.default.dim("\u2500".repeat(40)));
7107
7208
  lines.push("");
7108
7209
  lines.push(import_picocolors2.default.bold(import_picocolors2.default.white("Agent Configuration")));
7109
7210
  lines.push("");
7110
- const sisyphusModel = config.hasClaude ? "claude-opus-4-5" : "glm-4.7-free";
7111
- const oracleModel = config.hasChatGPT ? "gpt-5.2" : config.hasClaude ? "claude-opus-4-5" : "glm-4.7-free";
7112
- const librarianModel = "glm-4.7-free";
7113
- 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
+ }
7114
7230
  lines.push(` ${SYMBOLS.bullet} Sisyphus ${SYMBOLS.arrow} ${import_picocolors2.default.cyan(sisyphusModel)}`);
7115
7231
  lines.push(` ${SYMBOLS.bullet} Oracle ${SYMBOLS.arrow} ${import_picocolors2.default.cyan(oracleModel)}`);
7116
7232
  lines.push(` ${SYMBOLS.bullet} Librarian ${SYMBOLS.arrow} ${import_picocolors2.default.cyan(librarianModel)}`);
@@ -7161,6 +7277,12 @@ function printBox(content, title) {
7161
7277
  }
7162
7278
  function validateNonTuiArgs(args) {
7163
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
+ }
7164
7286
  if (args.claude === undefined) {
7165
7287
  errors.push("--claude is required (values: no, yes, max20)");
7166
7288
  } else if (!["no", "yes", "max20"].includes(args.claude)) {
@@ -7171,19 +7293,24 @@ function validateNonTuiArgs(args) {
7171
7293
  } else if (!["no", "yes"].includes(args.chatgpt)) {
7172
7294
  errors.push(`Invalid --chatgpt value: ${args.chatgpt} (expected: no, yes)`);
7173
7295
  }
7174
- if (args.gemini === undefined) {
7175
- errors.push("--gemini is required (values: no, yes)");
7176
- } else if (!["no", "yes"].includes(args.gemini)) {
7177
- errors.push(`Invalid --gemini value: ${args.gemini} (expected: no, yes)`);
7178
- }
7179
7296
  return { valid: errors.length === 0, errors };
7180
7297
  }
7181
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
+ }
7182
7308
  return {
7309
+ hasProxyPal: false,
7183
7310
  hasClaude: args.claude !== "no",
7184
7311
  isMax20: args.claude === "max20",
7185
7312
  hasChatGPT: args.chatgpt === "yes",
7186
- hasGemini: args.gemini === "yes"
7313
+ hasGemini: false
7187
7314
  };
7188
7315
  }
7189
7316
  function detectedToInitialValues(detected) {
@@ -7192,13 +7319,34 @@ function detectedToInitialValues(detected) {
7192
7319
  claude = detected.isMax20 ? "max20" : "yes";
7193
7320
  }
7194
7321
  return {
7322
+ proxypal: detected.hasProxyPal ? "yes" : "no",
7195
7323
  claude,
7196
- chatgpt: detected.hasChatGPT ? "yes" : "no",
7197
- gemini: detected.hasGemini ? "yes" : "no"
7324
+ chatgpt: detected.hasChatGPT ? "yes" : "no"
7198
7325
  };
7199
7326
  }
7200
7327
  async function runTuiMode(detected) {
7201
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
+ }
7202
7350
  const claude = await ve({
7203
7351
  message: "Do you have a Claude Pro/Max subscription?",
7204
7352
  options: [
@@ -7224,23 +7372,12 @@ async function runTuiMode(detected) {
7224
7372
  xe("Installation cancelled.");
7225
7373
  return null;
7226
7374
  }
7227
- const gemini = await ve({
7228
- message: "Will you integrate Google Gemini?",
7229
- options: [
7230
- { value: "no", label: "No", hint: "Frontend/docs agents will use fallback" },
7231
- { value: "yes", label: "Yes", hint: "Beautiful UI generation with Gemini 3 Pro" }
7232
- ],
7233
- initialValue: initial.gemini
7234
- });
7235
- if (pD(gemini)) {
7236
- xe("Installation cancelled.");
7237
- return null;
7238
- }
7239
7375
  return {
7376
+ hasProxyPal: false,
7240
7377
  hasClaude: claude !== "no",
7241
7378
  isMax20: claude === "max20",
7242
7379
  hasChatGPT: chatgpt === "yes",
7243
- hasGemini: gemini === "yes"
7380
+ hasGemini: false
7244
7381
  };
7245
7382
  }
7246
7383
  async function runNonTuiInstall(args) {
@@ -7252,7 +7389,8 @@ async function runNonTuiInstall(args) {
7252
7389
  console.log(` ${SYMBOLS.bullet} ${err}`);
7253
7390
  }
7254
7391
  console.log();
7255
- 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>");
7256
7394
  console.log();
7257
7395
  return 1;
7258
7396
  }
@@ -7272,7 +7410,11 @@ async function runNonTuiInstall(args) {
7272
7410
  printSuccess(`OpenCode ${version ?? ""} detected`);
7273
7411
  if (isUpdate) {
7274
7412
  const initial = detectedToInitialValues(detected);
7275
- 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
+ }
7276
7418
  }
7277
7419
  const config = argsToConfig(args);
7278
7420
  printStep(step++, totalSteps, "Adding oh-my-opencode plugin...");
@@ -7282,7 +7424,16 @@ async function runNonTuiInstall(args) {
7282
7424
  return 1;
7283
7425
  }
7284
7426
  printSuccess(`Plugin ${isUpdate ? "verified" : "added"} ${SYMBOLS.arrow} ${import_picocolors2.default.dim(pluginResult.configPath)}`);
7285
- 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) {
7286
7437
  printStep(step++, totalSteps, "Adding auth plugins...");
7287
7438
  const authResult = await addAuthPlugins(config);
7288
7439
  if (!authResult.success) {
@@ -7308,10 +7459,16 @@ async function runNonTuiInstall(args) {
7308
7459
  }
7309
7460
  printSuccess(`Config written ${SYMBOLS.arrow} ${import_picocolors2.default.dim(omoResult.configPath)}`);
7310
7461
  printBox(formatConfigSummary(config), isUpdate ? "Updated Configuration" : "Installation Complete");
7311
- if (!config.hasClaude && !config.hasChatGPT && !config.hasGemini) {
7462
+ if (!config.hasProxyPal && !config.hasClaude && !config.hasChatGPT) {
7312
7463
  printWarning("No model providers configured. Using opencode/glm-4.7-free as fallback.");
7313
7464
  }
7314
- 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) {
7315
7472
  console.log(import_picocolors2.default.bold("Next Steps - Authenticate your providers:"));
7316
7473
  console.log();
7317
7474
  if (config.hasClaude) {
@@ -7320,9 +7477,6 @@ async function runNonTuiInstall(args) {
7320
7477
  if (config.hasChatGPT) {
7321
7478
  console.log(` ${SYMBOLS.arrow} ${import_picocolors2.default.dim("opencode auth login")} ${import_picocolors2.default.gray("(select OpenAI \u2192 ChatGPT Plus/Pro)")}`);
7322
7479
  }
7323
- if (config.hasGemini) {
7324
- console.log(` ${SYMBOLS.arrow} ${import_picocolors2.default.dim("opencode auth login")} ${import_picocolors2.default.gray("(select Google \u2192 OAuth with Antigravity)")}`);
7325
- }
7326
7480
  console.log();
7327
7481
  }
7328
7482
  console.log(`${SYMBOLS.star} ${import_picocolors2.default.bold(import_picocolors2.default.green(isUpdate ? "Configuration updated!" : "Installation complete!"))}`);
@@ -7347,7 +7501,11 @@ async function install(args) {
7347
7501
  Ie(import_picocolors2.default.bgMagenta(import_picocolors2.default.white(isUpdate ? " oMoMoMoMo... Update " : " oMoMoMoMo... ")));
7348
7502
  if (isUpdate) {
7349
7503
  const initial = detectedToInitialValues(detected);
7350
- 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
+ }
7351
7509
  }
7352
7510
  const s = Y2();
7353
7511
  s.start("Checking OpenCode installation");
@@ -7372,7 +7530,16 @@ async function install(args) {
7372
7530
  return 1;
7373
7531
  }
7374
7532
  s.stop(`Plugin added to ${import_picocolors2.default.cyan(pluginResult.configPath)}`);
7375
- 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) {
7376
7543
  s.start("Adding auth plugins (fetching latest versions)");
7377
7544
  const authResult = await addAuthPlugins(config);
7378
7545
  if (!authResult.success) {
@@ -7398,11 +7565,18 @@ async function install(args) {
7398
7565
  return 1;
7399
7566
  }
7400
7567
  s.stop(`Config written to ${import_picocolors2.default.cyan(omoResult.configPath)}`);
7401
- if (!config.hasClaude && !config.hasChatGPT && !config.hasGemini) {
7568
+ if (!config.hasProxyPal && !config.hasClaude && !config.hasChatGPT) {
7402
7569
  M2.warn("No model providers configured. Using opencode/glm-4.7-free as fallback.");
7403
7570
  }
7404
7571
  Me(formatConfigSummary(config), isUpdate ? "Updated Configuration" : "Installation Complete");
7405
- 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) {
7406
7580
  const steps = [];
7407
7581
  if (config.hasClaude) {
7408
7582
  steps.push(`${import_picocolors2.default.dim("opencode auth login")} ${import_picocolors2.default.gray("(select Anthropic \u2192 Claude Pro/Max)")}`);
@@ -7410,9 +7584,6 @@ async function install(args) {
7410
7584
  if (config.hasChatGPT) {
7411
7585
  steps.push(`${import_picocolors2.default.dim("opencode auth login")} ${import_picocolors2.default.gray("(select OpenAI \u2192 ChatGPT Plus/Pro)")}`);
7412
7586
  }
7413
- if (config.hasGemini) {
7414
- steps.push(`${import_picocolors2.default.dim("opencode auth login")} ${import_picocolors2.default.gray("(select Google \u2192 OAuth with Antigravity)")}`);
7415
- }
7416
7587
  Me(steps.join(`
7417
7588
  `), "Next Steps - Authenticate your providers");
7418
7589
  }
@@ -7660,7 +7831,7 @@ var serializeObjectParam = ({ allowReserved, explode, name, style, value, valueO
7660
7831
 
7661
7832
  // node_modules/@opencode-ai/sdk/dist/gen/core/utils.gen.js
7662
7833
  var PATH_PARAM_RE = /\{[^{}]+\}/g;
7663
- var defaultPathSerializer = ({ path: path3, url: _url }) => {
7834
+ var defaultPathSerializer = ({ path: path2, url: _url }) => {
7664
7835
  let url = _url;
7665
7836
  const matches = _url.match(PATH_PARAM_RE);
7666
7837
  if (matches) {
@@ -7679,7 +7850,7 @@ var defaultPathSerializer = ({ path: path3, url: _url }) => {
7679
7850
  name = name.substring(1);
7680
7851
  style = "matrix";
7681
7852
  }
7682
- const value = path3[name];
7853
+ const value = path2[name];
7683
7854
  if (value === undefined || value === null) {
7684
7855
  continue;
7685
7856
  }
@@ -7710,11 +7881,11 @@ var defaultPathSerializer = ({ path: path3, url: _url }) => {
7710
7881
  }
7711
7882
  return url;
7712
7883
  };
7713
- var getUrl = ({ baseUrl, path: path3, query, querySerializer, url: _url }) => {
7884
+ var getUrl = ({ baseUrl, path: path2, query, querySerializer, url: _url }) => {
7714
7885
  const pathUrl = _url.startsWith("/") ? _url : `/${_url}`;
7715
7886
  let url = (baseUrl ?? "") + pathUrl;
7716
- if (path3) {
7717
- url = defaultPathSerializer({ path: path3, url });
7887
+ if (path2) {
7888
+ url = defaultPathSerializer({ path: path2, url });
7718
7889
  }
7719
7890
  let search = query ? querySerializer(query) : "";
7720
7891
  if (search.startsWith("?")) {
@@ -9226,49 +9397,49 @@ All tasks completed.`));
9226
9397
  }
9227
9398
  // src/hooks/auto-update-checker/checker.ts
9228
9399
  import * as fs3 from "fs";
9229
- import * as path4 from "path";
9400
+ import * as path3 from "path";
9230
9401
  import { fileURLToPath } from "url";
9231
9402
 
9232
9403
  // src/hooks/auto-update-checker/constants.ts
9233
- import * as path3 from "path";
9234
- import * as os3 from "os";
9404
+ import * as path2 from "path";
9405
+ import * as os2 from "os";
9235
9406
  import * as fs2 from "fs";
9236
9407
  var PACKAGE_NAME = "oh-my-opencode";
9237
9408
  var NPM_REGISTRY_URL = `https://registry.npmjs.org/-/package/${PACKAGE_NAME}/dist-tags`;
9238
9409
  var NPM_FETCH_TIMEOUT = 5000;
9239
9410
  function getCacheDir() {
9240
9411
  if (process.platform === "win32") {
9241
- return path3.join(process.env.LOCALAPPDATA ?? os3.homedir(), "opencode");
9412
+ return path2.join(process.env.LOCALAPPDATA ?? os2.homedir(), "opencode");
9242
9413
  }
9243
- return path3.join(os3.homedir(), ".cache", "opencode");
9414
+ return path2.join(os2.homedir(), ".cache", "opencode");
9244
9415
  }
9245
9416
  var CACHE_DIR = getCacheDir();
9246
- var VERSION_FILE = path3.join(CACHE_DIR, "version");
9247
- 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");
9248
9419
  function getUserConfigDir() {
9249
9420
  if (process.platform === "win32") {
9250
- const crossPlatformDir = path3.join(os3.homedir(), ".config");
9251
- const appdataDir = process.env.APPDATA ?? path3.join(os3.homedir(), "AppData", "Roaming");
9252
- const crossPlatformConfig = path3.join(crossPlatformDir, "opencode", "opencode.json");
9253
- 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");
9254
9425
  if (fs2.existsSync(crossPlatformConfig) || fs2.existsSync(crossPlatformConfigJsonc)) {
9255
9426
  return crossPlatformDir;
9256
9427
  }
9257
9428
  return appdataDir;
9258
9429
  }
9259
- return process.env.XDG_CONFIG_HOME ?? path3.join(os3.homedir(), ".config");
9430
+ return process.env.XDG_CONFIG_HOME ?? path2.join(os2.homedir(), ".config");
9260
9431
  }
9261
9432
  function getWindowsAppdataDir() {
9262
9433
  if (process.platform !== "win32")
9263
9434
  return null;
9264
- return process.env.APPDATA ?? path3.join(os3.homedir(), "AppData", "Roaming");
9435
+ return process.env.APPDATA ?? path2.join(os2.homedir(), "AppData", "Roaming");
9265
9436
  }
9266
9437
  var USER_CONFIG_DIR = getUserConfigDir();
9267
- var USER_OPENCODE_CONFIG = path3.join(USER_CONFIG_DIR, "opencode", "opencode.json");
9268
- 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");
9269
9440
 
9270
9441
  // src/hooks/auto-update-checker/checker.ts
9271
- import * as os4 from "os";
9442
+ import * as os3 from "os";
9272
9443
  function isLocalDevMode(directory) {
9273
9444
  return getLocalDevPath(directory) !== null;
9274
9445
  }
@@ -9277,18 +9448,18 @@ function stripJsonComments(json2) {
9277
9448
  }
9278
9449
  function getConfigPaths(directory) {
9279
9450
  const paths = [
9280
- path4.join(directory, ".opencode", "opencode.json"),
9281
- path4.join(directory, ".opencode", "opencode.jsonc"),
9451
+ path3.join(directory, ".opencode", "opencode.json"),
9452
+ path3.join(directory, ".opencode", "opencode.jsonc"),
9282
9453
  USER_OPENCODE_CONFIG,
9283
9454
  USER_OPENCODE_CONFIG_JSONC
9284
9455
  ];
9285
9456
  if (process.platform === "win32") {
9286
- const crossPlatformDir = path4.join(os4.homedir(), ".config");
9457
+ const crossPlatformDir = path3.join(os3.homedir(), ".config");
9287
9458
  const appdataDir = getWindowsAppdataDir();
9288
9459
  if (appdataDir) {
9289
9460
  const alternateDir = USER_CONFIG_DIR === crossPlatformDir ? appdataDir : crossPlatformDir;
9290
- const alternateConfig = path4.join(alternateDir, "opencode", "opencode.json");
9291
- 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");
9292
9463
  if (!paths.includes(alternateConfig)) {
9293
9464
  paths.push(alternateConfig);
9294
9465
  }
@@ -9325,9 +9496,9 @@ function getLocalDevPath(directory) {
9325
9496
  function findPackageJsonUp(startPath) {
9326
9497
  try {
9327
9498
  const stat = fs3.statSync(startPath);
9328
- let dir = stat.isDirectory() ? startPath : path4.dirname(startPath);
9499
+ let dir = stat.isDirectory() ? startPath : path3.dirname(startPath);
9329
9500
  for (let i2 = 0;i2 < 10; i2++) {
9330
- const pkgPath = path4.join(dir, "package.json");
9501
+ const pkgPath = path3.join(dir, "package.json");
9331
9502
  if (fs3.existsSync(pkgPath)) {
9332
9503
  try {
9333
9504
  const content = fs3.readFileSync(pkgPath, "utf-8");
@@ -9336,7 +9507,7 @@ function findPackageJsonUp(startPath) {
9336
9507
  return pkgPath;
9337
9508
  } catch {}
9338
9509
  }
9339
- const parent = path4.dirname(dir);
9510
+ const parent = path3.dirname(dir);
9340
9511
  if (parent === dir)
9341
9512
  break;
9342
9513
  dir = parent;
@@ -9378,7 +9549,7 @@ function getCachedVersion() {
9378
9549
  }
9379
9550
  } catch {}
9380
9551
  try {
9381
- const currentDir = path4.dirname(fileURLToPath(import.meta.url));
9552
+ const currentDir = path3.dirname(fileURLToPath(import.meta.url));
9382
9553
  const pkgPath = findPackageJsonUp(currentDir);
9383
9554
  if (pkgPath) {
9384
9555
  const content = fs3.readFileSync(pkgPath, "utf-8");
@@ -9835,8 +10006,8 @@ function getPluginCheckDefinition() {
9835
10006
 
9836
10007
  // src/cli/doctor/checks/config.ts
9837
10008
  import { existsSync as existsSync7, readFileSync as readFileSync5 } from "fs";
9838
- import { homedir as homedir5 } from "os";
9839
- import { join as join6 } from "path";
10009
+ import { homedir as homedir4 } from "os";
10010
+ import { join as join5 } from "path";
9840
10011
 
9841
10012
  // node_modules/zod/v4/classic/external.js
9842
10013
  var exports_external = {};
@@ -10567,10 +10738,10 @@ function mergeDefs(...defs) {
10567
10738
  function cloneDef(schema2) {
10568
10739
  return mergeDefs(schema2._zod.def);
10569
10740
  }
10570
- function getElementAtPath(obj, path5) {
10571
- if (!path5)
10741
+ function getElementAtPath(obj, path4) {
10742
+ if (!path4)
10572
10743
  return obj;
10573
- return path5.reduce((acc, key) => acc?.[key], obj);
10744
+ return path4.reduce((acc, key) => acc?.[key], obj);
10574
10745
  }
10575
10746
  function promiseAllObject(promisesObj) {
10576
10747
  const keys = Object.keys(promisesObj);
@@ -10929,11 +11100,11 @@ function aborted(x2, startIndex = 0) {
10929
11100
  }
10930
11101
  return false;
10931
11102
  }
10932
- function prefixIssues(path5, issues) {
11103
+ function prefixIssues(path4, issues) {
10933
11104
  return issues.map((iss) => {
10934
11105
  var _a;
10935
11106
  (_a = iss).path ?? (_a.path = []);
10936
- iss.path.unshift(path5);
11107
+ iss.path.unshift(path4);
10937
11108
  return iss;
10938
11109
  });
10939
11110
  }
@@ -11101,7 +11272,7 @@ function treeifyError(error, _mapper) {
11101
11272
  return issue2.message;
11102
11273
  };
11103
11274
  const result = { errors: [] };
11104
- const processError = (error2, path5 = []) => {
11275
+ const processError = (error2, path4 = []) => {
11105
11276
  var _a, _b;
11106
11277
  for (const issue2 of error2.issues) {
11107
11278
  if (issue2.code === "invalid_union" && issue2.errors.length) {
@@ -11111,7 +11282,7 @@ function treeifyError(error, _mapper) {
11111
11282
  } else if (issue2.code === "invalid_element") {
11112
11283
  processError({ issues: issue2.issues }, issue2.path);
11113
11284
  } else {
11114
- const fullpath = [...path5, ...issue2.path];
11285
+ const fullpath = [...path4, ...issue2.path];
11115
11286
  if (fullpath.length === 0) {
11116
11287
  result.errors.push(mapper(issue2));
11117
11288
  continue;
@@ -11143,8 +11314,8 @@ function treeifyError(error, _mapper) {
11143
11314
  }
11144
11315
  function toDotPath(_path) {
11145
11316
  const segs = [];
11146
- const path5 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
11147
- for (const seg of path5) {
11317
+ const path4 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
11318
+ for (const seg of path4) {
11148
11319
  if (typeof seg === "number")
11149
11320
  segs.push(`[${seg}]`);
11150
11321
  else if (typeof seg === "symbol")
@@ -22234,7 +22405,9 @@ var HookNameSchema = exports_external.enum([
22234
22405
  "edit-error-recovery",
22235
22406
  "prometheus-md-only",
22236
22407
  "start-work",
22237
- "sisyphus-orchestrator"
22408
+ "sisyphus-orchestrator",
22409
+ "maestro-sisyphus-bridge",
22410
+ "tdd-enforcement"
22238
22411
  ]);
22239
22412
  var BuiltinCommandNameSchema = exports_external.enum([
22240
22413
  "init-deep",
@@ -22404,6 +22577,18 @@ var GitMasterConfigSchema = exports_external.object({
22404
22577
  commit_footer: exports_external.boolean().default(true),
22405
22578
  include_co_authored_by: exports_external.boolean().default(true)
22406
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
+ });
22407
22592
  var OhMyOpenCodeConfigSchema = exports_external.object({
22408
22593
  $schema: exports_external.string().optional(),
22409
22594
  disabled_mcps: exports_external.array(AnyMcpNameSchema).optional(),
@@ -22414,7 +22599,6 @@ var OhMyOpenCodeConfigSchema = exports_external.object({
22414
22599
  agents: AgentOverridesSchema.optional(),
22415
22600
  categories: CategoriesConfigSchema.optional(),
22416
22601
  claude_code: ClaudeCodeConfigSchema.optional(),
22417
- google_auth: exports_external.boolean().optional(),
22418
22602
  sisyphus_agent: SisyphusAgentConfigSchema.optional(),
22419
22603
  comment_checker: CommentCheckerConfigSchema.optional(),
22420
22604
  experimental: ExperimentalConfigSchema.optional(),
@@ -22423,12 +22607,13 @@ var OhMyOpenCodeConfigSchema = exports_external.object({
22423
22607
  ralph_loop: RalphLoopConfigSchema.optional(),
22424
22608
  background_task: BackgroundTaskConfigSchema.optional(),
22425
22609
  notification: NotificationConfigSchema.optional(),
22426
- git_master: GitMasterConfigSchema.optional()
22610
+ git_master: GitMasterConfigSchema.optional(),
22611
+ maestro: MaestroConfigSchema.optional()
22427
22612
  });
22428
22613
  // src/cli/doctor/checks/config.ts
22429
- var USER_CONFIG_DIR2 = join6(homedir5(), ".config", "opencode");
22430
- var USER_CONFIG_BASE = join6(USER_CONFIG_DIR2, `${PACKAGE_NAME2}`);
22431
- 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);
22432
22617
  function findConfigPath() {
22433
22618
  const projectDetected = detectConfigFile(PROJECT_CONFIG_BASE);
22434
22619
  if (projectDetected.format !== "none") {
@@ -22526,15 +22711,15 @@ function getConfigCheckDefinition() {
22526
22711
 
22527
22712
  // src/cli/doctor/checks/auth.ts
22528
22713
  import { existsSync as existsSync8, readFileSync as readFileSync6 } from "fs";
22529
- import { homedir as homedir6 } from "os";
22530
- import { join as join7 } from "path";
22531
- var OPENCODE_CONFIG_DIR = join7(homedir6(), ".config", "opencode");
22532
- var OPENCODE_JSON = join7(OPENCODE_CONFIG_DIR, "opencode.json");
22533
- 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");
22534
22719
  var AUTH_PLUGINS = {
22535
22720
  anthropic: { plugin: "builtin", name: "Anthropic (Claude)" },
22536
22721
  openai: { plugin: "opencode-openai-codex-auth", name: "OpenAI (ChatGPT)" },
22537
- google: { plugin: "opencode-antigravity-auth", name: "Google (Gemini)" }
22722
+ google: { plugin: "opencode-proxypal-auth", name: "Google (Gemini)" }
22538
22723
  };
22539
22724
  function getOpenCodeConfig() {
22540
22725
  const configPath = existsSync8(OPENCODE_JSONC) ? OPENCODE_JSONC : OPENCODE_JSON;
@@ -22971,13 +23156,13 @@ function getLspCheckDefinition() {
22971
23156
 
22972
23157
  // src/cli/doctor/checks/mcp.ts
22973
23158
  import { existsSync as existsSync9, readFileSync as readFileSync7 } from "fs";
22974
- import { homedir as homedir7 } from "os";
22975
- import { join as join8 } from "path";
23159
+ import { homedir as homedir6 } from "os";
23160
+ import { join as join7 } from "path";
22976
23161
  var BUILTIN_MCP_SERVERS = ["context7", "grep_app"];
22977
23162
  var MCP_CONFIG_PATHS = [
22978
- join8(homedir7(), ".claude", ".mcp.json"),
22979
- join8(process.cwd(), ".mcp.json"),
22980
- 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")
22981
23166
  ];
22982
23167
  function loadUserMcpConfig() {
22983
23168
  const servers = {};
@@ -23376,161 +23561,29 @@ async function doctor(options = {}) {
23376
23561
  return result.exitCode;
23377
23562
  }
23378
23563
 
23379
- // src/auth/antigravity/storage.ts
23380
- import { promises as fs4 } from "fs";
23381
- import { join as join9, dirname as dirname2 } from "path";
23382
- function getDataDir2() {
23383
- return join9(getDataDir(), "opencode");
23384
- }
23385
- function getStoragePath() {
23386
- return join9(getDataDir2(), "oh-my-opencode-accounts.json");
23387
- }
23388
- async function loadAccounts(path5) {
23389
- const storagePath = path5 ?? getStoragePath();
23390
- try {
23391
- const content = await fs4.readFile(storagePath, "utf-8");
23392
- const data = JSON.parse(content);
23393
- if (!isValidAccountStorage(data)) {
23394
- return null;
23395
- }
23396
- return data;
23397
- } catch (error45) {
23398
- const errorCode = error45.code;
23399
- if (errorCode === "ENOENT") {
23400
- return null;
23401
- }
23402
- if (error45 instanceof SyntaxError) {
23403
- return null;
23404
- }
23405
- throw error45;
23406
- }
23407
- }
23408
- async function saveAccounts(storage, path5) {
23409
- const storagePath = path5 ?? getStoragePath();
23410
- await fs4.mkdir(dirname2(storagePath), { recursive: true });
23411
- const content = JSON.stringify(storage, null, 2);
23412
- const tempPath = `${storagePath}.tmp.${process.pid}.${Date.now()}`;
23413
- await fs4.writeFile(tempPath, content, { encoding: "utf-8", mode: 384 });
23414
- try {
23415
- await fs4.rename(tempPath, storagePath);
23416
- } catch (error45) {
23417
- await fs4.unlink(tempPath).catch(() => {});
23418
- throw error45;
23419
- }
23420
- }
23421
- function isValidAccountStorage(data) {
23422
- if (typeof data !== "object" || data === null) {
23423
- return false;
23424
- }
23425
- const obj = data;
23426
- if (typeof obj.version !== "number") {
23427
- return false;
23428
- }
23429
- if (!Array.isArray(obj.accounts)) {
23430
- return false;
23431
- }
23432
- if (typeof obj.activeIndex !== "number") {
23433
- return false;
23434
- }
23435
- return true;
23436
- }
23437
-
23438
- // src/cli/commands/auth.ts
23439
- async function listAccounts() {
23440
- const accounts = await loadAccounts();
23441
- if (!accounts || accounts.accounts.length === 0) {
23442
- console.log("No accounts found.");
23443
- console.log("Run 'opencode auth login' and select Google (Antigravity) to add accounts.");
23444
- return 0;
23445
- }
23446
- console.log(`
23447
- Google Antigravity Accounts (${accounts.accounts.length}/10):
23448
- `);
23449
- for (let i2 = 0;i2 < accounts.accounts.length; i2++) {
23450
- const acc = accounts.accounts[i2];
23451
- const isActive = i2 === accounts.activeIndex;
23452
- const activeMarker = isActive ? "* " : " ";
23453
- console.log(`${activeMarker}[${i2}] ${acc.email || "Unknown"}`);
23454
- console.log(` Tier: ${acc.tier || "free"}`);
23455
- const rateLimits = acc.rateLimits || {};
23456
- const now = Date.now();
23457
- const limited = [];
23458
- if (rateLimits.claude && rateLimits.claude > now) {
23459
- const mins = Math.ceil((rateLimits.claude - now) / 60000);
23460
- limited.push(`claude (${mins}m)`);
23461
- }
23462
- if (rateLimits["gemini-flash"] && rateLimits["gemini-flash"] > now) {
23463
- const mins = Math.ceil((rateLimits["gemini-flash"] - now) / 60000);
23464
- limited.push(`gemini-flash (${mins}m)`);
23465
- }
23466
- if (rateLimits["gemini-pro"] && rateLimits["gemini-pro"] > now) {
23467
- const mins = Math.ceil((rateLimits["gemini-pro"] - now) / 60000);
23468
- limited.push(`gemini-pro (${mins}m)`);
23469
- }
23470
- if (limited.length > 0) {
23471
- console.log(` Rate limited: ${limited.join(", ")}`);
23472
- }
23473
- console.log();
23474
- }
23475
- return 0;
23476
- }
23477
- async function removeAccount(indexOrEmail) {
23478
- const accounts = await loadAccounts();
23479
- if (!accounts || accounts.accounts.length === 0) {
23480
- console.error("No accounts found.");
23481
- return 1;
23482
- }
23483
- let index;
23484
- const parsedIndex = Number(indexOrEmail);
23485
- if (Number.isInteger(parsedIndex) && String(parsedIndex) === indexOrEmail) {
23486
- index = parsedIndex;
23487
- } else {
23488
- index = accounts.accounts.findIndex((acc) => acc.email === indexOrEmail);
23489
- if (index === -1) {
23490
- console.error(`Account not found: ${indexOrEmail}`);
23491
- return 1;
23492
- }
23493
- }
23494
- if (index < 0 || index >= accounts.accounts.length) {
23495
- console.error(`Invalid index: ${index}. Valid range: 0-${accounts.accounts.length - 1}`);
23496
- return 1;
23497
- }
23498
- const removed = accounts.accounts[index];
23499
- accounts.accounts.splice(index, 1);
23500
- if (accounts.accounts.length === 0) {
23501
- accounts.activeIndex = -1;
23502
- } else if (accounts.activeIndex >= accounts.accounts.length) {
23503
- accounts.activeIndex = accounts.accounts.length - 1;
23504
- } else if (accounts.activeIndex > index) {
23505
- accounts.activeIndex--;
23506
- }
23507
- await saveAccounts(accounts);
23508
- console.log(`Removed account: ${removed.email || "Unknown"} (index ${index})`);
23509
- console.log(`Remaining accounts: ${accounts.accounts.length}`);
23510
- return 0;
23511
- }
23512
-
23513
23564
  // src/cli/index.ts
23514
23565
  var packageJson = await Promise.resolve().then(() => __toESM(require_package(), 1));
23515
23566
  var VERSION = packageJson.version;
23516
23567
  var program2 = new Command;
23517
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");
23518
- 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", `
23519
23570
  Examples:
23520
23571
  $ bunx oh-my-opencode install
23521
- $ bunx oh-my-opencode install --no-tui --claude=max20 --chatgpt=yes --gemini=yes
23522
- $ 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
23523
23575
 
23524
23576
  Model Providers:
23577
+ ProxyPal Use ProxyPal proxy for all models (github.com/heyhuynhgiabuu/proxypal)
23525
23578
  Claude Required for Sisyphus (main orchestrator) and Librarian agents
23526
23579
  ChatGPT Powers the Oracle agent for debugging and architecture
23527
23580
  Gemini Powers frontend, documentation, and multimodal agents
23528
23581
  `).action(async (options) => {
23529
23582
  const args = {
23530
23583
  tui: options.tui !== false,
23584
+ proxypal: options.proxypal,
23531
23585
  claude: options.claude,
23532
23586
  chatgpt: options.chatgpt,
23533
- gemini: options.gemini,
23534
23587
  skipAuth: options.skipAuth ?? false
23535
23588
  };
23536
23589
  const exitCode = await install(args);
@@ -23597,32 +23650,6 @@ Categories:
23597
23650
  const exitCode = await doctor(doctorOptions);
23598
23651
  process.exit(exitCode);
23599
23652
  });
23600
- var authCommand = program2.command("auth").description("Manage Google Antigravity accounts");
23601
- authCommand.command("list").description("List all Google Antigravity accounts").addHelpText("after", `
23602
- Examples:
23603
- $ bunx oh-my-opencode auth list
23604
-
23605
- Shows:
23606
- - Account index and email
23607
- - Account tier (free/paid)
23608
- - Active account (marked with *)
23609
- - Rate limit status per model family
23610
- `).action(async () => {
23611
- const exitCode = await listAccounts();
23612
- process.exit(exitCode);
23613
- });
23614
- authCommand.command("remove <index-or-email>").description("Remove an account by index or email").addHelpText("after", `
23615
- Examples:
23616
- $ bunx oh-my-opencode auth remove 0
23617
- $ bunx oh-my-opencode auth remove user@example.com
23618
-
23619
- Note:
23620
- - Use 'auth list' to see account indices
23621
- - Removing the active account will switch to the next available account
23622
- `).action(async (indexOrEmail) => {
23623
- const exitCode = await removeAccount(indexOrEmail);
23624
- process.exit(exitCode);
23625
- });
23626
23653
  program2.command("version").description("Show version information").action(() => {
23627
23654
  console.log(`oh-my-opencode v${VERSION}`);
23628
23655
  });