oh-my-opencode 3.0.0-beta.9 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ja.md +52 -804
- package/README.ko.md +377 -0
- package/README.md +61 -933
- package/README.zh-cn.md +53 -928
- package/dist/agents/atlas.d.ts +19 -0
- package/dist/agents/{sisyphus-prompt-builder.d.ts → dynamic-agent-prompt-builder.d.ts} +10 -6
- package/dist/agents/explore.d.ts +1 -2
- package/dist/agents/index.d.ts +9 -3
- package/dist/agents/librarian.d.ts +1 -2
- package/dist/agents/metis.d.ts +1 -2
- package/dist/agents/momus.d.ts +15 -3
- package/dist/agents/multimodal-looker.d.ts +1 -2
- package/dist/agents/oracle.d.ts +1 -2
- package/dist/agents/prometheus-prompt.d.ts +1 -1
- package/dist/agents/sisyphus-junior.d.ts +1 -2
- package/dist/agents/sisyphus.d.ts +2 -3
- package/dist/agents/types.d.ts +2 -2
- package/dist/agents/utils.d.ts +4 -3
- package/dist/cli/config-manager.d.ts +77 -14
- package/dist/cli/doctor/checks/dependencies.d.ts +1 -1
- package/dist/cli/doctor/checks/index.d.ts +1 -0
- package/dist/cli/doctor/checks/model-resolution.d.ts +33 -0
- package/dist/cli/doctor/constants.d.ts +1 -0
- package/dist/cli/index.js +922 -418
- package/dist/cli/install.test.d.ts +1 -0
- package/dist/cli/model-fallback.d.ts +18 -0
- package/dist/cli/model-fallback.test.d.ts +1 -0
- package/dist/cli/types.d.ts +9 -3
- package/dist/config/schema.d.ts +50 -246
- package/dist/features/background-agent/manager.d.ts +10 -0
- package/dist/features/background-agent/types.d.ts +4 -3
- package/dist/features/builtin-commands/templates/init-deep.d.ts +1 -1
- package/dist/features/builtin-commands/templates/ralph-loop.d.ts +1 -1
- package/dist/features/builtin-commands/templates/start-work.d.ts +1 -1
- package/dist/features/builtin-commands/types.d.ts +1 -1
- package/dist/features/skill-mcp-manager/manager.d.ts +1 -0
- package/dist/features/task-toast-manager/manager.d.ts +1 -0
- package/dist/features/task-toast-manager/types.d.ts +3 -0
- package/dist/hooks/{sisyphus-orchestrator → atlas}/index.d.ts +3 -3
- package/dist/hooks/atlas/index.test.d.ts +1 -0
- package/dist/hooks/auto-update-checker/constants.d.ts +0 -3
- package/dist/hooks/index.d.ts +2 -2
- package/dist/hooks/prometheus-md-only/constants.d.ts +1 -0
- package/dist/hooks/question-label-truncator/index.d.ts +7 -0
- package/dist/hooks/question-label-truncator/index.test.d.ts +1 -0
- package/dist/hooks/ralph-loop/index.d.ts +1 -0
- package/dist/hooks/ralph-loop/types.d.ts +1 -0
- package/dist/index.js +12810 -13083
- package/dist/index.test.d.ts +1 -0
- package/dist/mcp/context7.d.ts +1 -0
- package/dist/mcp/grep-app.d.ts +1 -0
- package/dist/mcp/index.d.ts +1 -0
- package/dist/mcp/websearch.d.ts +1 -0
- package/dist/plugin-handlers/config-handler.d.ts +1 -0
- package/dist/shared/agent-config-integration.test.d.ts +1 -0
- package/dist/shared/agent-display-names.d.ts +12 -0
- package/dist/shared/agent-display-names.test.d.ts +1 -0
- package/dist/shared/case-insensitive.d.ts +24 -0
- package/dist/shared/case-insensitive.test.d.ts +1 -0
- package/dist/shared/index.d.ts +4 -1
- package/dist/shared/migration.d.ts +15 -1
- package/dist/shared/model-availability.d.ts +8 -0
- package/dist/shared/model-availability.test.d.ts +1 -0
- package/dist/shared/model-requirements.d.ts +11 -0
- package/dist/shared/model-requirements.test.d.ts +1 -0
- package/dist/shared/model-resolver.d.ts +20 -0
- package/dist/shared/model-resolver.test.d.ts +1 -0
- package/dist/tools/call-omo-agent/constants.d.ts +1 -1
- package/dist/tools/delegate-task/constants.d.ts +3 -4
- package/dist/tools/delegate-task/tools.d.ts +11 -1
- package/dist/tools/delegate-task/types.d.ts +3 -2
- package/dist/tools/index.d.ts +1 -2
- package/dist/tools/skill/types.d.ts +1 -1
- package/package.json +8 -12
- package/dist/agents/build-prompt.d.ts +0 -31
- package/dist/agents/document-writer.d.ts +0 -5
- package/dist/agents/frontend-ui-ux-engineer.d.ts +0 -5
- package/dist/agents/orchestrator-sisyphus.d.ts +0 -20
- package/dist/agents/plan-prompt.d.ts +0 -64
- package/dist/hooks/anthropic-context-window-limit-recovery/pruning-executor.d.ts +0 -3
- package/dist/hooks/anthropic-context-window-limit-recovery/pruning-purge-errors.d.ts +0 -7
- package/dist/hooks/anthropic-context-window-limit-recovery/pruning-storage.d.ts +0 -2
- package/dist/hooks/anthropic-context-window-limit-recovery/pruning-supersede.d.ts +0 -6
- package/dist/hooks/background-compaction/index.d.ts +0 -19
- package/dist/hooks/comment-checker/constants.d.ts +0 -3
- package/dist/hooks/comment-checker/filters/bdd.d.ts +0 -2
- package/dist/hooks/comment-checker/filters/directive.d.ts +0 -2
- package/dist/hooks/comment-checker/filters/docstring.d.ts +0 -2
- package/dist/hooks/comment-checker/filters/index.d.ts +0 -7
- package/dist/hooks/comment-checker/filters/shebang.d.ts +0 -2
- package/dist/hooks/comment-checker/output/formatter.d.ts +0 -2
- package/dist/hooks/comment-checker/output/index.d.ts +0 -2
- package/dist/hooks/comment-checker/output/xml-builder.d.ts +0 -2
- package/dist/shared/config-path.d.ts +0 -17
- package/dist/tools/ast-grep/napi.d.ts +0 -13
- package/dist/tools/interactive-bash/types.d.ts +0 -3
- /package/dist/{hooks/sisyphus-orchestrator/index.test.d.ts → cli/doctor/checks/model-resolution.test.d.ts} +0 -0
package/dist/cli/index.js
CHANGED
|
@@ -4913,10 +4913,12 @@ var init_dynamic_truncator = __esm(() => {
|
|
|
4913
4913
|
ANTHROPIC_ACTUAL_LIMIT = process.env.ANTHROPIC_1M_CONTEXT === "true" || process.env.VERTEX_ANTHROPIC_1M_CONTEXT === "true" ? 1e6 : 200000;
|
|
4914
4914
|
});
|
|
4915
4915
|
|
|
4916
|
-
// src/shared/config-path.ts
|
|
4917
|
-
var init_config_path = () => {};
|
|
4918
|
-
|
|
4919
4916
|
// src/shared/data-path.ts
|
|
4917
|
+
import * as path2 from "path";
|
|
4918
|
+
import * as os2 from "os";
|
|
4919
|
+
function getDataDir() {
|
|
4920
|
+
return process.env.XDG_DATA_HOME ?? path2.join(os2.homedir(), ".local", "share");
|
|
4921
|
+
}
|
|
4920
4922
|
var init_data_path = () => {};
|
|
4921
4923
|
|
|
4922
4924
|
// src/shared/config-errors.ts
|
|
@@ -5832,25 +5834,23 @@ var BUILTIN_AGENT_NAMES;
|
|
|
5832
5834
|
var init_migration = __esm(() => {
|
|
5833
5835
|
init_logger();
|
|
5834
5836
|
BUILTIN_AGENT_NAMES = new Set([
|
|
5835
|
-
"
|
|
5837
|
+
"sisyphus",
|
|
5836
5838
|
"oracle",
|
|
5837
5839
|
"librarian",
|
|
5838
5840
|
"explore",
|
|
5839
|
-
"frontend-ui-ux-engineer",
|
|
5840
|
-
"document-writer",
|
|
5841
5841
|
"multimodal-looker",
|
|
5842
|
-
"
|
|
5843
|
-
"
|
|
5844
|
-
"
|
|
5845
|
-
"
|
|
5842
|
+
"metis",
|
|
5843
|
+
"momus",
|
|
5844
|
+
"prometheus",
|
|
5845
|
+
"atlas",
|
|
5846
5846
|
"build"
|
|
5847
5847
|
]);
|
|
5848
5848
|
});
|
|
5849
5849
|
|
|
5850
5850
|
// src/shared/opencode-config-dir.ts
|
|
5851
5851
|
import { existsSync as existsSync2 } from "fs";
|
|
5852
|
-
import { homedir } from "os";
|
|
5853
|
-
import { join as
|
|
5852
|
+
import { homedir as homedir2 } from "os";
|
|
5853
|
+
import { join as join3, resolve } from "path";
|
|
5854
5854
|
function isDevBuild(version) {
|
|
5855
5855
|
if (!version)
|
|
5856
5856
|
return false;
|
|
@@ -5860,15 +5860,15 @@ function getTauriConfigDir(identifier) {
|
|
|
5860
5860
|
const platform = process.platform;
|
|
5861
5861
|
switch (platform) {
|
|
5862
5862
|
case "darwin":
|
|
5863
|
-
return
|
|
5863
|
+
return join3(homedir2(), "Library", "Application Support", identifier);
|
|
5864
5864
|
case "win32": {
|
|
5865
|
-
const appData = process.env.APPDATA ||
|
|
5866
|
-
return
|
|
5865
|
+
const appData = process.env.APPDATA || join3(homedir2(), "AppData", "Roaming");
|
|
5866
|
+
return join3(appData, identifier);
|
|
5867
5867
|
}
|
|
5868
5868
|
case "linux":
|
|
5869
5869
|
default: {
|
|
5870
|
-
const xdgConfig = process.env.XDG_CONFIG_HOME ||
|
|
5871
|
-
return
|
|
5870
|
+
const xdgConfig = process.env.XDG_CONFIG_HOME || join3(homedir2(), ".config");
|
|
5871
|
+
return join3(xdgConfig, identifier);
|
|
5872
5872
|
}
|
|
5873
5873
|
}
|
|
5874
5874
|
}
|
|
@@ -5878,21 +5878,21 @@ function getCliConfigDir() {
|
|
|
5878
5878
|
return resolve(envConfigDir);
|
|
5879
5879
|
}
|
|
5880
5880
|
if (process.platform === "win32") {
|
|
5881
|
-
const crossPlatformDir =
|
|
5882
|
-
const crossPlatformConfig =
|
|
5881
|
+
const crossPlatformDir = join3(homedir2(), ".config", "opencode");
|
|
5882
|
+
const crossPlatformConfig = join3(crossPlatformDir, "opencode.json");
|
|
5883
5883
|
if (existsSync2(crossPlatformConfig)) {
|
|
5884
5884
|
return crossPlatformDir;
|
|
5885
5885
|
}
|
|
5886
|
-
const appData = process.env.APPDATA ||
|
|
5887
|
-
const appdataDir =
|
|
5888
|
-
const appdataConfig =
|
|
5886
|
+
const appData = process.env.APPDATA || join3(homedir2(), "AppData", "Roaming");
|
|
5887
|
+
const appdataDir = join3(appData, "opencode");
|
|
5888
|
+
const appdataConfig = join3(appdataDir, "opencode.json");
|
|
5889
5889
|
if (existsSync2(appdataConfig)) {
|
|
5890
5890
|
return appdataDir;
|
|
5891
5891
|
}
|
|
5892
5892
|
return crossPlatformDir;
|
|
5893
5893
|
}
|
|
5894
|
-
const xdgConfig = process.env.XDG_CONFIG_HOME ||
|
|
5895
|
-
return
|
|
5894
|
+
const xdgConfig = process.env.XDG_CONFIG_HOME || join3(homedir2(), ".config");
|
|
5895
|
+
return join3(xdgConfig, "opencode");
|
|
5896
5896
|
}
|
|
5897
5897
|
function getOpenCodeConfigDir(options) {
|
|
5898
5898
|
const { binary: binary2, version, checkExisting = true } = options;
|
|
@@ -5903,8 +5903,8 @@ function getOpenCodeConfigDir(options) {
|
|
|
5903
5903
|
const tauriDir = getTauriConfigDir(identifier);
|
|
5904
5904
|
if (checkExisting) {
|
|
5905
5905
|
const legacyDir = getCliConfigDir();
|
|
5906
|
-
const legacyConfig =
|
|
5907
|
-
const legacyConfigC =
|
|
5906
|
+
const legacyConfig = join3(legacyDir, "opencode.json");
|
|
5907
|
+
const legacyConfigC = join3(legacyDir, "opencode.jsonc");
|
|
5908
5908
|
if (existsSync2(legacyConfig) || existsSync2(legacyConfigC)) {
|
|
5909
5909
|
return legacyDir;
|
|
5910
5910
|
}
|
|
@@ -5915,10 +5915,10 @@ function getOpenCodeConfigPaths(options) {
|
|
|
5915
5915
|
const configDir = getOpenCodeConfigDir(options);
|
|
5916
5916
|
return {
|
|
5917
5917
|
configDir,
|
|
5918
|
-
configJson:
|
|
5919
|
-
configJsonc:
|
|
5920
|
-
packageJson:
|
|
5921
|
-
omoConfig:
|
|
5918
|
+
configJson: join3(configDir, "opencode.json"),
|
|
5919
|
+
configJsonc: join3(configDir, "opencode.jsonc"),
|
|
5920
|
+
packageJson: join3(configDir, "package.json"),
|
|
5921
|
+
omoConfig: join3(configDir, "oh-my-opencode.json")
|
|
5922
5922
|
};
|
|
5923
5923
|
}
|
|
5924
5924
|
var TAURI_APP_IDENTIFIER = "ai.opencode.desktop", TAURI_APP_IDENTIFIER_DEV = "ai.opencode.desktop.dev";
|
|
@@ -5937,6 +5937,9 @@ var init_external_plugin_detector = __esm(() => {
|
|
|
5937
5937
|
|
|
5938
5938
|
// src/shared/zip-extractor.ts
|
|
5939
5939
|
var init_zip_extractor = () => {};
|
|
5940
|
+
// src/shared/agent-variant.ts
|
|
5941
|
+
var init_agent_variant = () => {};
|
|
5942
|
+
|
|
5940
5943
|
// src/shared/session-cursor.ts
|
|
5941
5944
|
var sessionCursors;
|
|
5942
5945
|
var init_session_cursor = __esm(() => {
|
|
@@ -5948,6 +5951,154 @@ var init_system_directive = () => {};
|
|
|
5948
5951
|
// src/shared/agent-tool-restrictions.ts
|
|
5949
5952
|
var init_agent_tool_restrictions = () => {};
|
|
5950
5953
|
|
|
5954
|
+
// src/shared/model-requirements.ts
|
|
5955
|
+
var AGENT_MODEL_REQUIREMENTS, CATEGORY_MODEL_REQUIREMENTS;
|
|
5956
|
+
var init_model_requirements = __esm(() => {
|
|
5957
|
+
AGENT_MODEL_REQUIREMENTS = {
|
|
5958
|
+
sisyphus: {
|
|
5959
|
+
fallbackChain: [
|
|
5960
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" },
|
|
5961
|
+
{ providers: ["zai-coding-plan"], model: "glm-4.7" },
|
|
5962
|
+
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2-codex", variant: "medium" },
|
|
5963
|
+
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro" }
|
|
5964
|
+
]
|
|
5965
|
+
},
|
|
5966
|
+
oracle: {
|
|
5967
|
+
fallbackChain: [
|
|
5968
|
+
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2", variant: "high" },
|
|
5969
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" },
|
|
5970
|
+
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro" }
|
|
5971
|
+
]
|
|
5972
|
+
},
|
|
5973
|
+
librarian: {
|
|
5974
|
+
fallbackChain: [
|
|
5975
|
+
{ providers: ["zai-coding-plan"], model: "glm-4.7" },
|
|
5976
|
+
{ providers: ["opencode"], model: "big-pickle" },
|
|
5977
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-sonnet-4-5" }
|
|
5978
|
+
]
|
|
5979
|
+
},
|
|
5980
|
+
explore: {
|
|
5981
|
+
fallbackChain: [
|
|
5982
|
+
{ providers: ["anthropic", "opencode"], model: "claude-haiku-4-5" },
|
|
5983
|
+
{ providers: ["opencode"], model: "gpt-5-nano" }
|
|
5984
|
+
]
|
|
5985
|
+
},
|
|
5986
|
+
"multimodal-looker": {
|
|
5987
|
+
fallbackChain: [
|
|
5988
|
+
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-flash" },
|
|
5989
|
+
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2" },
|
|
5990
|
+
{ providers: ["zai-coding-plan"], model: "glm-4.6v" },
|
|
5991
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-haiku-4-5" },
|
|
5992
|
+
{ providers: ["opencode"], model: "gpt-5-nano" }
|
|
5993
|
+
]
|
|
5994
|
+
},
|
|
5995
|
+
prometheus: {
|
|
5996
|
+
fallbackChain: [
|
|
5997
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" },
|
|
5998
|
+
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2", variant: "high" },
|
|
5999
|
+
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro" }
|
|
6000
|
+
]
|
|
6001
|
+
},
|
|
6002
|
+
metis: {
|
|
6003
|
+
fallbackChain: [
|
|
6004
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" },
|
|
6005
|
+
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2", variant: "high" },
|
|
6006
|
+
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro", variant: "max" }
|
|
6007
|
+
]
|
|
6008
|
+
},
|
|
6009
|
+
momus: {
|
|
6010
|
+
fallbackChain: [
|
|
6011
|
+
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2", variant: "medium" },
|
|
6012
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5" },
|
|
6013
|
+
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro", variant: "max" }
|
|
6014
|
+
]
|
|
6015
|
+
},
|
|
6016
|
+
atlas: {
|
|
6017
|
+
fallbackChain: [
|
|
6018
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-sonnet-4-5" },
|
|
6019
|
+
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2" },
|
|
6020
|
+
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro" }
|
|
6021
|
+
]
|
|
6022
|
+
}
|
|
6023
|
+
};
|
|
6024
|
+
CATEGORY_MODEL_REQUIREMENTS = {
|
|
6025
|
+
"visual-engineering": {
|
|
6026
|
+
fallbackChain: [
|
|
6027
|
+
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro" },
|
|
6028
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" },
|
|
6029
|
+
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2", variant: "high" }
|
|
6030
|
+
]
|
|
6031
|
+
},
|
|
6032
|
+
ultrabrain: {
|
|
6033
|
+
fallbackChain: [
|
|
6034
|
+
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2-codex", variant: "xhigh" },
|
|
6035
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" },
|
|
6036
|
+
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro" }
|
|
6037
|
+
]
|
|
6038
|
+
},
|
|
6039
|
+
artistry: {
|
|
6040
|
+
fallbackChain: [
|
|
6041
|
+
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro", variant: "max" },
|
|
6042
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" },
|
|
6043
|
+
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2" }
|
|
6044
|
+
]
|
|
6045
|
+
},
|
|
6046
|
+
quick: {
|
|
6047
|
+
fallbackChain: [
|
|
6048
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-haiku-4-5" },
|
|
6049
|
+
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-flash" },
|
|
6050
|
+
{ providers: ["opencode"], model: "gpt-5-nano" }
|
|
6051
|
+
]
|
|
6052
|
+
},
|
|
6053
|
+
"unspecified-low": {
|
|
6054
|
+
fallbackChain: [
|
|
6055
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-sonnet-4-5" },
|
|
6056
|
+
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2-codex", variant: "medium" },
|
|
6057
|
+
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-flash" }
|
|
6058
|
+
]
|
|
6059
|
+
},
|
|
6060
|
+
"unspecified-high": {
|
|
6061
|
+
fallbackChain: [
|
|
6062
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" },
|
|
6063
|
+
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2", variant: "high" },
|
|
6064
|
+
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro" }
|
|
6065
|
+
]
|
|
6066
|
+
},
|
|
6067
|
+
writing: {
|
|
6068
|
+
fallbackChain: [
|
|
6069
|
+
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-flash" },
|
|
6070
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-sonnet-4-5" },
|
|
6071
|
+
{ providers: ["zai-coding-plan"], model: "glm-4.7" },
|
|
6072
|
+
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2" }
|
|
6073
|
+
]
|
|
6074
|
+
}
|
|
6075
|
+
};
|
|
6076
|
+
});
|
|
6077
|
+
|
|
6078
|
+
// src/shared/model-availability.ts
|
|
6079
|
+
import { existsSync as existsSync3, readFileSync as readFileSync2 } from "fs";
|
|
6080
|
+
import { homedir as homedir3 } from "os";
|
|
6081
|
+
import { join as join4 } from "path";
|
|
6082
|
+
function getOpenCodeCacheDir() {
|
|
6083
|
+
const xdgCache = process.env.XDG_CACHE_HOME;
|
|
6084
|
+
if (xdgCache)
|
|
6085
|
+
return join4(xdgCache, "opencode");
|
|
6086
|
+
return join4(homedir3(), ".cache", "opencode");
|
|
6087
|
+
}
|
|
6088
|
+
function isModelCacheAvailable() {
|
|
6089
|
+
const cacheFile = join4(getOpenCodeCacheDir(), "models.json");
|
|
6090
|
+
return existsSync3(cacheFile);
|
|
6091
|
+
}
|
|
6092
|
+
var init_model_availability = __esm(() => {
|
|
6093
|
+
init_logger();
|
|
6094
|
+
});
|
|
6095
|
+
|
|
6096
|
+
// src/shared/model-resolver.ts
|
|
6097
|
+
var init_model_resolver = __esm(() => {
|
|
6098
|
+
init_logger();
|
|
6099
|
+
init_model_availability();
|
|
6100
|
+
});
|
|
6101
|
+
|
|
5951
6102
|
// src/shared/index.ts
|
|
5952
6103
|
var init_shared = __esm(() => {
|
|
5953
6104
|
init_frontmatter();
|
|
@@ -5959,7 +6110,6 @@ var init_shared = __esm(() => {
|
|
|
5959
6110
|
init_deep_merge();
|
|
5960
6111
|
init_file_utils();
|
|
5961
6112
|
init_dynamic_truncator();
|
|
5962
|
-
init_config_path();
|
|
5963
6113
|
init_data_path();
|
|
5964
6114
|
init_config_errors();
|
|
5965
6115
|
init_claude_config_dir();
|
|
@@ -5969,13 +6119,129 @@ var init_shared = __esm(() => {
|
|
|
5969
6119
|
init_opencode_version();
|
|
5970
6120
|
init_external_plugin_detector();
|
|
5971
6121
|
init_zip_extractor();
|
|
6122
|
+
init_agent_variant();
|
|
5972
6123
|
init_session_cursor();
|
|
5973
6124
|
init_system_directive();
|
|
5974
6125
|
init_agent_tool_restrictions();
|
|
6126
|
+
init_model_requirements();
|
|
6127
|
+
init_model_resolver();
|
|
6128
|
+
init_model_availability();
|
|
6129
|
+
});
|
|
6130
|
+
|
|
6131
|
+
// src/cli/model-fallback.ts
|
|
6132
|
+
function toProviderAvailability(config) {
|
|
6133
|
+
return {
|
|
6134
|
+
native: {
|
|
6135
|
+
claude: config.hasClaude,
|
|
6136
|
+
openai: config.hasOpenAI,
|
|
6137
|
+
gemini: config.hasGemini
|
|
6138
|
+
},
|
|
6139
|
+
opencodeZen: config.hasOpencodeZen,
|
|
6140
|
+
copilot: config.hasCopilot,
|
|
6141
|
+
zai: config.hasZaiCodingPlan,
|
|
6142
|
+
isMaxPlan: config.isMax20
|
|
6143
|
+
};
|
|
6144
|
+
}
|
|
6145
|
+
function isProviderAvailable(provider, avail) {
|
|
6146
|
+
const mapping = {
|
|
6147
|
+
anthropic: avail.native.claude,
|
|
6148
|
+
openai: avail.native.openai,
|
|
6149
|
+
google: avail.native.gemini,
|
|
6150
|
+
"github-copilot": avail.copilot,
|
|
6151
|
+
opencode: avail.opencodeZen,
|
|
6152
|
+
"zai-coding-plan": avail.zai
|
|
6153
|
+
};
|
|
6154
|
+
return mapping[provider] ?? false;
|
|
6155
|
+
}
|
|
6156
|
+
function transformModelForProvider(provider, model) {
|
|
6157
|
+
if (provider === "github-copilot") {
|
|
6158
|
+
return model.replace("claude-opus-4-5", "claude-opus-4.5").replace("claude-sonnet-4-5", "claude-sonnet-4.5").replace("claude-haiku-4-5", "claude-haiku-4.5").replace("claude-sonnet-4", "claude-sonnet-4");
|
|
6159
|
+
}
|
|
6160
|
+
return model;
|
|
6161
|
+
}
|
|
6162
|
+
function resolveModelFromChain(fallbackChain, avail) {
|
|
6163
|
+
for (const entry of fallbackChain) {
|
|
6164
|
+
for (const provider of entry.providers) {
|
|
6165
|
+
if (isProviderAvailable(provider, avail)) {
|
|
6166
|
+
const transformedModel = transformModelForProvider(provider, entry.model);
|
|
6167
|
+
return {
|
|
6168
|
+
model: `${provider}/${transformedModel}`,
|
|
6169
|
+
variant: entry.variant
|
|
6170
|
+
};
|
|
6171
|
+
}
|
|
6172
|
+
}
|
|
6173
|
+
}
|
|
6174
|
+
return null;
|
|
6175
|
+
}
|
|
6176
|
+
function getSisyphusFallbackChain(isMaxPlan) {
|
|
6177
|
+
if (isMaxPlan) {
|
|
6178
|
+
return AGENT_MODEL_REQUIREMENTS.sisyphus.fallbackChain;
|
|
6179
|
+
}
|
|
6180
|
+
return [
|
|
6181
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-sonnet-4-5" },
|
|
6182
|
+
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2", variant: "high" },
|
|
6183
|
+
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro" }
|
|
6184
|
+
];
|
|
6185
|
+
}
|
|
6186
|
+
function generateModelConfig(config) {
|
|
6187
|
+
const avail = toProviderAvailability(config);
|
|
6188
|
+
const hasAnyProvider = avail.native.claude || avail.native.openai || avail.native.gemini || avail.opencodeZen || avail.copilot || avail.zai;
|
|
6189
|
+
if (!hasAnyProvider) {
|
|
6190
|
+
return {
|
|
6191
|
+
$schema: SCHEMA_URL,
|
|
6192
|
+
agents: Object.fromEntries(Object.keys(AGENT_MODEL_REQUIREMENTS).map((role) => [role, { model: ULTIMATE_FALLBACK }])),
|
|
6193
|
+
categories: Object.fromEntries(Object.keys(CATEGORY_MODEL_REQUIREMENTS).map((cat) => [cat, { model: ULTIMATE_FALLBACK }]))
|
|
6194
|
+
};
|
|
6195
|
+
}
|
|
6196
|
+
const agents = {};
|
|
6197
|
+
const categories = {};
|
|
6198
|
+
for (const [role, req] of Object.entries(AGENT_MODEL_REQUIREMENTS)) {
|
|
6199
|
+
if (role === "librarian" && avail.zai) {
|
|
6200
|
+
agents[role] = { model: ZAI_MODEL };
|
|
6201
|
+
continue;
|
|
6202
|
+
}
|
|
6203
|
+
if (role === "explore") {
|
|
6204
|
+
if (avail.native.claude) {
|
|
6205
|
+
agents[role] = { model: "anthropic/claude-haiku-4-5" };
|
|
6206
|
+
} else if (avail.opencodeZen) {
|
|
6207
|
+
agents[role] = { model: "opencode/claude-haiku-4-5" };
|
|
6208
|
+
} else {
|
|
6209
|
+
agents[role] = { model: "opencode/gpt-5-nano" };
|
|
6210
|
+
}
|
|
6211
|
+
continue;
|
|
6212
|
+
}
|
|
6213
|
+
const fallbackChain = role === "sisyphus" ? getSisyphusFallbackChain(avail.isMaxPlan) : req.fallbackChain;
|
|
6214
|
+
const resolved = resolveModelFromChain(fallbackChain, avail);
|
|
6215
|
+
if (resolved) {
|
|
6216
|
+
const variant = resolved.variant ?? req.variant;
|
|
6217
|
+
agents[role] = variant ? { model: resolved.model, variant } : { model: resolved.model };
|
|
6218
|
+
} else {
|
|
6219
|
+
agents[role] = { model: ULTIMATE_FALLBACK };
|
|
6220
|
+
}
|
|
6221
|
+
}
|
|
6222
|
+
for (const [cat, req] of Object.entries(CATEGORY_MODEL_REQUIREMENTS)) {
|
|
6223
|
+
const fallbackChain = cat === "unspecified-high" && !avail.isMaxPlan ? CATEGORY_MODEL_REQUIREMENTS["unspecified-low"].fallbackChain : req.fallbackChain;
|
|
6224
|
+
const resolved = resolveModelFromChain(fallbackChain, avail);
|
|
6225
|
+
if (resolved) {
|
|
6226
|
+
const variant = resolved.variant ?? req.variant;
|
|
6227
|
+
categories[cat] = variant ? { model: resolved.model, variant } : { model: resolved.model };
|
|
6228
|
+
} else {
|
|
6229
|
+
categories[cat] = { model: ULTIMATE_FALLBACK };
|
|
6230
|
+
}
|
|
6231
|
+
}
|
|
6232
|
+
return {
|
|
6233
|
+
$schema: SCHEMA_URL,
|
|
6234
|
+
agents,
|
|
6235
|
+
categories
|
|
6236
|
+
};
|
|
6237
|
+
}
|
|
6238
|
+
var ZAI_MODEL = "zai-coding-plan/glm-4.7", ULTIMATE_FALLBACK = "opencode/big-pickle", SCHEMA_URL = "https://raw.githubusercontent.com/code-yeongyu/oh-my-opencode/master/assets/oh-my-opencode.schema.json";
|
|
6239
|
+
var init_model_fallback = __esm(() => {
|
|
6240
|
+
init_model_requirements();
|
|
5975
6241
|
});
|
|
5976
6242
|
|
|
5977
6243
|
// src/cli/config-manager.ts
|
|
5978
|
-
import { existsSync as
|
|
6244
|
+
import { existsSync as existsSync4, mkdirSync, readFileSync as readFileSync3, writeFileSync, statSync } from "fs";
|
|
5979
6245
|
function initConfigContext(binary2, version) {
|
|
5980
6246
|
const paths = getOpenCodeConfigPaths({ binary: binary2, version });
|
|
5981
6247
|
configContext = { binary: binary2, version, paths };
|
|
@@ -6065,10 +6331,10 @@ async function getPluginNameWithVersion(currentVersion) {
|
|
|
6065
6331
|
function detectConfigFormat() {
|
|
6066
6332
|
const configJsonc = getConfigJsonc();
|
|
6067
6333
|
const configJson = getConfigJson();
|
|
6068
|
-
if (
|
|
6334
|
+
if (existsSync4(configJsonc)) {
|
|
6069
6335
|
return { format: "jsonc", path: configJsonc };
|
|
6070
6336
|
}
|
|
6071
|
-
if (
|
|
6337
|
+
if (existsSync4(configJson)) {
|
|
6072
6338
|
return { format: "json", path: configJson };
|
|
6073
6339
|
}
|
|
6074
6340
|
return { format: "none", path: configJson };
|
|
@@ -6076,31 +6342,31 @@ function detectConfigFormat() {
|
|
|
6076
6342
|
function isEmptyOrWhitespace(content) {
|
|
6077
6343
|
return content.trim().length === 0;
|
|
6078
6344
|
}
|
|
6079
|
-
function parseConfigWithError(
|
|
6345
|
+
function parseConfigWithError(path3) {
|
|
6080
6346
|
try {
|
|
6081
|
-
const stat = statSync(
|
|
6347
|
+
const stat = statSync(path3);
|
|
6082
6348
|
if (stat.size === 0) {
|
|
6083
|
-
return { config: null, error: `Config file is empty: ${
|
|
6349
|
+
return { config: null, error: `Config file is empty: ${path3}. Delete it or add valid JSON content.` };
|
|
6084
6350
|
}
|
|
6085
|
-
const content =
|
|
6351
|
+
const content = readFileSync3(path3, "utf-8");
|
|
6086
6352
|
if (isEmptyOrWhitespace(content)) {
|
|
6087
|
-
return { config: null, error: `Config file contains only whitespace: ${
|
|
6353
|
+
return { config: null, error: `Config file contains only whitespace: ${path3}. Delete it or add valid JSON content.` };
|
|
6088
6354
|
}
|
|
6089
6355
|
const config = parseJsonc(content);
|
|
6090
6356
|
if (config === null || config === undefined) {
|
|
6091
|
-
return { config: null, error: `Config file parsed to null/undefined: ${
|
|
6357
|
+
return { config: null, error: `Config file parsed to null/undefined: ${path3}. Ensure it contains valid JSON.` };
|
|
6092
6358
|
}
|
|
6093
6359
|
if (typeof config !== "object" || Array.isArray(config)) {
|
|
6094
|
-
return { config: null, error: `Config file must contain a JSON object, not ${Array.isArray(config) ? "an array" : typeof config}: ${
|
|
6360
|
+
return { config: null, error: `Config file must contain a JSON object, not ${Array.isArray(config) ? "an array" : typeof config}: ${path3}` };
|
|
6095
6361
|
}
|
|
6096
6362
|
return { config };
|
|
6097
6363
|
} catch (err) {
|
|
6098
|
-
return { config: null, error: formatErrorWithSuggestion(err, `parse config file ${
|
|
6364
|
+
return { config: null, error: formatErrorWithSuggestion(err, `parse config file ${path3}`) };
|
|
6099
6365
|
}
|
|
6100
6366
|
}
|
|
6101
6367
|
function ensureConfigDir() {
|
|
6102
6368
|
const configDir = getConfigDir();
|
|
6103
|
-
if (!
|
|
6369
|
+
if (!existsSync4(configDir)) {
|
|
6104
6370
|
mkdirSync(configDir, { recursive: true });
|
|
6105
6371
|
}
|
|
6106
6372
|
}
|
|
@@ -6110,25 +6376,25 @@ async function addPluginToOpenCodeConfig(currentVersion) {
|
|
|
6110
6376
|
} catch (err) {
|
|
6111
6377
|
return { success: false, configPath: getConfigDir(), error: formatErrorWithSuggestion(err, "create config directory") };
|
|
6112
6378
|
}
|
|
6113
|
-
const { format: format2, path:
|
|
6379
|
+
const { format: format2, path: path3 } = detectConfigFormat();
|
|
6114
6380
|
const pluginEntry = await getPluginNameWithVersion(currentVersion);
|
|
6115
6381
|
try {
|
|
6116
6382
|
if (format2 === "none") {
|
|
6117
6383
|
const config2 = { plugin: [pluginEntry] };
|
|
6118
|
-
writeFileSync(
|
|
6384
|
+
writeFileSync(path3, JSON.stringify(config2, null, 2) + `
|
|
6119
6385
|
`);
|
|
6120
|
-
return { success: true, configPath:
|
|
6386
|
+
return { success: true, configPath: path3 };
|
|
6121
6387
|
}
|
|
6122
|
-
const parseResult = parseConfigWithError(
|
|
6388
|
+
const parseResult = parseConfigWithError(path3);
|
|
6123
6389
|
if (!parseResult.config) {
|
|
6124
|
-
return { success: false, configPath:
|
|
6390
|
+
return { success: false, configPath: path3, error: parseResult.error ?? "Failed to parse config file" };
|
|
6125
6391
|
}
|
|
6126
6392
|
const config = parseResult.config;
|
|
6127
6393
|
const plugins = config.plugin ?? [];
|
|
6128
6394
|
const existingIndex = plugins.findIndex((p2) => p2 === PACKAGE_NAME || p2.startsWith(`${PACKAGE_NAME}@`));
|
|
6129
6395
|
if (existingIndex !== -1) {
|
|
6130
6396
|
if (plugins[existingIndex] === pluginEntry) {
|
|
6131
|
-
return { success: true, configPath:
|
|
6397
|
+
return { success: true, configPath: path3 };
|
|
6132
6398
|
}
|
|
6133
6399
|
plugins[existingIndex] = pluginEntry;
|
|
6134
6400
|
} else {
|
|
@@ -6136,7 +6402,7 @@ async function addPluginToOpenCodeConfig(currentVersion) {
|
|
|
6136
6402
|
}
|
|
6137
6403
|
config.plugin = plugins;
|
|
6138
6404
|
if (format2 === "jsonc") {
|
|
6139
|
-
const content =
|
|
6405
|
+
const content = readFileSync3(path3, "utf-8");
|
|
6140
6406
|
const pluginArrayRegex = /"plugin"\s*:\s*\[([\s\S]*?)\]/;
|
|
6141
6407
|
const match = content.match(pluginArrayRegex);
|
|
6142
6408
|
if (match) {
|
|
@@ -6145,19 +6411,19 @@ async function addPluginToOpenCodeConfig(currentVersion) {
|
|
|
6145
6411
|
const newContent = content.replace(pluginArrayRegex, `"plugin": [
|
|
6146
6412
|
${formattedPlugins}
|
|
6147
6413
|
]`);
|
|
6148
|
-
writeFileSync(
|
|
6414
|
+
writeFileSync(path3, newContent);
|
|
6149
6415
|
} else {
|
|
6150
6416
|
const newContent = content.replace(/^(\s*\{)/, `$1
|
|
6151
6417
|
"plugin": ["${pluginEntry}"],`);
|
|
6152
|
-
writeFileSync(
|
|
6418
|
+
writeFileSync(path3, newContent);
|
|
6153
6419
|
}
|
|
6154
6420
|
} else {
|
|
6155
|
-
writeFileSync(
|
|
6421
|
+
writeFileSync(path3, JSON.stringify(config, null, 2) + `
|
|
6156
6422
|
`);
|
|
6157
6423
|
}
|
|
6158
|
-
return { success: true, configPath:
|
|
6424
|
+
return { success: true, configPath: path3 };
|
|
6159
6425
|
} catch (err) {
|
|
6160
|
-
return { success: false, configPath:
|
|
6426
|
+
return { success: false, configPath: path3, error: formatErrorWithSuggestion(err, "update opencode config") };
|
|
6161
6427
|
}
|
|
6162
6428
|
}
|
|
6163
6429
|
function deepMerge(target, source) {
|
|
@@ -6174,63 +6440,7 @@ function deepMerge(target, source) {
|
|
|
6174
6440
|
return result;
|
|
6175
6441
|
}
|
|
6176
6442
|
function generateOmoConfig(installConfig) {
|
|
6177
|
-
|
|
6178
|
-
$schema: "https://raw.githubusercontent.com/code-yeongyu/oh-my-opencode/master/assets/oh-my-opencode.schema.json"
|
|
6179
|
-
};
|
|
6180
|
-
const agents = {};
|
|
6181
|
-
if (!installConfig.hasClaude) {
|
|
6182
|
-
agents["Sisyphus"] = {
|
|
6183
|
-
model: installConfig.hasCopilot ? "github-copilot/claude-opus-4.5" : "opencode/glm-4.7-free"
|
|
6184
|
-
};
|
|
6185
|
-
}
|
|
6186
|
-
agents["librarian"] = { model: "opencode/glm-4.7-free" };
|
|
6187
|
-
if (installConfig.hasGemini) {
|
|
6188
|
-
agents["explore"] = { model: "google/antigravity-gemini-3-flash" };
|
|
6189
|
-
} else if (installConfig.hasClaude && installConfig.isMax20) {
|
|
6190
|
-
agents["explore"] = { model: "anthropic/claude-haiku-4-5" };
|
|
6191
|
-
} else if (installConfig.hasCopilot) {
|
|
6192
|
-
agents["explore"] = { model: "github-copilot/grok-code-fast-1" };
|
|
6193
|
-
} else {
|
|
6194
|
-
agents["explore"] = { model: "opencode/glm-4.7-free" };
|
|
6195
|
-
}
|
|
6196
|
-
if (!installConfig.hasChatGPT) {
|
|
6197
|
-
const oracleFallback = installConfig.hasCopilot ? "github-copilot/gpt-5.2" : installConfig.hasClaude ? "anthropic/claude-opus-4-5" : "opencode/glm-4.7-free";
|
|
6198
|
-
agents["oracle"] = { model: oracleFallback };
|
|
6199
|
-
}
|
|
6200
|
-
if (installConfig.hasGemini) {
|
|
6201
|
-
agents["frontend-ui-ux-engineer"] = { model: "google/antigravity-gemini-3-pro-high" };
|
|
6202
|
-
agents["document-writer"] = { model: "google/antigravity-gemini-3-flash" };
|
|
6203
|
-
agents["multimodal-looker"] = { model: "google/antigravity-gemini-3-flash" };
|
|
6204
|
-
} else if (installConfig.hasClaude) {
|
|
6205
|
-
agents["frontend-ui-ux-engineer"] = { model: "anthropic/claude-opus-4-5" };
|
|
6206
|
-
agents["document-writer"] = { model: "anthropic/claude-opus-4-5" };
|
|
6207
|
-
agents["multimodal-looker"] = { model: "anthropic/claude-opus-4-5" };
|
|
6208
|
-
} else if (installConfig.hasCopilot) {
|
|
6209
|
-
agents["frontend-ui-ux-engineer"] = { model: "github-copilot/gemini-3-pro-preview" };
|
|
6210
|
-
agents["document-writer"] = { model: "github-copilot/gemini-3-flash-preview" };
|
|
6211
|
-
agents["multimodal-looker"] = { model: "github-copilot/gemini-3-flash-preview" };
|
|
6212
|
-
} else {
|
|
6213
|
-
agents["frontend-ui-ux-engineer"] = { model: "opencode/glm-4.7-free" };
|
|
6214
|
-
agents["document-writer"] = { model: "opencode/glm-4.7-free" };
|
|
6215
|
-
agents["multimodal-looker"] = { model: "opencode/glm-4.7-free" };
|
|
6216
|
-
}
|
|
6217
|
-
if (Object.keys(agents).length > 0) {
|
|
6218
|
-
config.agents = agents;
|
|
6219
|
-
}
|
|
6220
|
-
if (installConfig.hasGemini) {
|
|
6221
|
-
config.categories = {
|
|
6222
|
-
"visual-engineering": { model: "google/gemini-3-pro-high" },
|
|
6223
|
-
artistry: { model: "google/gemini-3-pro-high" },
|
|
6224
|
-
writing: { model: "google/gemini-3-flash-high" }
|
|
6225
|
-
};
|
|
6226
|
-
} else if (installConfig.hasCopilot) {
|
|
6227
|
-
config.categories = {
|
|
6228
|
-
"visual-engineering": { model: "github-copilot/gemini-3-pro-preview" },
|
|
6229
|
-
artistry: { model: "github-copilot/gemini-3-pro-preview" },
|
|
6230
|
-
writing: { model: "github-copilot/gemini-3-flash-preview" }
|
|
6231
|
-
};
|
|
6232
|
-
}
|
|
6233
|
-
return config;
|
|
6443
|
+
return generateModelConfig(installConfig);
|
|
6234
6444
|
}
|
|
6235
6445
|
function writeOmoConfig(installConfig) {
|
|
6236
6446
|
try {
|
|
@@ -6241,10 +6451,10 @@ function writeOmoConfig(installConfig) {
|
|
|
6241
6451
|
const omoConfigPath = getOmoConfig();
|
|
6242
6452
|
try {
|
|
6243
6453
|
const newConfig = generateOmoConfig(installConfig);
|
|
6244
|
-
if (
|
|
6454
|
+
if (existsSync4(omoConfigPath)) {
|
|
6245
6455
|
try {
|
|
6246
6456
|
const stat = statSync(omoConfigPath);
|
|
6247
|
-
const content =
|
|
6457
|
+
const content = readFileSync3(omoConfigPath, "utf-8");
|
|
6248
6458
|
if (stat.size === 0 || isEmptyOrWhitespace(content)) {
|
|
6249
6459
|
writeFileSync(omoConfigPath, JSON.stringify(newConfig, null, 2) + `
|
|
6250
6460
|
`);
|
|
@@ -6310,11 +6520,11 @@ async function addAuthPlugins(config) {
|
|
|
6310
6520
|
} catch (err) {
|
|
6311
6521
|
return { success: false, configPath: getConfigDir(), error: formatErrorWithSuggestion(err, "create config directory") };
|
|
6312
6522
|
}
|
|
6313
|
-
const { format: format2, path:
|
|
6523
|
+
const { format: format2, path: path3 } = detectConfigFormat();
|
|
6314
6524
|
try {
|
|
6315
6525
|
let existingConfig = null;
|
|
6316
6526
|
if (format2 !== "none") {
|
|
6317
|
-
const parseResult = parseConfigWithError(
|
|
6527
|
+
const parseResult = parseConfigWithError(path3);
|
|
6318
6528
|
if (parseResult.error && !parseResult.config) {
|
|
6319
6529
|
existingConfig = {};
|
|
6320
6530
|
} else {
|
|
@@ -6330,11 +6540,11 @@ async function addAuthPlugins(config) {
|
|
|
6330
6540
|
}
|
|
6331
6541
|
}
|
|
6332
6542
|
const newConfig = { ...existingConfig ?? {}, plugin: plugins };
|
|
6333
|
-
writeFileSync(
|
|
6543
|
+
writeFileSync(path3, JSON.stringify(newConfig, null, 2) + `
|
|
6334
6544
|
`);
|
|
6335
|
-
return { success: true, configPath:
|
|
6545
|
+
return { success: true, configPath: path3 };
|
|
6336
6546
|
} catch (err) {
|
|
6337
|
-
return { success: false, configPath:
|
|
6547
|
+
return { success: false, configPath: path3, error: formatErrorWithSuggestion(err, "add auth plugins to config") };
|
|
6338
6548
|
}
|
|
6339
6549
|
}
|
|
6340
6550
|
async function runBunInstall() {
|
|
@@ -6383,11 +6593,11 @@ function addProviderConfig(config) {
|
|
|
6383
6593
|
} catch (err) {
|
|
6384
6594
|
return { success: false, configPath: getConfigDir(), error: formatErrorWithSuggestion(err, "create config directory") };
|
|
6385
6595
|
}
|
|
6386
|
-
const { format: format2, path:
|
|
6596
|
+
const { format: format2, path: path3 } = detectConfigFormat();
|
|
6387
6597
|
try {
|
|
6388
6598
|
let existingConfig = null;
|
|
6389
6599
|
if (format2 !== "none") {
|
|
6390
|
-
const parseResult = parseConfigWithError(
|
|
6600
|
+
const parseResult = parseConfigWithError(path3);
|
|
6391
6601
|
if (parseResult.error && !parseResult.config) {
|
|
6392
6602
|
existingConfig = {};
|
|
6393
6603
|
} else {
|
|
@@ -6402,11 +6612,31 @@ function addProviderConfig(config) {
|
|
|
6402
6612
|
if (Object.keys(providers).length > 0) {
|
|
6403
6613
|
newConfig.provider = providers;
|
|
6404
6614
|
}
|
|
6405
|
-
writeFileSync(
|
|
6615
|
+
writeFileSync(path3, JSON.stringify(newConfig, null, 2) + `
|
|
6406
6616
|
`);
|
|
6407
|
-
return { success: true, configPath:
|
|
6617
|
+
return { success: true, configPath: path3 };
|
|
6408
6618
|
} catch (err) {
|
|
6409
|
-
return { success: false, configPath:
|
|
6619
|
+
return { success: false, configPath: path3, error: formatErrorWithSuggestion(err, "add provider config") };
|
|
6620
|
+
}
|
|
6621
|
+
}
|
|
6622
|
+
function detectProvidersFromOmoConfig() {
|
|
6623
|
+
const omoConfigPath = getOmoConfig();
|
|
6624
|
+
if (!existsSync4(omoConfigPath)) {
|
|
6625
|
+
return { hasOpenAI: true, hasOpencodeZen: true, hasZaiCodingPlan: false };
|
|
6626
|
+
}
|
|
6627
|
+
try {
|
|
6628
|
+
const content = readFileSync3(omoConfigPath, "utf-8");
|
|
6629
|
+
const omoConfig = parseJsonc(content);
|
|
6630
|
+
if (!omoConfig || typeof omoConfig !== "object") {
|
|
6631
|
+
return { hasOpenAI: true, hasOpencodeZen: true, hasZaiCodingPlan: false };
|
|
6632
|
+
}
|
|
6633
|
+
const configStr = JSON.stringify(omoConfig);
|
|
6634
|
+
const hasOpenAI = configStr.includes('"openai/');
|
|
6635
|
+
const hasOpencodeZen = configStr.includes('"opencode/');
|
|
6636
|
+
const hasZaiCodingPlan = configStr.includes('"zai-coding-plan/');
|
|
6637
|
+
return { hasOpenAI, hasOpencodeZen, hasZaiCodingPlan };
|
|
6638
|
+
} catch {
|
|
6639
|
+
return { hasOpenAI: true, hasOpencodeZen: true, hasZaiCodingPlan: false };
|
|
6410
6640
|
}
|
|
6411
6641
|
}
|
|
6412
6642
|
function detectCurrentConfig() {
|
|
@@ -6414,15 +6644,17 @@ function detectCurrentConfig() {
|
|
|
6414
6644
|
isInstalled: false,
|
|
6415
6645
|
hasClaude: true,
|
|
6416
6646
|
isMax20: true,
|
|
6417
|
-
|
|
6647
|
+
hasOpenAI: true,
|
|
6418
6648
|
hasGemini: false,
|
|
6419
|
-
hasCopilot: false
|
|
6649
|
+
hasCopilot: false,
|
|
6650
|
+
hasOpencodeZen: true,
|
|
6651
|
+
hasZaiCodingPlan: false
|
|
6420
6652
|
};
|
|
6421
|
-
const { format: format2, path:
|
|
6653
|
+
const { format: format2, path: path3 } = detectConfigFormat();
|
|
6422
6654
|
if (format2 === "none") {
|
|
6423
6655
|
return result;
|
|
6424
6656
|
}
|
|
6425
|
-
const parseResult = parseConfigWithError(
|
|
6657
|
+
const parseResult = parseConfigWithError(path3);
|
|
6426
6658
|
if (!parseResult.config) {
|
|
6427
6659
|
return result;
|
|
6428
6660
|
}
|
|
@@ -6433,44 +6665,16 @@ function detectCurrentConfig() {
|
|
|
6433
6665
|
return result;
|
|
6434
6666
|
}
|
|
6435
6667
|
result.hasGemini = plugins.some((p2) => p2.startsWith("opencode-antigravity-auth"));
|
|
6436
|
-
const
|
|
6437
|
-
|
|
6438
|
-
|
|
6439
|
-
|
|
6440
|
-
try {
|
|
6441
|
-
const stat = statSync(omoConfigPath);
|
|
6442
|
-
if (stat.size === 0) {
|
|
6443
|
-
return result;
|
|
6444
|
-
}
|
|
6445
|
-
const content = readFileSync2(omoConfigPath, "utf-8");
|
|
6446
|
-
if (isEmptyOrWhitespace(content)) {
|
|
6447
|
-
return result;
|
|
6448
|
-
}
|
|
6449
|
-
const omoConfig = parseJsonc(content);
|
|
6450
|
-
if (!omoConfig || typeof omoConfig !== "object") {
|
|
6451
|
-
return result;
|
|
6452
|
-
}
|
|
6453
|
-
const agents = omoConfig.agents ?? {};
|
|
6454
|
-
if (agents["Sisyphus"]?.model === "opencode/glm-4.7-free") {
|
|
6455
|
-
result.hasClaude = false;
|
|
6456
|
-
result.isMax20 = false;
|
|
6457
|
-
} else if (agents["librarian"]?.model === "opencode/glm-4.7-free") {
|
|
6458
|
-
result.hasClaude = true;
|
|
6459
|
-
result.isMax20 = false;
|
|
6460
|
-
}
|
|
6461
|
-
if (agents["oracle"]?.model?.startsWith("anthropic/")) {
|
|
6462
|
-
result.hasChatGPT = false;
|
|
6463
|
-
} else if (agents["oracle"]?.model === "opencode/glm-4.7-free") {
|
|
6464
|
-
result.hasChatGPT = false;
|
|
6465
|
-
}
|
|
6466
|
-
const hasAnyCopilotModel = Object.values(agents).some((agent) => agent?.model?.startsWith("github-copilot/"));
|
|
6467
|
-
result.hasCopilot = hasAnyCopilotModel;
|
|
6468
|
-
} catch {}
|
|
6668
|
+
const { hasOpenAI, hasOpencodeZen, hasZaiCodingPlan } = detectProvidersFromOmoConfig();
|
|
6669
|
+
result.hasOpenAI = hasOpenAI;
|
|
6670
|
+
result.hasOpencodeZen = hasOpencodeZen;
|
|
6671
|
+
result.hasZaiCodingPlan = hasZaiCodingPlan;
|
|
6469
6672
|
return result;
|
|
6470
6673
|
}
|
|
6471
6674
|
var OPENCODE_BINARIES, configContext = null, BUN_INSTALL_TIMEOUT_SECONDS = 60, BUN_INSTALL_TIMEOUT_MS, NPM_FETCH_TIMEOUT_MS = 5000, PACKAGE_NAME = "oh-my-opencode", PRIORITIZED_TAGS, ANTIGRAVITY_PROVIDER_CONFIG;
|
|
6472
6675
|
var init_config_manager = __esm(() => {
|
|
6473
6676
|
init_shared();
|
|
6677
|
+
init_model_fallback();
|
|
6474
6678
|
OPENCODE_BINARIES = ["opencode", "opencode-desktop"];
|
|
6475
6679
|
BUN_INSTALL_TIMEOUT_MS = BUN_INSTALL_TIMEOUT_SECONDS * 1000;
|
|
6476
6680
|
PRIORITIZED_TAGS = ["latest", "beta", "next"];
|
|
@@ -6478,25 +6682,48 @@ var init_config_manager = __esm(() => {
|
|
|
6478
6682
|
google: {
|
|
6479
6683
|
name: "Google",
|
|
6480
6684
|
models: {
|
|
6481
|
-
"antigravity-gemini-3-pro
|
|
6482
|
-
name: "Gemini 3 Pro
|
|
6483
|
-
thinking: true,
|
|
6484
|
-
attachment: true,
|
|
6685
|
+
"antigravity-gemini-3-pro": {
|
|
6686
|
+
name: "Gemini 3 Pro (Antigravity)",
|
|
6485
6687
|
limit: { context: 1048576, output: 65535 },
|
|
6486
|
-
modalities: { input: ["text", "image", "pdf"], output: ["text"] }
|
|
6487
|
-
|
|
6488
|
-
|
|
6489
|
-
|
|
6490
|
-
|
|
6491
|
-
attachment: true,
|
|
6492
|
-
limit: { context: 1048576, output: 65535 },
|
|
6493
|
-
modalities: { input: ["text", "image", "pdf"], output: ["text"] }
|
|
6688
|
+
modalities: { input: ["text", "image", "pdf"], output: ["text"] },
|
|
6689
|
+
variants: {
|
|
6690
|
+
low: { thinkingLevel: "low" },
|
|
6691
|
+
high: { thinkingLevel: "high" }
|
|
6692
|
+
}
|
|
6494
6693
|
},
|
|
6495
6694
|
"antigravity-gemini-3-flash": {
|
|
6496
6695
|
name: "Gemini 3 Flash (Antigravity)",
|
|
6497
|
-
attachment: true,
|
|
6498
6696
|
limit: { context: 1048576, output: 65536 },
|
|
6697
|
+
modalities: { input: ["text", "image", "pdf"], output: ["text"] },
|
|
6698
|
+
variants: {
|
|
6699
|
+
minimal: { thinkingLevel: "minimal" },
|
|
6700
|
+
low: { thinkingLevel: "low" },
|
|
6701
|
+
medium: { thinkingLevel: "medium" },
|
|
6702
|
+
high: { thinkingLevel: "high" }
|
|
6703
|
+
}
|
|
6704
|
+
},
|
|
6705
|
+
"antigravity-claude-sonnet-4-5": {
|
|
6706
|
+
name: "Claude Sonnet 4.5 (Antigravity)",
|
|
6707
|
+
limit: { context: 200000, output: 64000 },
|
|
6499
6708
|
modalities: { input: ["text", "image", "pdf"], output: ["text"] }
|
|
6709
|
+
},
|
|
6710
|
+
"antigravity-claude-sonnet-4-5-thinking": {
|
|
6711
|
+
name: "Claude Sonnet 4.5 Thinking (Antigravity)",
|
|
6712
|
+
limit: { context: 200000, output: 64000 },
|
|
6713
|
+
modalities: { input: ["text", "image", "pdf"], output: ["text"] },
|
|
6714
|
+
variants: {
|
|
6715
|
+
low: { thinkingConfig: { thinkingBudget: 8192 } },
|
|
6716
|
+
max: { thinkingConfig: { thinkingBudget: 32768 } }
|
|
6717
|
+
}
|
|
6718
|
+
},
|
|
6719
|
+
"antigravity-claude-opus-4-5-thinking": {
|
|
6720
|
+
name: "Claude Opus 4.5 Thinking (Antigravity)",
|
|
6721
|
+
limit: { context: 200000, output: 64000 },
|
|
6722
|
+
modalities: { input: ["text", "image", "pdf"], output: ["text"] },
|
|
6723
|
+
variants: {
|
|
6724
|
+
low: { thinkingConfig: { thinkingBudget: 8192 } },
|
|
6725
|
+
max: { thinkingConfig: { thinkingBudget: 32768 } }
|
|
6726
|
+
}
|
|
6500
6727
|
}
|
|
6501
6728
|
}
|
|
6502
6729
|
}
|
|
@@ -6504,56 +6731,43 @@ var init_config_manager = __esm(() => {
|
|
|
6504
6731
|
});
|
|
6505
6732
|
|
|
6506
6733
|
// src/hooks/auto-update-checker/constants.ts
|
|
6507
|
-
import * as
|
|
6508
|
-
import * as
|
|
6509
|
-
import * as fs2 from "fs";
|
|
6734
|
+
import * as path3 from "path";
|
|
6735
|
+
import * as os3 from "os";
|
|
6510
6736
|
function getCacheDir() {
|
|
6511
6737
|
if (process.platform === "win32") {
|
|
6512
|
-
return
|
|
6513
|
-
}
|
|
6514
|
-
return path2.join(os2.homedir(), ".cache", "opencode");
|
|
6515
|
-
}
|
|
6516
|
-
function getUserConfigDir() {
|
|
6517
|
-
if (process.platform === "win32") {
|
|
6518
|
-
const crossPlatformDir = path2.join(os2.homedir(), ".config");
|
|
6519
|
-
const appdataDir = process.env.APPDATA ?? path2.join(os2.homedir(), "AppData", "Roaming");
|
|
6520
|
-
const crossPlatformConfig = path2.join(crossPlatformDir, "opencode", "opencode.json");
|
|
6521
|
-
const crossPlatformConfigJsonc = path2.join(crossPlatformDir, "opencode", "opencode.jsonc");
|
|
6522
|
-
if (fs2.existsSync(crossPlatformConfig) || fs2.existsSync(crossPlatformConfigJsonc)) {
|
|
6523
|
-
return crossPlatformDir;
|
|
6524
|
-
}
|
|
6525
|
-
return appdataDir;
|
|
6738
|
+
return path3.join(process.env.LOCALAPPDATA ?? os3.homedir(), "opencode");
|
|
6526
6739
|
}
|
|
6527
|
-
return
|
|
6740
|
+
return path3.join(os3.homedir(), ".cache", "opencode");
|
|
6528
6741
|
}
|
|
6529
6742
|
function getWindowsAppdataDir() {
|
|
6530
6743
|
if (process.platform !== "win32")
|
|
6531
6744
|
return null;
|
|
6532
|
-
return process.env.APPDATA ??
|
|
6745
|
+
return process.env.APPDATA ?? path3.join(os3.homedir(), "AppData", "Roaming");
|
|
6533
6746
|
}
|
|
6534
6747
|
var PACKAGE_NAME2 = "oh-my-opencode", NPM_REGISTRY_URL, NPM_FETCH_TIMEOUT = 5000, CACHE_DIR, VERSION_FILE, INSTALLED_PACKAGE_JSON, USER_CONFIG_DIR, USER_OPENCODE_CONFIG, USER_OPENCODE_CONFIG_JSONC;
|
|
6535
6748
|
var init_constants = __esm(() => {
|
|
6749
|
+
init_shared();
|
|
6536
6750
|
NPM_REGISTRY_URL = `https://registry.npmjs.org/-/package/${PACKAGE_NAME2}/dist-tags`;
|
|
6537
6751
|
CACHE_DIR = getCacheDir();
|
|
6538
|
-
VERSION_FILE =
|
|
6539
|
-
INSTALLED_PACKAGE_JSON =
|
|
6540
|
-
USER_CONFIG_DIR =
|
|
6541
|
-
USER_OPENCODE_CONFIG =
|
|
6542
|
-
USER_OPENCODE_CONFIG_JSONC =
|
|
6752
|
+
VERSION_FILE = path3.join(CACHE_DIR, "version");
|
|
6753
|
+
INSTALLED_PACKAGE_JSON = path3.join(CACHE_DIR, "node_modules", PACKAGE_NAME2, "package.json");
|
|
6754
|
+
USER_CONFIG_DIR = getOpenCodeConfigDir({ binary: "opencode" });
|
|
6755
|
+
USER_OPENCODE_CONFIG = path3.join(USER_CONFIG_DIR, "opencode.json");
|
|
6756
|
+
USER_OPENCODE_CONFIG_JSONC = path3.join(USER_CONFIG_DIR, "opencode.jsonc");
|
|
6543
6757
|
});
|
|
6544
6758
|
|
|
6545
6759
|
// src/hooks/auto-update-checker/cache.ts
|
|
6546
|
-
import * as
|
|
6547
|
-
import * as
|
|
6760
|
+
import * as fs2 from "fs";
|
|
6761
|
+
import * as path4 from "path";
|
|
6548
6762
|
function stripTrailingCommas(json2) {
|
|
6549
6763
|
return json2.replace(/,(\s*[}\]])/g, "$1");
|
|
6550
6764
|
}
|
|
6551
6765
|
function removeFromBunLock(packageName) {
|
|
6552
|
-
const lockPath =
|
|
6553
|
-
if (!
|
|
6766
|
+
const lockPath = path4.join(CACHE_DIR, "bun.lock");
|
|
6767
|
+
if (!fs2.existsSync(lockPath))
|
|
6554
6768
|
return false;
|
|
6555
6769
|
try {
|
|
6556
|
-
const content =
|
|
6770
|
+
const content = fs2.readFileSync(lockPath, "utf-8");
|
|
6557
6771
|
const lock = JSON.parse(stripTrailingCommas(content));
|
|
6558
6772
|
let modified = false;
|
|
6559
6773
|
if (lock.workspaces?.[""]?.dependencies?.[packageName]) {
|
|
@@ -6565,7 +6779,7 @@ function removeFromBunLock(packageName) {
|
|
|
6565
6779
|
modified = true;
|
|
6566
6780
|
}
|
|
6567
6781
|
if (modified) {
|
|
6568
|
-
|
|
6782
|
+
fs2.writeFileSync(lockPath, JSON.stringify(lock, null, 2));
|
|
6569
6783
|
log(`[auto-update-checker] Removed from bun.lock: ${packageName}`);
|
|
6570
6784
|
}
|
|
6571
6785
|
return modified;
|
|
@@ -6575,22 +6789,22 @@ function removeFromBunLock(packageName) {
|
|
|
6575
6789
|
}
|
|
6576
6790
|
function invalidatePackage(packageName = PACKAGE_NAME2) {
|
|
6577
6791
|
try {
|
|
6578
|
-
const pkgDir =
|
|
6579
|
-
const pkgJsonPath =
|
|
6792
|
+
const pkgDir = path4.join(CACHE_DIR, "node_modules", packageName);
|
|
6793
|
+
const pkgJsonPath = path4.join(CACHE_DIR, "package.json");
|
|
6580
6794
|
let packageRemoved = false;
|
|
6581
6795
|
let dependencyRemoved = false;
|
|
6582
6796
|
let lockRemoved = false;
|
|
6583
|
-
if (
|
|
6584
|
-
|
|
6797
|
+
if (fs2.existsSync(pkgDir)) {
|
|
6798
|
+
fs2.rmSync(pkgDir, { recursive: true, force: true });
|
|
6585
6799
|
log(`[auto-update-checker] Package removed: ${pkgDir}`);
|
|
6586
6800
|
packageRemoved = true;
|
|
6587
6801
|
}
|
|
6588
|
-
if (
|
|
6589
|
-
const content =
|
|
6802
|
+
if (fs2.existsSync(pkgJsonPath)) {
|
|
6803
|
+
const content = fs2.readFileSync(pkgJsonPath, "utf-8");
|
|
6590
6804
|
const pkgJson = JSON.parse(content);
|
|
6591
6805
|
if (pkgJson.dependencies?.[packageName]) {
|
|
6592
6806
|
delete pkgJson.dependencies[packageName];
|
|
6593
|
-
|
|
6807
|
+
fs2.writeFileSync(pkgJsonPath, JSON.stringify(pkgJson, null, 2));
|
|
6594
6808
|
log(`[auto-update-checker] Dependency removed from package.json: ${packageName}`);
|
|
6595
6809
|
dependencyRemoved = true;
|
|
6596
6810
|
}
|
|
@@ -6682,6 +6896,7 @@ v${latestVersion} available. Restart OpenCode to apply.` : `OpenCode is now on S
|
|
|
6682
6896
|
const localDevVersion = getLocalDevVersion(ctx.directory);
|
|
6683
6897
|
const displayVersion = localDevVersion ?? cachedVersion;
|
|
6684
6898
|
await showConfigErrorsIfAny(ctx);
|
|
6899
|
+
await showModelCacheWarningIfNeeded(ctx);
|
|
6685
6900
|
if (localDevVersion) {
|
|
6686
6901
|
if (showStartupToast) {
|
|
6687
6902
|
showLocalDevToast(ctx, displayVersion, isSisyphusEnabled).catch(() => {});
|
|
@@ -6755,6 +6970,19 @@ async function runBunInstallSafe() {
|
|
|
6755
6970
|
return false;
|
|
6756
6971
|
}
|
|
6757
6972
|
}
|
|
6973
|
+
async function showModelCacheWarningIfNeeded(ctx) {
|
|
6974
|
+
if (isModelCacheAvailable())
|
|
6975
|
+
return;
|
|
6976
|
+
await ctx.client.tui.showToast({
|
|
6977
|
+
body: {
|
|
6978
|
+
title: "Model Cache Not Found",
|
|
6979
|
+
message: "Run 'opencode models --refresh' or restart OpenCode to populate the models cache for optimal agent model selection.",
|
|
6980
|
+
variant: "warning",
|
|
6981
|
+
duration: 1e4
|
|
6982
|
+
}
|
|
6983
|
+
}).catch(() => {});
|
|
6984
|
+
log("[auto-update-checker] Model cache warning shown");
|
|
6985
|
+
}
|
|
6758
6986
|
async function showConfigErrorsIfAny(ctx) {
|
|
6759
6987
|
const errors = getConfigLoadErrors();
|
|
6760
6988
|
if (errors.length === 0)
|
|
@@ -6832,16 +7060,17 @@ var init_auto_update_checker = __esm(() => {
|
|
|
6832
7060
|
init_logger();
|
|
6833
7061
|
init_config_errors();
|
|
6834
7062
|
init_config_manager();
|
|
7063
|
+
init_model_availability();
|
|
6835
7064
|
init_checker();
|
|
6836
7065
|
init_cache();
|
|
6837
7066
|
SISYPHUS_SPINNER = ["\xB7", "\u2022", "\u25CF", "\u25CB", "\u25CC", "\u25E6", " "];
|
|
6838
7067
|
});
|
|
6839
7068
|
|
|
6840
7069
|
// src/hooks/auto-update-checker/checker.ts
|
|
6841
|
-
import * as
|
|
6842
|
-
import * as
|
|
7070
|
+
import * as fs3 from "fs";
|
|
7071
|
+
import * as path5 from "path";
|
|
6843
7072
|
import { fileURLToPath } from "url";
|
|
6844
|
-
import * as
|
|
7073
|
+
import * as os4 from "os";
|
|
6845
7074
|
function isLocalDevMode(directory) {
|
|
6846
7075
|
return getLocalDevPath(directory) !== null;
|
|
6847
7076
|
}
|
|
@@ -6850,18 +7079,18 @@ function stripJsonComments(json2) {
|
|
|
6850
7079
|
}
|
|
6851
7080
|
function getConfigPaths(directory) {
|
|
6852
7081
|
const paths = [
|
|
6853
|
-
|
|
6854
|
-
|
|
7082
|
+
path5.join(directory, ".opencode", "opencode.json"),
|
|
7083
|
+
path5.join(directory, ".opencode", "opencode.jsonc"),
|
|
6855
7084
|
USER_OPENCODE_CONFIG,
|
|
6856
7085
|
USER_OPENCODE_CONFIG_JSONC
|
|
6857
7086
|
];
|
|
6858
7087
|
if (process.platform === "win32") {
|
|
6859
|
-
const crossPlatformDir =
|
|
7088
|
+
const crossPlatformDir = path5.join(os4.homedir(), ".config");
|
|
6860
7089
|
const appdataDir = getWindowsAppdataDir();
|
|
6861
7090
|
if (appdataDir) {
|
|
6862
7091
|
const alternateDir = USER_CONFIG_DIR === crossPlatformDir ? appdataDir : crossPlatformDir;
|
|
6863
|
-
const alternateConfig =
|
|
6864
|
-
const alternateConfigJsonc =
|
|
7092
|
+
const alternateConfig = path5.join(alternateDir, "opencode", "opencode.json");
|
|
7093
|
+
const alternateConfigJsonc = path5.join(alternateDir, "opencode", "opencode.jsonc");
|
|
6865
7094
|
if (!paths.includes(alternateConfig)) {
|
|
6866
7095
|
paths.push(alternateConfig);
|
|
6867
7096
|
}
|
|
@@ -6875,9 +7104,9 @@ function getConfigPaths(directory) {
|
|
|
6875
7104
|
function getLocalDevPath(directory) {
|
|
6876
7105
|
for (const configPath of getConfigPaths(directory)) {
|
|
6877
7106
|
try {
|
|
6878
|
-
if (!
|
|
7107
|
+
if (!fs3.existsSync(configPath))
|
|
6879
7108
|
continue;
|
|
6880
|
-
const content =
|
|
7109
|
+
const content = fs3.readFileSync(configPath, "utf-8");
|
|
6881
7110
|
const config = JSON.parse(stripJsonComments(content));
|
|
6882
7111
|
const plugins = config.plugin ?? [];
|
|
6883
7112
|
for (const entry of plugins) {
|
|
@@ -6897,19 +7126,19 @@ function getLocalDevPath(directory) {
|
|
|
6897
7126
|
}
|
|
6898
7127
|
function findPackageJsonUp(startPath) {
|
|
6899
7128
|
try {
|
|
6900
|
-
const stat =
|
|
6901
|
-
let dir = stat.isDirectory() ? startPath :
|
|
7129
|
+
const stat = fs3.statSync(startPath);
|
|
7130
|
+
let dir = stat.isDirectory() ? startPath : path5.dirname(startPath);
|
|
6902
7131
|
for (let i2 = 0;i2 < 10; i2++) {
|
|
6903
|
-
const pkgPath =
|
|
6904
|
-
if (
|
|
7132
|
+
const pkgPath = path5.join(dir, "package.json");
|
|
7133
|
+
if (fs3.existsSync(pkgPath)) {
|
|
6905
7134
|
try {
|
|
6906
|
-
const content =
|
|
7135
|
+
const content = fs3.readFileSync(pkgPath, "utf-8");
|
|
6907
7136
|
const pkg = JSON.parse(content);
|
|
6908
7137
|
if (pkg.name === PACKAGE_NAME2)
|
|
6909
7138
|
return pkgPath;
|
|
6910
7139
|
} catch {}
|
|
6911
7140
|
}
|
|
6912
|
-
const parent =
|
|
7141
|
+
const parent = path5.dirname(dir);
|
|
6913
7142
|
if (parent === dir)
|
|
6914
7143
|
break;
|
|
6915
7144
|
dir = parent;
|
|
@@ -6925,7 +7154,7 @@ function getLocalDevVersion(directory) {
|
|
|
6925
7154
|
const pkgPath = findPackageJsonUp(localPath);
|
|
6926
7155
|
if (!pkgPath)
|
|
6927
7156
|
return null;
|
|
6928
|
-
const content =
|
|
7157
|
+
const content = fs3.readFileSync(pkgPath, "utf-8");
|
|
6929
7158
|
const pkg = JSON.parse(content);
|
|
6930
7159
|
return pkg.version ?? null;
|
|
6931
7160
|
} catch {
|
|
@@ -6935,9 +7164,9 @@ function getLocalDevVersion(directory) {
|
|
|
6935
7164
|
function findPluginEntry(directory) {
|
|
6936
7165
|
for (const configPath of getConfigPaths(directory)) {
|
|
6937
7166
|
try {
|
|
6938
|
-
if (!
|
|
7167
|
+
if (!fs3.existsSync(configPath))
|
|
6939
7168
|
continue;
|
|
6940
|
-
const content =
|
|
7169
|
+
const content = fs3.readFileSync(configPath, "utf-8");
|
|
6941
7170
|
const config = JSON.parse(stripJsonComments(content));
|
|
6942
7171
|
const plugins = config.plugin ?? [];
|
|
6943
7172
|
for (const entry of plugins) {
|
|
@@ -6958,18 +7187,18 @@ function findPluginEntry(directory) {
|
|
|
6958
7187
|
}
|
|
6959
7188
|
function getCachedVersion() {
|
|
6960
7189
|
try {
|
|
6961
|
-
if (
|
|
6962
|
-
const content =
|
|
7190
|
+
if (fs3.existsSync(INSTALLED_PACKAGE_JSON)) {
|
|
7191
|
+
const content = fs3.readFileSync(INSTALLED_PACKAGE_JSON, "utf-8");
|
|
6963
7192
|
const pkg = JSON.parse(content);
|
|
6964
7193
|
if (pkg.version)
|
|
6965
7194
|
return pkg.version;
|
|
6966
7195
|
}
|
|
6967
7196
|
} catch {}
|
|
6968
7197
|
try {
|
|
6969
|
-
const currentDir =
|
|
7198
|
+
const currentDir = path5.dirname(fileURLToPath(import.meta.url));
|
|
6970
7199
|
const pkgPath = findPackageJsonUp(currentDir);
|
|
6971
7200
|
if (pkgPath) {
|
|
6972
|
-
const content =
|
|
7201
|
+
const content = fs3.readFileSync(pkgPath, "utf-8");
|
|
6973
7202
|
const pkg = JSON.parse(content);
|
|
6974
7203
|
if (pkg.version)
|
|
6975
7204
|
return pkg.version;
|
|
@@ -6981,7 +7210,7 @@ function getCachedVersion() {
|
|
|
6981
7210
|
}
|
|
6982
7211
|
function updatePinnedVersion(configPath, oldEntry, newVersion) {
|
|
6983
7212
|
try {
|
|
6984
|
-
const content =
|
|
7213
|
+
const content = fs3.readFileSync(configPath, "utf-8");
|
|
6985
7214
|
const newEntry = `${PACKAGE_NAME2}@${newVersion}`;
|
|
6986
7215
|
const pluginMatch = content.match(/"plugin"\s*:\s*\[/);
|
|
6987
7216
|
if (!pluginMatch || pluginMatch.index === undefined) {
|
|
@@ -7013,7 +7242,7 @@ function updatePinnedVersion(configPath, oldEntry, newVersion) {
|
|
|
7013
7242
|
log(`[auto-update-checker] No changes made to ${configPath}`);
|
|
7014
7243
|
return false;
|
|
7015
7244
|
}
|
|
7016
|
-
|
|
7245
|
+
fs3.writeFileSync(configPath, updatedContent, "utf-8");
|
|
7017
7246
|
log(`[auto-update-checker] Updated ${configPath}: ${oldEntry} \u2192 ${newEntry}`);
|
|
7018
7247
|
return true;
|
|
7019
7248
|
} catch (err) {
|
|
@@ -7672,7 +7901,7 @@ var import_picocolors2 = __toESM(require_picocolors(), 1);
|
|
|
7672
7901
|
// package.json
|
|
7673
7902
|
var package_default = {
|
|
7674
7903
|
name: "oh-my-opencode",
|
|
7675
|
-
version: "3.0.
|
|
7904
|
+
version: "3.0.1",
|
|
7676
7905
|
description: "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
|
|
7677
7906
|
main: "dist/index.js",
|
|
7678
7907
|
types: "dist/index.d.ts",
|
|
@@ -7728,18 +7957,14 @@ var package_default = {
|
|
|
7728
7957
|
"@clack/prompts": "^0.11.0",
|
|
7729
7958
|
"@code-yeongyu/comment-checker": "^0.6.1",
|
|
7730
7959
|
"@modelcontextprotocol/sdk": "^1.25.1",
|
|
7731
|
-
"@openauthjs/openauth": "^0.4.3",
|
|
7732
7960
|
"@opencode-ai/plugin": "^1.1.19",
|
|
7733
7961
|
"@opencode-ai/sdk": "^1.1.19",
|
|
7734
7962
|
commander: "^14.0.2",
|
|
7735
7963
|
"detect-libc": "^2.0.0",
|
|
7736
|
-
hono: "^4.10.4",
|
|
7737
7964
|
"js-yaml": "^4.1.1",
|
|
7738
7965
|
"jsonc-parser": "^3.3.1",
|
|
7739
|
-
open: "^11.0.0",
|
|
7740
7966
|
picocolors: "^1.1.1",
|
|
7741
7967
|
picomatch: "^4.0.2",
|
|
7742
|
-
"xdg-basedir": "^5.1.0",
|
|
7743
7968
|
zod: "^4.1.8"
|
|
7744
7969
|
},
|
|
7745
7970
|
devDependencies: {
|
|
@@ -7749,13 +7974,13 @@ var package_default = {
|
|
|
7749
7974
|
typescript: "^5.7.3"
|
|
7750
7975
|
},
|
|
7751
7976
|
optionalDependencies: {
|
|
7752
|
-
"oh-my-opencode-darwin-arm64": "3.0.
|
|
7753
|
-
"oh-my-opencode-darwin-x64": "3.0.
|
|
7754
|
-
"oh-my-opencode-linux-arm64": "3.0.
|
|
7755
|
-
"oh-my-opencode-linux-arm64-musl": "3.0.
|
|
7756
|
-
"oh-my-opencode-linux-x64": "3.0.
|
|
7757
|
-
"oh-my-opencode-linux-x64-musl": "3.0.
|
|
7758
|
-
"oh-my-opencode-windows-x64": "3.0.
|
|
7977
|
+
"oh-my-opencode-darwin-arm64": "3.0.1",
|
|
7978
|
+
"oh-my-opencode-darwin-x64": "3.0.1",
|
|
7979
|
+
"oh-my-opencode-linux-arm64": "3.0.1",
|
|
7980
|
+
"oh-my-opencode-linux-arm64-musl": "3.0.1",
|
|
7981
|
+
"oh-my-opencode-linux-x64": "3.0.1",
|
|
7982
|
+
"oh-my-opencode-linux-x64-musl": "3.0.1",
|
|
7983
|
+
"oh-my-opencode-windows-x64": "3.0.1"
|
|
7759
7984
|
},
|
|
7760
7985
|
trustedDependencies: [
|
|
7761
7986
|
"@ast-grep/cli",
|
|
@@ -7767,13 +7992,13 @@ var package_default = {
|
|
|
7767
7992
|
// src/cli/install.ts
|
|
7768
7993
|
var VERSION = package_default.version;
|
|
7769
7994
|
var SYMBOLS = {
|
|
7770
|
-
check: import_picocolors2.default.green("
|
|
7771
|
-
cross: import_picocolors2.default.red("
|
|
7772
|
-
arrow: import_picocolors2.default.cyan("
|
|
7773
|
-
bullet: import_picocolors2.default.dim("
|
|
7774
|
-
info: import_picocolors2.default.blue("
|
|
7775
|
-
warn: import_picocolors2.default.yellow("
|
|
7776
|
-
star: import_picocolors2.default.yellow("
|
|
7995
|
+
check: import_picocolors2.default.green("[OK]"),
|
|
7996
|
+
cross: import_picocolors2.default.red("[X]"),
|
|
7997
|
+
arrow: import_picocolors2.default.cyan("->"),
|
|
7998
|
+
bullet: import_picocolors2.default.dim("*"),
|
|
7999
|
+
info: import_picocolors2.default.blue("[i]"),
|
|
8000
|
+
warn: import_picocolors2.default.yellow("[!]"),
|
|
8001
|
+
star: import_picocolors2.default.yellow("*")
|
|
7777
8002
|
};
|
|
7778
8003
|
function formatProvider(name, enabled, detail) {
|
|
7779
8004
|
const status = enabled ? SYMBOLS.check : import_picocolors2.default.dim("\u25CB");
|
|
@@ -7787,22 +8012,18 @@ function formatConfigSummary(config) {
|
|
|
7787
8012
|
lines.push("");
|
|
7788
8013
|
const claudeDetail = config.hasClaude ? config.isMax20 ? "max20" : "standard" : undefined;
|
|
7789
8014
|
lines.push(formatProvider("Claude", config.hasClaude, claudeDetail));
|
|
7790
|
-
lines.push(formatProvider("ChatGPT", config.
|
|
8015
|
+
lines.push(formatProvider("OpenAI/ChatGPT", config.hasOpenAI, "GPT-5.2 for Oracle"));
|
|
7791
8016
|
lines.push(formatProvider("Gemini", config.hasGemini));
|
|
7792
|
-
lines.push(formatProvider("GitHub Copilot", config.hasCopilot, "fallback
|
|
8017
|
+
lines.push(formatProvider("GitHub Copilot", config.hasCopilot, "fallback"));
|
|
8018
|
+
lines.push(formatProvider("OpenCode Zen", config.hasOpencodeZen, "opencode/ models"));
|
|
8019
|
+
lines.push(formatProvider("Z.ai Coding Plan", config.hasZaiCodingPlan, "Librarian/Multimodal"));
|
|
7793
8020
|
lines.push("");
|
|
7794
8021
|
lines.push(import_picocolors2.default.dim("\u2500".repeat(40)));
|
|
7795
8022
|
lines.push("");
|
|
7796
|
-
lines.push(import_picocolors2.default.bold(import_picocolors2.default.white("
|
|
8023
|
+
lines.push(import_picocolors2.default.bold(import_picocolors2.default.white("Model Assignment")));
|
|
7797
8024
|
lines.push("");
|
|
7798
|
-
|
|
7799
|
-
|
|
7800
|
-
const librarianModel = "glm-4.7-free";
|
|
7801
|
-
const frontendModel = config.hasGemini ? "antigravity-gemini-3-pro-high" : config.hasClaude ? "claude-opus-4-5" : "glm-4.7-free";
|
|
7802
|
-
lines.push(` ${SYMBOLS.bullet} Sisyphus ${SYMBOLS.arrow} ${import_picocolors2.default.cyan(sisyphusModel)}`);
|
|
7803
|
-
lines.push(` ${SYMBOLS.bullet} Oracle ${SYMBOLS.arrow} ${import_picocolors2.default.cyan(oracleModel)}`);
|
|
7804
|
-
lines.push(` ${SYMBOLS.bullet} Librarian ${SYMBOLS.arrow} ${import_picocolors2.default.cyan(librarianModel)}`);
|
|
7805
|
-
lines.push(` ${SYMBOLS.bullet} Frontend ${SYMBOLS.arrow} ${import_picocolors2.default.cyan(frontendModel)}`);
|
|
8025
|
+
lines.push(` ${SYMBOLS.info} Models auto-configured based on provider priority`);
|
|
8026
|
+
lines.push(` ${SYMBOLS.bullet} Priority: Native > Copilot > OpenCode Zen > Z.ai`);
|
|
7806
8027
|
return lines.join(`
|
|
7807
8028
|
`);
|
|
7808
8029
|
}
|
|
@@ -7854,11 +8075,6 @@ function validateNonTuiArgs(args) {
|
|
|
7854
8075
|
} else if (!["no", "yes", "max20"].includes(args.claude)) {
|
|
7855
8076
|
errors.push(`Invalid --claude value: ${args.claude} (expected: no, yes, max20)`);
|
|
7856
8077
|
}
|
|
7857
|
-
if (args.chatgpt === undefined) {
|
|
7858
|
-
errors.push("--chatgpt is required (values: no, yes)");
|
|
7859
|
-
} else if (!["no", "yes"].includes(args.chatgpt)) {
|
|
7860
|
-
errors.push(`Invalid --chatgpt value: ${args.chatgpt} (expected: no, yes)`);
|
|
7861
|
-
}
|
|
7862
8078
|
if (args.gemini === undefined) {
|
|
7863
8079
|
errors.push("--gemini is required (values: no, yes)");
|
|
7864
8080
|
} else if (!["no", "yes"].includes(args.gemini)) {
|
|
@@ -7869,15 +8085,26 @@ function validateNonTuiArgs(args) {
|
|
|
7869
8085
|
} else if (!["no", "yes"].includes(args.copilot)) {
|
|
7870
8086
|
errors.push(`Invalid --copilot value: ${args.copilot} (expected: no, yes)`);
|
|
7871
8087
|
}
|
|
8088
|
+
if (args.openai !== undefined && !["no", "yes"].includes(args.openai)) {
|
|
8089
|
+
errors.push(`Invalid --openai value: ${args.openai} (expected: no, yes)`);
|
|
8090
|
+
}
|
|
8091
|
+
if (args.opencodeZen !== undefined && !["no", "yes"].includes(args.opencodeZen)) {
|
|
8092
|
+
errors.push(`Invalid --opencode-zen value: ${args.opencodeZen} (expected: no, yes)`);
|
|
8093
|
+
}
|
|
8094
|
+
if (args.zaiCodingPlan !== undefined && !["no", "yes"].includes(args.zaiCodingPlan)) {
|
|
8095
|
+
errors.push(`Invalid --zai-coding-plan value: ${args.zaiCodingPlan} (expected: no, yes)`);
|
|
8096
|
+
}
|
|
7872
8097
|
return { valid: errors.length === 0, errors };
|
|
7873
8098
|
}
|
|
7874
8099
|
function argsToConfig(args) {
|
|
7875
8100
|
return {
|
|
7876
8101
|
hasClaude: args.claude !== "no",
|
|
7877
8102
|
isMax20: args.claude === "max20",
|
|
7878
|
-
|
|
8103
|
+
hasOpenAI: args.openai === "yes",
|
|
7879
8104
|
hasGemini: args.gemini === "yes",
|
|
7880
|
-
hasCopilot: args.copilot === "yes"
|
|
8105
|
+
hasCopilot: args.copilot === "yes",
|
|
8106
|
+
hasOpencodeZen: args.opencodeZen === "yes",
|
|
8107
|
+
hasZaiCodingPlan: args.zaiCodingPlan === "yes"
|
|
7881
8108
|
};
|
|
7882
8109
|
}
|
|
7883
8110
|
function detectedToInitialValues(detected) {
|
|
@@ -7887,9 +8114,11 @@ function detectedToInitialValues(detected) {
|
|
|
7887
8114
|
}
|
|
7888
8115
|
return {
|
|
7889
8116
|
claude,
|
|
7890
|
-
|
|
8117
|
+
openai: detected.hasOpenAI ? "yes" : "no",
|
|
7891
8118
|
gemini: detected.hasGemini ? "yes" : "no",
|
|
7892
|
-
copilot: detected.hasCopilot ? "yes" : "no"
|
|
8119
|
+
copilot: detected.hasCopilot ? "yes" : "no",
|
|
8120
|
+
opencodeZen: detected.hasOpencodeZen ? "yes" : "no",
|
|
8121
|
+
zaiCodingPlan: detected.hasZaiCodingPlan ? "yes" : "no"
|
|
7893
8122
|
};
|
|
7894
8123
|
}
|
|
7895
8124
|
async function runTuiMode(detected) {
|
|
@@ -7897,7 +8126,7 @@ async function runTuiMode(detected) {
|
|
|
7897
8126
|
const claude = await ve({
|
|
7898
8127
|
message: "Do you have a Claude Pro/Max subscription?",
|
|
7899
8128
|
options: [
|
|
7900
|
-
{ value: "no", label: "No", hint: "Will use opencode/
|
|
8129
|
+
{ value: "no", label: "No", hint: "Will use opencode/big-pickle as fallback" },
|
|
7901
8130
|
{ value: "yes", label: "Yes (standard)", hint: "Claude Opus 4.5 for orchestration" },
|
|
7902
8131
|
{ value: "max20", label: "Yes (max20 mode)", hint: "Full power with Claude Sonnet 4.5 for Librarian" }
|
|
7903
8132
|
],
|
|
@@ -7907,15 +8136,15 @@ async function runTuiMode(detected) {
|
|
|
7907
8136
|
xe("Installation cancelled.");
|
|
7908
8137
|
return null;
|
|
7909
8138
|
}
|
|
7910
|
-
const
|
|
7911
|
-
message: "Do you have
|
|
8139
|
+
const openai = await ve({
|
|
8140
|
+
message: "Do you have an OpenAI/ChatGPT Plus subscription?",
|
|
7912
8141
|
options: [
|
|
7913
|
-
{ value: "no", label: "No", hint: "Oracle will use fallback
|
|
7914
|
-
{ value: "yes", label: "Yes", hint: "GPT-5.2 for
|
|
8142
|
+
{ value: "no", label: "No", hint: "Oracle will use fallback models" },
|
|
8143
|
+
{ value: "yes", label: "Yes", hint: "GPT-5.2 for Oracle (high-IQ debugging)" }
|
|
7915
8144
|
],
|
|
7916
|
-
initialValue: initial.
|
|
8145
|
+
initialValue: initial.openai
|
|
7917
8146
|
});
|
|
7918
|
-
if (pD(
|
|
8147
|
+
if (pD(openai)) {
|
|
7919
8148
|
xe("Installation cancelled.");
|
|
7920
8149
|
return null;
|
|
7921
8150
|
}
|
|
@@ -7943,12 +8172,38 @@ async function runTuiMode(detected) {
|
|
|
7943
8172
|
xe("Installation cancelled.");
|
|
7944
8173
|
return null;
|
|
7945
8174
|
}
|
|
8175
|
+
const opencodeZen = await ve({
|
|
8176
|
+
message: "Do you have access to OpenCode Zen (opencode/ models)?",
|
|
8177
|
+
options: [
|
|
8178
|
+
{ value: "no", label: "No", hint: "Will use other configured providers" },
|
|
8179
|
+
{ value: "yes", label: "Yes", hint: "opencode/claude-opus-4-5, opencode/gpt-5.2, etc." }
|
|
8180
|
+
],
|
|
8181
|
+
initialValue: initial.opencodeZen
|
|
8182
|
+
});
|
|
8183
|
+
if (pD(opencodeZen)) {
|
|
8184
|
+
xe("Installation cancelled.");
|
|
8185
|
+
return null;
|
|
8186
|
+
}
|
|
8187
|
+
const zaiCodingPlan = await ve({
|
|
8188
|
+
message: "Do you have a Z.ai Coding Plan subscription?",
|
|
8189
|
+
options: [
|
|
8190
|
+
{ value: "no", label: "No", hint: "Will use other configured providers" },
|
|
8191
|
+
{ value: "yes", label: "Yes", hint: "Fallback for Librarian and Multimodal Looker" }
|
|
8192
|
+
],
|
|
8193
|
+
initialValue: initial.zaiCodingPlan
|
|
8194
|
+
});
|
|
8195
|
+
if (pD(zaiCodingPlan)) {
|
|
8196
|
+
xe("Installation cancelled.");
|
|
8197
|
+
return null;
|
|
8198
|
+
}
|
|
7946
8199
|
return {
|
|
7947
8200
|
hasClaude: claude !== "no",
|
|
7948
8201
|
isMax20: claude === "max20",
|
|
7949
|
-
|
|
8202
|
+
hasOpenAI: openai === "yes",
|
|
7950
8203
|
hasGemini: gemini === "yes",
|
|
7951
|
-
hasCopilot: copilot === "yes"
|
|
8204
|
+
hasCopilot: copilot === "yes",
|
|
8205
|
+
hasOpencodeZen: opencodeZen === "yes",
|
|
8206
|
+
hasZaiCodingPlan: zaiCodingPlan === "yes"
|
|
7952
8207
|
};
|
|
7953
8208
|
}
|
|
7954
8209
|
async function runNonTuiInstall(args) {
|
|
@@ -7960,7 +8215,7 @@ async function runNonTuiInstall(args) {
|
|
|
7960
8215
|
console.log(` ${SYMBOLS.bullet} ${err}`);
|
|
7961
8216
|
}
|
|
7962
8217
|
console.log();
|
|
7963
|
-
printInfo("Usage: bunx oh-my-opencode install --no-tui --claude=<no|yes|max20> --
|
|
8218
|
+
printInfo("Usage: bunx oh-my-opencode install --no-tui --claude=<no|yes|max20> --gemini=<no|yes> --copilot=<no|yes>");
|
|
7964
8219
|
console.log();
|
|
7965
8220
|
return 1;
|
|
7966
8221
|
}
|
|
@@ -7971,16 +8226,16 @@ async function runNonTuiInstall(args) {
|
|
|
7971
8226
|
let step = 1;
|
|
7972
8227
|
printStep(step++, totalSteps, "Checking OpenCode installation...");
|
|
7973
8228
|
const installed = await isOpenCodeInstalled();
|
|
8229
|
+
const version = await getOpenCodeVersion();
|
|
7974
8230
|
if (!installed) {
|
|
7975
|
-
|
|
8231
|
+
printWarning("OpenCode binary not found. Plugin will be configured, but you'll need to install OpenCode to use it.");
|
|
7976
8232
|
printInfo("Visit https://opencode.ai/docs for installation instructions");
|
|
7977
|
-
|
|
8233
|
+
} else {
|
|
8234
|
+
printSuccess(`OpenCode ${version ?? ""} detected`);
|
|
7978
8235
|
}
|
|
7979
|
-
const version = await getOpenCodeVersion();
|
|
7980
|
-
printSuccess(`OpenCode ${version ?? ""} detected`);
|
|
7981
8236
|
if (isUpdate) {
|
|
7982
8237
|
const initial = detectedToInitialValues(detected);
|
|
7983
|
-
printInfo(`Current config: Claude=${initial.claude},
|
|
8238
|
+
printInfo(`Current config: Claude=${initial.claude}, Gemini=${initial.gemini}`);
|
|
7984
8239
|
}
|
|
7985
8240
|
const config = argsToConfig(args);
|
|
7986
8241
|
printStep(step++, totalSteps, "Adding oh-my-opencode plugin...");
|
|
@@ -8016,26 +8271,38 @@ async function runNonTuiInstall(args) {
|
|
|
8016
8271
|
}
|
|
8017
8272
|
printSuccess(`Config written ${SYMBOLS.arrow} ${import_picocolors2.default.dim(omoResult.configPath)}`);
|
|
8018
8273
|
printBox(formatConfigSummary(config), isUpdate ? "Updated Configuration" : "Installation Complete");
|
|
8019
|
-
if (!config.hasClaude
|
|
8020
|
-
|
|
8274
|
+
if (!config.hasClaude) {
|
|
8275
|
+
console.log();
|
|
8276
|
+
console.log(import_picocolors2.default.bgRed(import_picocolors2.default.white(import_picocolors2.default.bold(" CRITICAL WARNING "))));
|
|
8277
|
+
console.log();
|
|
8278
|
+
console.log(import_picocolors2.default.red(import_picocolors2.default.bold(" Sisyphus agent is STRONGLY optimized for Claude Opus 4.5.")));
|
|
8279
|
+
console.log(import_picocolors2.default.red(" Without Claude, you may experience significantly degraded performance:"));
|
|
8280
|
+
console.log(import_picocolors2.default.dim(" \u2022 Reduced orchestration quality"));
|
|
8281
|
+
console.log(import_picocolors2.default.dim(" \u2022 Weaker tool selection and delegation"));
|
|
8282
|
+
console.log(import_picocolors2.default.dim(" \u2022 Less reliable task completion"));
|
|
8283
|
+
console.log();
|
|
8284
|
+
console.log(import_picocolors2.default.yellow(" Consider subscribing to Claude Pro/Max for the best experience."));
|
|
8285
|
+
console.log();
|
|
8286
|
+
}
|
|
8287
|
+
if (!config.hasClaude && !config.hasOpenAI && !config.hasGemini && !config.hasCopilot && !config.hasOpencodeZen) {
|
|
8288
|
+
printWarning("No model providers configured. Using opencode/big-pickle as fallback.");
|
|
8021
8289
|
}
|
|
8022
8290
|
console.log(`${SYMBOLS.star} ${import_picocolors2.default.bold(import_picocolors2.default.green(isUpdate ? "Configuration updated!" : "Installation complete!"))}`);
|
|
8023
8291
|
console.log(` Run ${import_picocolors2.default.cyan("opencode")} to start!`);
|
|
8024
8292
|
console.log();
|
|
8025
8293
|
printBox(`${import_picocolors2.default.bold("Pro Tip:")} Include ${import_picocolors2.default.cyan("ultrawork")} (or ${import_picocolors2.default.cyan("ulw")}) in your prompt.
|
|
8026
8294
|
` + `All features work like magic\u2014parallel agents, background tasks,
|
|
8027
|
-
` + `deep exploration, and relentless execution until completion.`, "
|
|
8295
|
+
` + `deep exploration, and relentless execution until completion.`, "The Magic Word");
|
|
8028
8296
|
console.log(`${SYMBOLS.star} ${import_picocolors2.default.yellow("If you found this helpful, consider starring the repo!")}`);
|
|
8029
8297
|
console.log(` ${import_picocolors2.default.dim("gh repo star code-yeongyu/oh-my-opencode")}`);
|
|
8030
8298
|
console.log();
|
|
8031
8299
|
console.log(import_picocolors2.default.dim("oMoMoMoMo... Enjoy!"));
|
|
8032
8300
|
console.log();
|
|
8033
|
-
if ((config.hasClaude || config.
|
|
8301
|
+
if ((config.hasClaude || config.hasGemini || config.hasCopilot) && !args.skipAuth) {
|
|
8034
8302
|
printBox(`Run ${import_picocolors2.default.cyan("opencode auth login")} and select your provider:
|
|
8035
8303
|
` + (config.hasClaude ? ` ${SYMBOLS.bullet} Anthropic ${import_picocolors2.default.gray("\u2192 Claude Pro/Max")}
|
|
8036
|
-
` : "") + (config.hasChatGPT ? ` ${SYMBOLS.bullet} OpenAI ${import_picocolors2.default.gray("\u2192 ChatGPT Plus/Pro")}
|
|
8037
8304
|
` : "") + (config.hasGemini ? ` ${SYMBOLS.bullet} Google ${import_picocolors2.default.gray("\u2192 OAuth with Antigravity")}
|
|
8038
|
-
` : "") + (config.hasCopilot ? ` ${SYMBOLS.bullet} GitHub ${import_picocolors2.default.gray("\u2192 Copilot")}` : ""), "
|
|
8305
|
+
` : "") + (config.hasCopilot ? ` ${SYMBOLS.bullet} GitHub ${import_picocolors2.default.gray("\u2192 Copilot")}` : ""), "Authenticate Your Providers");
|
|
8039
8306
|
}
|
|
8040
8307
|
return 0;
|
|
8041
8308
|
}
|
|
@@ -8048,20 +8315,19 @@ async function install(args) {
|
|
|
8048
8315
|
Ie(import_picocolors2.default.bgMagenta(import_picocolors2.default.white(isUpdate ? " oMoMoMoMo... Update " : " oMoMoMoMo... ")));
|
|
8049
8316
|
if (isUpdate) {
|
|
8050
8317
|
const initial = detectedToInitialValues(detected);
|
|
8051
|
-
M2.info(`Existing configuration detected: Claude=${initial.claude},
|
|
8318
|
+
M2.info(`Existing configuration detected: Claude=${initial.claude}, Gemini=${initial.gemini}`);
|
|
8052
8319
|
}
|
|
8053
8320
|
const s = Y2();
|
|
8054
8321
|
s.start("Checking OpenCode installation");
|
|
8055
8322
|
const installed = await isOpenCodeInstalled();
|
|
8323
|
+
const version = await getOpenCodeVersion();
|
|
8056
8324
|
if (!installed) {
|
|
8057
|
-
s.stop(
|
|
8058
|
-
M2.
|
|
8325
|
+
s.stop(`OpenCode binary not found ${import_picocolors2.default.yellow("[!]")}`);
|
|
8326
|
+
M2.warn("OpenCode binary not found. Plugin will be configured, but you'll need to install OpenCode to use it.");
|
|
8059
8327
|
Me("Visit https://opencode.ai/docs for installation instructions", "Installation Guide");
|
|
8060
|
-
|
|
8061
|
-
|
|
8328
|
+
} else {
|
|
8329
|
+
s.stop(`OpenCode ${version ?? "installed"} ${import_picocolors2.default.green("[OK]")}`);
|
|
8062
8330
|
}
|
|
8063
|
-
const version = await getOpenCodeVersion();
|
|
8064
|
-
s.stop(`OpenCode ${version ?? "installed"} ${import_picocolors2.default.green("\u2713")}`);
|
|
8065
8331
|
const config = await runTuiMode(detected);
|
|
8066
8332
|
if (!config)
|
|
8067
8333
|
return 1;
|
|
@@ -8099,30 +8365,41 @@ async function install(args) {
|
|
|
8099
8365
|
return 1;
|
|
8100
8366
|
}
|
|
8101
8367
|
s.stop(`Config written to ${import_picocolors2.default.cyan(omoResult.configPath)}`);
|
|
8102
|
-
if (!config.hasClaude
|
|
8103
|
-
|
|
8368
|
+
if (!config.hasClaude) {
|
|
8369
|
+
console.log();
|
|
8370
|
+
console.log(import_picocolors2.default.bgRed(import_picocolors2.default.white(import_picocolors2.default.bold(" CRITICAL WARNING "))));
|
|
8371
|
+
console.log();
|
|
8372
|
+
console.log(import_picocolors2.default.red(import_picocolors2.default.bold(" Sisyphus agent is STRONGLY optimized for Claude Opus 4.5.")));
|
|
8373
|
+
console.log(import_picocolors2.default.red(" Without Claude, you may experience significantly degraded performance:"));
|
|
8374
|
+
console.log(import_picocolors2.default.dim(" \u2022 Reduced orchestration quality"));
|
|
8375
|
+
console.log(import_picocolors2.default.dim(" \u2022 Weaker tool selection and delegation"));
|
|
8376
|
+
console.log(import_picocolors2.default.dim(" \u2022 Less reliable task completion"));
|
|
8377
|
+
console.log();
|
|
8378
|
+
console.log(import_picocolors2.default.yellow(" Consider subscribing to Claude Pro/Max for the best experience."));
|
|
8379
|
+
console.log();
|
|
8380
|
+
}
|
|
8381
|
+
if (!config.hasClaude && !config.hasOpenAI && !config.hasGemini && !config.hasCopilot && !config.hasOpencodeZen) {
|
|
8382
|
+
M2.warn("No model providers configured. Using opencode/big-pickle as fallback.");
|
|
8104
8383
|
}
|
|
8105
8384
|
Me(formatConfigSummary(config), isUpdate ? "Updated Configuration" : "Installation Complete");
|
|
8106
8385
|
M2.success(import_picocolors2.default.bold(isUpdate ? "Configuration updated!" : "Installation complete!"));
|
|
8107
8386
|
M2.message(`Run ${import_picocolors2.default.cyan("opencode")} to start!`);
|
|
8108
8387
|
Me(`Include ${import_picocolors2.default.cyan("ultrawork")} (or ${import_picocolors2.default.cyan("ulw")}) in your prompt.
|
|
8109
8388
|
` + `All features work like magic\u2014parallel agents, background tasks,
|
|
8110
|
-
` + `deep exploration, and relentless execution until completion.`, "
|
|
8389
|
+
` + `deep exploration, and relentless execution until completion.`, "The Magic Word");
|
|
8111
8390
|
M2.message(`${import_picocolors2.default.yellow("\u2605")} If you found this helpful, consider starring the repo!`);
|
|
8112
8391
|
M2.message(` ${import_picocolors2.default.dim("gh repo star code-yeongyu/oh-my-opencode")}`);
|
|
8113
8392
|
Se(import_picocolors2.default.green("oMoMoMoMo... Enjoy!"));
|
|
8114
|
-
if ((config.hasClaude || config.
|
|
8393
|
+
if ((config.hasClaude || config.hasGemini || config.hasCopilot) && !args.skipAuth) {
|
|
8115
8394
|
const providers = [];
|
|
8116
8395
|
if (config.hasClaude)
|
|
8117
8396
|
providers.push(`Anthropic ${import_picocolors2.default.gray("\u2192 Claude Pro/Max")}`);
|
|
8118
|
-
if (config.hasChatGPT)
|
|
8119
|
-
providers.push(`OpenAI ${import_picocolors2.default.gray("\u2192 ChatGPT Plus/Pro")}`);
|
|
8120
8397
|
if (config.hasGemini)
|
|
8121
8398
|
providers.push(`Google ${import_picocolors2.default.gray("\u2192 OAuth with Antigravity")}`);
|
|
8122
8399
|
if (config.hasCopilot)
|
|
8123
8400
|
providers.push(`GitHub ${import_picocolors2.default.gray("\u2192 Copilot")}`);
|
|
8124
8401
|
console.log();
|
|
8125
|
-
console.log(import_picocolors2.default.bold("
|
|
8402
|
+
console.log(import_picocolors2.default.bold("Authenticate Your Providers"));
|
|
8126
8403
|
console.log();
|
|
8127
8404
|
console.log(` Run ${import_picocolors2.default.cyan("opencode auth login")} and select:`);
|
|
8128
8405
|
for (const provider of providers) {
|
|
@@ -8366,7 +8643,7 @@ var serializeObjectParam = ({ allowReserved, explode, name, style, value, valueO
|
|
|
8366
8643
|
|
|
8367
8644
|
// node_modules/@opencode-ai/sdk/dist/gen/core/utils.gen.js
|
|
8368
8645
|
var PATH_PARAM_RE = /\{[^{}]+\}/g;
|
|
8369
|
-
var defaultPathSerializer = ({ path:
|
|
8646
|
+
var defaultPathSerializer = ({ path: path3, url: _url }) => {
|
|
8370
8647
|
let url = _url;
|
|
8371
8648
|
const matches = _url.match(PATH_PARAM_RE);
|
|
8372
8649
|
if (matches) {
|
|
@@ -8385,7 +8662,7 @@ var defaultPathSerializer = ({ path: path2, url: _url }) => {
|
|
|
8385
8662
|
name = name.substring(1);
|
|
8386
8663
|
style = "matrix";
|
|
8387
8664
|
}
|
|
8388
|
-
const value =
|
|
8665
|
+
const value = path3[name];
|
|
8389
8666
|
if (value === undefined || value === null) {
|
|
8390
8667
|
continue;
|
|
8391
8668
|
}
|
|
@@ -8416,11 +8693,11 @@ var defaultPathSerializer = ({ path: path2, url: _url }) => {
|
|
|
8416
8693
|
}
|
|
8417
8694
|
return url;
|
|
8418
8695
|
};
|
|
8419
|
-
var getUrl = ({ baseUrl, path:
|
|
8696
|
+
var getUrl = ({ baseUrl, path: path3, query, querySerializer, url: _url }) => {
|
|
8420
8697
|
const pathUrl = _url.startsWith("/") ? _url : `/${_url}`;
|
|
8421
8698
|
let url = (baseUrl ?? "") + pathUrl;
|
|
8422
|
-
if (
|
|
8423
|
-
url = defaultPathSerializer({ path:
|
|
8699
|
+
if (path3) {
|
|
8700
|
+
url = defaultPathSerializer({ path: path3, url });
|
|
8424
8701
|
}
|
|
8425
8702
|
let search = query ? querySerializer(query) : "";
|
|
8426
8703
|
if (search.startsWith("?")) {
|
|
@@ -9736,7 +10013,7 @@ function logEventVerbose(ctx, payload) {
|
|
|
9736
10013
|
const toolName = toolProps?.name ?? "unknown";
|
|
9737
10014
|
const input = toolProps?.input ?? {};
|
|
9738
10015
|
const inputStr = JSON.stringify(input).slice(0, 150);
|
|
9739
|
-
console.error(import_picocolors4.default.cyan(`${sessionTag}
|
|
10016
|
+
console.error(import_picocolors4.default.cyan(`${sessionTag} TOOL.EXECUTE: ${import_picocolors4.default.bold(toolName)}`));
|
|
9740
10017
|
console.error(import_picocolors4.default.dim(` input: ${inputStr}${inputStr.length >= 150 ? "..." : ""}`));
|
|
9741
10018
|
break;
|
|
9742
10019
|
}
|
|
@@ -9744,13 +10021,13 @@ function logEventVerbose(ctx, payload) {
|
|
|
9744
10021
|
const resultProps = props;
|
|
9745
10022
|
const output = resultProps?.output ?? "";
|
|
9746
10023
|
const preview = output.slice(0, 200).replace(/\n/g, "\\n");
|
|
9747
|
-
console.error(import_picocolors4.default.green(`${sessionTag}
|
|
10024
|
+
console.error(import_picocolors4.default.green(`${sessionTag} TOOL.RESULT: "${preview}${output.length > 200 ? "..." : ""}"`));
|
|
9748
10025
|
break;
|
|
9749
10026
|
}
|
|
9750
10027
|
case "session.error": {
|
|
9751
10028
|
const errorProps = props;
|
|
9752
10029
|
const errorMsg = serializeError(errorProps?.error);
|
|
9753
|
-
console.error(import_picocolors4.default.red(`${sessionTag}
|
|
10030
|
+
console.error(import_picocolors4.default.red(`${sessionTag} SESSION.ERROR: ${errorMsg}`));
|
|
9754
10031
|
break;
|
|
9755
10032
|
}
|
|
9756
10033
|
default:
|
|
@@ -9844,7 +10121,7 @@ function handleToolExecute(ctx, payload, state) {
|
|
|
9844
10121
|
}
|
|
9845
10122
|
}
|
|
9846
10123
|
process.stdout.write(`
|
|
9847
|
-
${import_picocolors4.default.cyan("
|
|
10124
|
+
${import_picocolors4.default.cyan(">")} ${import_picocolors4.default.bold(toolName)}${inputPreview}
|
|
9848
10125
|
`);
|
|
9849
10126
|
}
|
|
9850
10127
|
function handleToolResult(ctx, payload, state) {
|
|
@@ -9870,6 +10147,8 @@ function handleToolResult(ctx, payload, state) {
|
|
|
9870
10147
|
// src/cli/run/runner.ts
|
|
9871
10148
|
var POLL_INTERVAL_MS = 500;
|
|
9872
10149
|
var DEFAULT_TIMEOUT_MS = 0;
|
|
10150
|
+
var SESSION_CREATE_MAX_RETRIES = 3;
|
|
10151
|
+
var SESSION_CREATE_RETRY_DELAY_MS = 1000;
|
|
9873
10152
|
async function run(options) {
|
|
9874
10153
|
const {
|
|
9875
10154
|
message,
|
|
@@ -9903,12 +10182,39 @@ Interrupted. Shutting down...`));
|
|
|
9903
10182
|
process.exit(130);
|
|
9904
10183
|
});
|
|
9905
10184
|
try {
|
|
9906
|
-
|
|
9907
|
-
|
|
9908
|
-
|
|
9909
|
-
|
|
10185
|
+
let sessionID;
|
|
10186
|
+
let lastError;
|
|
10187
|
+
for (let attempt = 1;attempt <= SESSION_CREATE_MAX_RETRIES; attempt++) {
|
|
10188
|
+
const sessionRes = await client3.session.create({
|
|
10189
|
+
body: { title: "oh-my-opencode run" }
|
|
10190
|
+
});
|
|
10191
|
+
if (sessionRes.error) {
|
|
10192
|
+
lastError = sessionRes.error;
|
|
10193
|
+
console.error(import_picocolors5.default.yellow(`Session create attempt ${attempt}/${SESSION_CREATE_MAX_RETRIES} failed:`));
|
|
10194
|
+
console.error(import_picocolors5.default.dim(` Error: ${serializeError(sessionRes.error)}`));
|
|
10195
|
+
if (attempt < SESSION_CREATE_MAX_RETRIES) {
|
|
10196
|
+
const delay = SESSION_CREATE_RETRY_DELAY_MS * attempt;
|
|
10197
|
+
console.log(import_picocolors5.default.dim(` Retrying in ${delay}ms...`));
|
|
10198
|
+
await new Promise((resolve2) => setTimeout(resolve2, delay));
|
|
10199
|
+
continue;
|
|
10200
|
+
}
|
|
10201
|
+
}
|
|
10202
|
+
sessionID = sessionRes.data?.id;
|
|
10203
|
+
if (sessionID) {
|
|
10204
|
+
break;
|
|
10205
|
+
}
|
|
10206
|
+
lastError = new Error(`Unexpected response: ${JSON.stringify(sessionRes, null, 2)}`);
|
|
10207
|
+
console.error(import_picocolors5.default.yellow(`Session create attempt ${attempt}/${SESSION_CREATE_MAX_RETRIES}: No session ID returned`));
|
|
10208
|
+
if (attempt < SESSION_CREATE_MAX_RETRIES) {
|
|
10209
|
+
const delay = SESSION_CREATE_RETRY_DELAY_MS * attempt;
|
|
10210
|
+
console.log(import_picocolors5.default.dim(` Retrying in ${delay}ms...`));
|
|
10211
|
+
await new Promise((resolve2) => setTimeout(resolve2, delay));
|
|
10212
|
+
}
|
|
10213
|
+
}
|
|
9910
10214
|
if (!sessionID) {
|
|
9911
|
-
console.error(import_picocolors5.default.red("Failed to create session"));
|
|
10215
|
+
console.error(import_picocolors5.default.red("Failed to create session after all retries"));
|
|
10216
|
+
console.error(import_picocolors5.default.dim(`Last error: ${serializeError(lastError)}`));
|
|
10217
|
+
cleanup();
|
|
9912
10218
|
return 1;
|
|
9913
10219
|
}
|
|
9914
10220
|
console.log(import_picocolors5.default.dim(`Session: ${sessionID}`));
|
|
@@ -9978,13 +10284,13 @@ init_checker();
|
|
|
9978
10284
|
// src/cli/get-local-version/formatter.ts
|
|
9979
10285
|
var import_picocolors6 = __toESM(require_picocolors(), 1);
|
|
9980
10286
|
var SYMBOLS2 = {
|
|
9981
|
-
check: import_picocolors6.default.green("
|
|
9982
|
-
cross: import_picocolors6.default.red("
|
|
9983
|
-
arrow: import_picocolors6.default.cyan("
|
|
9984
|
-
info: import_picocolors6.default.blue("
|
|
9985
|
-
warn: import_picocolors6.default.yellow("
|
|
9986
|
-
pin: import_picocolors6.default.magenta("
|
|
9987
|
-
dev: import_picocolors6.default.cyan("
|
|
10287
|
+
check: import_picocolors6.default.green("[OK]"),
|
|
10288
|
+
cross: import_picocolors6.default.red("[X]"),
|
|
10289
|
+
arrow: import_picocolors6.default.cyan("->"),
|
|
10290
|
+
info: import_picocolors6.default.blue("[i]"),
|
|
10291
|
+
warn: import_picocolors6.default.yellow("[!]"),
|
|
10292
|
+
pin: import_picocolors6.default.magenta("[PINNED]"),
|
|
10293
|
+
dev: import_picocolors6.default.cyan("[DEV]")
|
|
9988
10294
|
};
|
|
9989
10295
|
function formatVersionOutput(info) {
|
|
9990
10296
|
const lines = [];
|
|
@@ -10143,6 +10449,7 @@ var CHECK_IDS = {
|
|
|
10143
10449
|
OPENCODE_INSTALLATION: "opencode-installation",
|
|
10144
10450
|
PLUGIN_REGISTRATION: "plugin-registration",
|
|
10145
10451
|
CONFIG_VALIDATION: "config-validation",
|
|
10452
|
+
MODEL_RESOLUTION: "model-resolution",
|
|
10146
10453
|
AUTH_ANTHROPIC: "auth-anthropic",
|
|
10147
10454
|
AUTH_OPENAI: "auth-openai",
|
|
10148
10455
|
AUTH_GOOGLE: "auth-google",
|
|
@@ -10159,6 +10466,7 @@ var CHECK_NAMES = {
|
|
|
10159
10466
|
[CHECK_IDS.OPENCODE_INSTALLATION]: "OpenCode Installation",
|
|
10160
10467
|
[CHECK_IDS.PLUGIN_REGISTRATION]: "Plugin Registration",
|
|
10161
10468
|
[CHECK_IDS.CONFIG_VALIDATION]: "Configuration Validity",
|
|
10469
|
+
[CHECK_IDS.MODEL_RESOLUTION]: "Model Resolution",
|
|
10162
10470
|
[CHECK_IDS.AUTH_ANTHROPIC]: "Anthropic (Claude) Auth",
|
|
10163
10471
|
[CHECK_IDS.AUTH_OPENAI]: "OpenAI (ChatGPT) Auth",
|
|
10164
10472
|
[CHECK_IDS.AUTH_GOOGLE]: "Google (Gemini) Auth",
|
|
@@ -10200,9 +10508,9 @@ function selectBinaryPath(paths, platform) {
|
|
|
10200
10508
|
return null;
|
|
10201
10509
|
if (platform !== "win32")
|
|
10202
10510
|
return paths[0];
|
|
10203
|
-
const normalized = paths.map((
|
|
10511
|
+
const normalized = paths.map((path6) => path6.toLowerCase());
|
|
10204
10512
|
for (const ext of WINDOWS_EXECUTABLE_EXTS) {
|
|
10205
|
-
const index = normalized.findIndex((
|
|
10513
|
+
const index = normalized.findIndex((path6) => path6.endsWith(ext));
|
|
10206
10514
|
if (index !== -1)
|
|
10207
10515
|
return paths[index];
|
|
10208
10516
|
}
|
|
@@ -10334,7 +10642,7 @@ function getOpenCodeCheckDefinition() {
|
|
|
10334
10642
|
}
|
|
10335
10643
|
|
|
10336
10644
|
// src/cli/doctor/checks/plugin.ts
|
|
10337
|
-
import { existsSync as existsSync7, readFileSync as
|
|
10645
|
+
import { existsSync as existsSync7, readFileSync as readFileSync6 } from "fs";
|
|
10338
10646
|
init_shared();
|
|
10339
10647
|
function detectConfigPath() {
|
|
10340
10648
|
const paths = getOpenCodeConfigPaths({ binary: "opencode", version: null });
|
|
@@ -10353,6 +10661,9 @@ function findPluginEntry2(plugins) {
|
|
|
10353
10661
|
const version = isPinned ? plugin.split("@")[1] : null;
|
|
10354
10662
|
return { entry: plugin, isPinned, version };
|
|
10355
10663
|
}
|
|
10664
|
+
if (plugin.startsWith("file://") && plugin.includes(PACKAGE_NAME3)) {
|
|
10665
|
+
return { entry: plugin, isPinned: false, version: "local-dev" };
|
|
10666
|
+
}
|
|
10356
10667
|
}
|
|
10357
10668
|
return null;
|
|
10358
10669
|
}
|
|
@@ -10368,7 +10679,7 @@ function getPluginInfo() {
|
|
|
10368
10679
|
};
|
|
10369
10680
|
}
|
|
10370
10681
|
try {
|
|
10371
|
-
const content =
|
|
10682
|
+
const content = readFileSync6(configInfo.path, "utf-8");
|
|
10372
10683
|
const config = parseJsonc(content);
|
|
10373
10684
|
const plugins = config.plugin ?? [];
|
|
10374
10685
|
const pluginEntry = findPluginEntry2(plugins);
|
|
@@ -10442,9 +10753,8 @@ function getPluginCheckDefinition() {
|
|
|
10442
10753
|
}
|
|
10443
10754
|
|
|
10444
10755
|
// src/cli/doctor/checks/config.ts
|
|
10445
|
-
import { existsSync as existsSync8, readFileSync as
|
|
10446
|
-
import {
|
|
10447
|
-
import { join as join6 } from "path";
|
|
10756
|
+
import { existsSync as existsSync8, readFileSync as readFileSync7 } from "fs";
|
|
10757
|
+
import { join as join8 } from "path";
|
|
10448
10758
|
init_shared();
|
|
10449
10759
|
|
|
10450
10760
|
// node_modules/zod/v4/classic/external.js
|
|
@@ -11176,10 +11486,10 @@ function mergeDefs(...defs) {
|
|
|
11176
11486
|
function cloneDef(schema2) {
|
|
11177
11487
|
return mergeDefs(schema2._zod.def);
|
|
11178
11488
|
}
|
|
11179
|
-
function getElementAtPath(obj,
|
|
11180
|
-
if (!
|
|
11489
|
+
function getElementAtPath(obj, path6) {
|
|
11490
|
+
if (!path6)
|
|
11181
11491
|
return obj;
|
|
11182
|
-
return
|
|
11492
|
+
return path6.reduce((acc, key) => acc?.[key], obj);
|
|
11183
11493
|
}
|
|
11184
11494
|
function promiseAllObject(promisesObj) {
|
|
11185
11495
|
const keys = Object.keys(promisesObj);
|
|
@@ -11538,11 +11848,11 @@ function aborted(x2, startIndex = 0) {
|
|
|
11538
11848
|
}
|
|
11539
11849
|
return false;
|
|
11540
11850
|
}
|
|
11541
|
-
function prefixIssues(
|
|
11851
|
+
function prefixIssues(path6, issues) {
|
|
11542
11852
|
return issues.map((iss) => {
|
|
11543
11853
|
var _a;
|
|
11544
11854
|
(_a = iss).path ?? (_a.path = []);
|
|
11545
|
-
iss.path.unshift(
|
|
11855
|
+
iss.path.unshift(path6);
|
|
11546
11856
|
return iss;
|
|
11547
11857
|
});
|
|
11548
11858
|
}
|
|
@@ -11710,7 +12020,7 @@ function treeifyError(error, _mapper) {
|
|
|
11710
12020
|
return issue2.message;
|
|
11711
12021
|
};
|
|
11712
12022
|
const result = { errors: [] };
|
|
11713
|
-
const processError = (error2,
|
|
12023
|
+
const processError = (error2, path6 = []) => {
|
|
11714
12024
|
var _a, _b;
|
|
11715
12025
|
for (const issue2 of error2.issues) {
|
|
11716
12026
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
@@ -11720,7 +12030,7 @@ function treeifyError(error, _mapper) {
|
|
|
11720
12030
|
} else if (issue2.code === "invalid_element") {
|
|
11721
12031
|
processError({ issues: issue2.issues }, issue2.path);
|
|
11722
12032
|
} else {
|
|
11723
|
-
const fullpath = [...
|
|
12033
|
+
const fullpath = [...path6, ...issue2.path];
|
|
11724
12034
|
if (fullpath.length === 0) {
|
|
11725
12035
|
result.errors.push(mapper(issue2));
|
|
11726
12036
|
continue;
|
|
@@ -11752,8 +12062,8 @@ function treeifyError(error, _mapper) {
|
|
|
11752
12062
|
}
|
|
11753
12063
|
function toDotPath(_path) {
|
|
11754
12064
|
const segs = [];
|
|
11755
|
-
const
|
|
11756
|
-
for (const seg of
|
|
12065
|
+
const path6 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
12066
|
+
for (const seg of path6) {
|
|
11757
12067
|
if (typeof seg === "number")
|
|
11758
12068
|
segs.push(`[${seg}]`);
|
|
11759
12069
|
else if (typeof seg === "symbol")
|
|
@@ -22780,16 +23090,15 @@ var AgentPermissionSchema = exports_external.object({
|
|
|
22780
23090
|
external_directory: PermissionValue.optional()
|
|
22781
23091
|
});
|
|
22782
23092
|
var BuiltinAgentNameSchema = exports_external.enum([
|
|
22783
|
-
"
|
|
23093
|
+
"sisyphus",
|
|
23094
|
+
"prometheus",
|
|
22784
23095
|
"oracle",
|
|
22785
23096
|
"librarian",
|
|
22786
23097
|
"explore",
|
|
22787
|
-
"frontend-ui-ux-engineer",
|
|
22788
|
-
"document-writer",
|
|
22789
23098
|
"multimodal-looker",
|
|
22790
|
-
"
|
|
22791
|
-
"
|
|
22792
|
-
"
|
|
23099
|
+
"metis",
|
|
23100
|
+
"momus",
|
|
23101
|
+
"atlas"
|
|
22793
23102
|
]);
|
|
22794
23103
|
var BuiltinSkillNameSchema = exports_external.enum([
|
|
22795
23104
|
"playwright",
|
|
@@ -22799,19 +23108,17 @@ var BuiltinSkillNameSchema = exports_external.enum([
|
|
|
22799
23108
|
var OverridableAgentNameSchema = exports_external.enum([
|
|
22800
23109
|
"build",
|
|
22801
23110
|
"plan",
|
|
22802
|
-
"
|
|
22803
|
-
"
|
|
23111
|
+
"sisyphus",
|
|
23112
|
+
"sisyphus-junior",
|
|
22804
23113
|
"OpenCode-Builder",
|
|
22805
|
-
"
|
|
22806
|
-
"
|
|
22807
|
-
"
|
|
23114
|
+
"prometheus",
|
|
23115
|
+
"metis",
|
|
23116
|
+
"momus",
|
|
22808
23117
|
"oracle",
|
|
22809
23118
|
"librarian",
|
|
22810
23119
|
"explore",
|
|
22811
|
-
"frontend-ui-ux-engineer",
|
|
22812
|
-
"document-writer",
|
|
22813
23120
|
"multimodal-looker",
|
|
22814
|
-
"
|
|
23121
|
+
"atlas"
|
|
22815
23122
|
]);
|
|
22816
23123
|
var HookNameSchema = exports_external.enum([
|
|
22817
23124
|
"todo-continuation-enforcer",
|
|
@@ -22843,7 +23150,7 @@ var HookNameSchema = exports_external.enum([
|
|
|
22843
23150
|
"delegate-task-retry",
|
|
22844
23151
|
"prometheus-md-only",
|
|
22845
23152
|
"start-work",
|
|
22846
|
-
"
|
|
23153
|
+
"atlas"
|
|
22847
23154
|
]);
|
|
22848
23155
|
var BuiltinCommandNameSchema = exports_external.enum([
|
|
22849
23156
|
"init-deep",
|
|
@@ -22868,19 +23175,17 @@ var AgentOverrideConfigSchema = exports_external.object({
|
|
|
22868
23175
|
var AgentOverridesSchema = exports_external.object({
|
|
22869
23176
|
build: AgentOverrideConfigSchema.optional(),
|
|
22870
23177
|
plan: AgentOverrideConfigSchema.optional(),
|
|
22871
|
-
|
|
22872
|
-
"
|
|
23178
|
+
sisyphus: AgentOverrideConfigSchema.optional(),
|
|
23179
|
+
"sisyphus-junior": AgentOverrideConfigSchema.optional(),
|
|
22873
23180
|
"OpenCode-Builder": AgentOverrideConfigSchema.optional(),
|
|
22874
|
-
|
|
22875
|
-
|
|
22876
|
-
|
|
23181
|
+
prometheus: AgentOverrideConfigSchema.optional(),
|
|
23182
|
+
metis: AgentOverrideConfigSchema.optional(),
|
|
23183
|
+
momus: AgentOverrideConfigSchema.optional(),
|
|
22877
23184
|
oracle: AgentOverrideConfigSchema.optional(),
|
|
22878
23185
|
librarian: AgentOverrideConfigSchema.optional(),
|
|
22879
23186
|
explore: AgentOverrideConfigSchema.optional(),
|
|
22880
|
-
"frontend-ui-ux-engineer": AgentOverrideConfigSchema.optional(),
|
|
22881
|
-
"document-writer": AgentOverrideConfigSchema.optional(),
|
|
22882
23187
|
"multimodal-looker": AgentOverrideConfigSchema.optional(),
|
|
22883
|
-
|
|
23188
|
+
atlas: AgentOverrideConfigSchema.optional()
|
|
22884
23189
|
});
|
|
22885
23190
|
var ClaudeCodeConfigSchema = exports_external.object({
|
|
22886
23191
|
mcp: exports_external.boolean().optional(),
|
|
@@ -22898,7 +23203,8 @@ var SisyphusAgentConfigSchema = exports_external.object({
|
|
|
22898
23203
|
replace_plan: exports_external.boolean().optional()
|
|
22899
23204
|
});
|
|
22900
23205
|
var CategoryConfigSchema = exports_external.object({
|
|
22901
|
-
|
|
23206
|
+
description: exports_external.string().optional(),
|
|
23207
|
+
model: exports_external.string().optional(),
|
|
22902
23208
|
variant: exports_external.string().optional(),
|
|
22903
23209
|
temperature: exports_external.number().min(0).max(2).optional(),
|
|
22904
23210
|
top_p: exports_external.number().min(0).max(1).optional(),
|
|
@@ -22907,19 +23213,20 @@ var CategoryConfigSchema = exports_external.object({
|
|
|
22907
23213
|
type: exports_external.enum(["enabled", "disabled"]),
|
|
22908
23214
|
budgetTokens: exports_external.number().optional()
|
|
22909
23215
|
}).optional(),
|
|
22910
|
-
reasoningEffort: exports_external.enum(["low", "medium", "high"]).optional(),
|
|
23216
|
+
reasoningEffort: exports_external.enum(["low", "medium", "high", "xhigh"]).optional(),
|
|
22911
23217
|
textVerbosity: exports_external.enum(["low", "medium", "high"]).optional(),
|
|
22912
23218
|
tools: exports_external.record(exports_external.string(), exports_external.boolean()).optional(),
|
|
22913
|
-
prompt_append: exports_external.string().optional()
|
|
23219
|
+
prompt_append: exports_external.string().optional(),
|
|
23220
|
+
is_unstable_agent: exports_external.boolean().optional()
|
|
22914
23221
|
});
|
|
22915
23222
|
var BuiltinCategoryNameSchema = exports_external.enum([
|
|
22916
23223
|
"visual-engineering",
|
|
22917
23224
|
"ultrabrain",
|
|
22918
23225
|
"artistry",
|
|
22919
23226
|
"quick",
|
|
22920
|
-
"
|
|
22921
|
-
"
|
|
22922
|
-
"
|
|
23227
|
+
"unspecified-low",
|
|
23228
|
+
"unspecified-high",
|
|
23229
|
+
"writing"
|
|
22923
23230
|
]);
|
|
22924
23231
|
var CategoriesConfigSchema = exports_external.record(exports_external.string(), CategoryConfigSchema);
|
|
22925
23232
|
var CommentCheckerConfigSchema = exports_external.object({
|
|
@@ -23002,8 +23309,8 @@ var RalphLoopConfigSchema = exports_external.object({
|
|
|
23002
23309
|
});
|
|
23003
23310
|
var BackgroundTaskConfigSchema = exports_external.object({
|
|
23004
23311
|
defaultConcurrency: exports_external.number().min(1).optional(),
|
|
23005
|
-
providerConcurrency: exports_external.record(exports_external.string(), exports_external.number().min(
|
|
23006
|
-
modelConcurrency: exports_external.record(exports_external.string(), exports_external.number().min(
|
|
23312
|
+
providerConcurrency: exports_external.record(exports_external.string(), exports_external.number().min(0)).optional(),
|
|
23313
|
+
modelConcurrency: exports_external.record(exports_external.string(), exports_external.number().min(0)).optional(),
|
|
23007
23314
|
staleTimeoutMs: exports_external.number().min(60000).optional()
|
|
23008
23315
|
});
|
|
23009
23316
|
var NotificationConfigSchema = exports_external.object({
|
|
@@ -23034,9 +23341,9 @@ var OhMyOpenCodeConfigSchema = exports_external.object({
|
|
|
23034
23341
|
git_master: GitMasterConfigSchema.optional()
|
|
23035
23342
|
});
|
|
23036
23343
|
// src/cli/doctor/checks/config.ts
|
|
23037
|
-
var USER_CONFIG_DIR2 =
|
|
23038
|
-
var USER_CONFIG_BASE =
|
|
23039
|
-
var PROJECT_CONFIG_BASE =
|
|
23344
|
+
var USER_CONFIG_DIR2 = getOpenCodeConfigDir({ binary: "opencode" });
|
|
23345
|
+
var USER_CONFIG_BASE = join8(USER_CONFIG_DIR2, `${PACKAGE_NAME3}`);
|
|
23346
|
+
var PROJECT_CONFIG_BASE = join8(process.cwd(), ".opencode", PACKAGE_NAME3);
|
|
23040
23347
|
function findConfigPath() {
|
|
23041
23348
|
const projectDetected = detectConfigFile(PROJECT_CONFIG_BASE);
|
|
23042
23349
|
if (projectDetected.format !== "none") {
|
|
@@ -23050,7 +23357,7 @@ function findConfigPath() {
|
|
|
23050
23357
|
}
|
|
23051
23358
|
function validateConfig(configPath) {
|
|
23052
23359
|
try {
|
|
23053
|
-
const content =
|
|
23360
|
+
const content = readFileSync7(configPath, "utf-8");
|
|
23054
23361
|
const rawConfig = parseJsonc(content);
|
|
23055
23362
|
const result = OhMyOpenCodeConfigSchema.safeParse(rawConfig);
|
|
23056
23363
|
if (!result.success) {
|
|
@@ -23132,25 +23439,195 @@ function getConfigCheckDefinition() {
|
|
|
23132
23439
|
};
|
|
23133
23440
|
}
|
|
23134
23441
|
|
|
23442
|
+
// src/cli/doctor/checks/model-resolution.ts
|
|
23443
|
+
import { readFileSync as readFileSync8, existsSync as existsSync9 } from "fs";
|
|
23444
|
+
init_shared();
|
|
23445
|
+
init_model_requirements();
|
|
23446
|
+
import { homedir as homedir6 } from "os";
|
|
23447
|
+
import { join as join9 } from "path";
|
|
23448
|
+
function getOpenCodeCacheDir2() {
|
|
23449
|
+
const xdgCache = process.env.XDG_CACHE_HOME;
|
|
23450
|
+
if (xdgCache)
|
|
23451
|
+
return join9(xdgCache, "opencode");
|
|
23452
|
+
return join9(homedir6(), ".cache", "opencode");
|
|
23453
|
+
}
|
|
23454
|
+
function loadAvailableModels() {
|
|
23455
|
+
const cacheFile = join9(getOpenCodeCacheDir2(), "models.json");
|
|
23456
|
+
if (!existsSync9(cacheFile)) {
|
|
23457
|
+
return { providers: [], modelCount: 0, cacheExists: false };
|
|
23458
|
+
}
|
|
23459
|
+
try {
|
|
23460
|
+
const content = readFileSync8(cacheFile, "utf-8");
|
|
23461
|
+
const data = JSON.parse(content);
|
|
23462
|
+
const providers = Object.keys(data);
|
|
23463
|
+
let modelCount = 0;
|
|
23464
|
+
for (const providerId of providers) {
|
|
23465
|
+
const models = data[providerId]?.models;
|
|
23466
|
+
if (models && typeof models === "object") {
|
|
23467
|
+
modelCount += Object.keys(models).length;
|
|
23468
|
+
}
|
|
23469
|
+
}
|
|
23470
|
+
return { providers, modelCount, cacheExists: true };
|
|
23471
|
+
} catch {
|
|
23472
|
+
return { providers: [], modelCount: 0, cacheExists: false };
|
|
23473
|
+
}
|
|
23474
|
+
}
|
|
23475
|
+
var PACKAGE_NAME4 = "oh-my-opencode";
|
|
23476
|
+
var USER_CONFIG_DIR3 = join9(homedir6(), ".config", "opencode");
|
|
23477
|
+
var USER_CONFIG_BASE2 = join9(USER_CONFIG_DIR3, PACKAGE_NAME4);
|
|
23478
|
+
var PROJECT_CONFIG_BASE2 = join9(process.cwd(), ".opencode", PACKAGE_NAME4);
|
|
23479
|
+
function loadConfig() {
|
|
23480
|
+
const projectDetected = detectConfigFile(PROJECT_CONFIG_BASE2);
|
|
23481
|
+
if (projectDetected.format !== "none") {
|
|
23482
|
+
try {
|
|
23483
|
+
const content = readFileSync8(projectDetected.path, "utf-8");
|
|
23484
|
+
return parseJsonc(content);
|
|
23485
|
+
} catch {
|
|
23486
|
+
return null;
|
|
23487
|
+
}
|
|
23488
|
+
}
|
|
23489
|
+
const userDetected = detectConfigFile(USER_CONFIG_BASE2);
|
|
23490
|
+
if (userDetected.format !== "none") {
|
|
23491
|
+
try {
|
|
23492
|
+
const content = readFileSync8(userDetected.path, "utf-8");
|
|
23493
|
+
return parseJsonc(content);
|
|
23494
|
+
} catch {
|
|
23495
|
+
return null;
|
|
23496
|
+
}
|
|
23497
|
+
}
|
|
23498
|
+
return null;
|
|
23499
|
+
}
|
|
23500
|
+
function formatProviderChain(providers) {
|
|
23501
|
+
return providers.join(" \u2192 ");
|
|
23502
|
+
}
|
|
23503
|
+
function getEffectiveModel(requirement, userOverride) {
|
|
23504
|
+
if (userOverride) {
|
|
23505
|
+
return userOverride;
|
|
23506
|
+
}
|
|
23507
|
+
const firstEntry = requirement.fallbackChain[0];
|
|
23508
|
+
if (!firstEntry) {
|
|
23509
|
+
return "unknown";
|
|
23510
|
+
}
|
|
23511
|
+
return `${firstEntry.providers[0]}/${firstEntry.model}`;
|
|
23512
|
+
}
|
|
23513
|
+
function buildEffectiveResolution(requirement, userOverride) {
|
|
23514
|
+
if (userOverride) {
|
|
23515
|
+
return `User override: ${userOverride}`;
|
|
23516
|
+
}
|
|
23517
|
+
const firstEntry = requirement.fallbackChain[0];
|
|
23518
|
+
if (!firstEntry) {
|
|
23519
|
+
return "No fallback chain defined";
|
|
23520
|
+
}
|
|
23521
|
+
return `Provider fallback: ${formatProviderChain(firstEntry.providers)} \u2192 ${firstEntry.model}`;
|
|
23522
|
+
}
|
|
23523
|
+
function getModelResolutionInfoWithOverrides(config2) {
|
|
23524
|
+
const agents = Object.entries(AGENT_MODEL_REQUIREMENTS).map(([name, requirement]) => {
|
|
23525
|
+
const userOverride = config2.agents?.[name]?.model;
|
|
23526
|
+
return {
|
|
23527
|
+
name,
|
|
23528
|
+
requirement,
|
|
23529
|
+
userOverride,
|
|
23530
|
+
effectiveModel: getEffectiveModel(requirement, userOverride),
|
|
23531
|
+
effectiveResolution: buildEffectiveResolution(requirement, userOverride)
|
|
23532
|
+
};
|
|
23533
|
+
});
|
|
23534
|
+
const categories = Object.entries(CATEGORY_MODEL_REQUIREMENTS).map(([name, requirement]) => {
|
|
23535
|
+
const userOverride = config2.categories?.[name]?.model;
|
|
23536
|
+
return {
|
|
23537
|
+
name,
|
|
23538
|
+
requirement,
|
|
23539
|
+
userOverride,
|
|
23540
|
+
effectiveModel: getEffectiveModel(requirement, userOverride),
|
|
23541
|
+
effectiveResolution: buildEffectiveResolution(requirement, userOverride)
|
|
23542
|
+
};
|
|
23543
|
+
});
|
|
23544
|
+
return { agents, categories };
|
|
23545
|
+
}
|
|
23546
|
+
function formatModelWithVariant(model, variant) {
|
|
23547
|
+
return variant ? `${model} (${variant})` : model;
|
|
23548
|
+
}
|
|
23549
|
+
function getEffectiveVariant(requirement) {
|
|
23550
|
+
const firstEntry = requirement.fallbackChain[0];
|
|
23551
|
+
return firstEntry?.variant ?? requirement.variant;
|
|
23552
|
+
}
|
|
23553
|
+
function buildDetailsArray(info, available) {
|
|
23554
|
+
const details = [];
|
|
23555
|
+
details.push("\u2550\u2550\u2550 Available Models (from cache) \u2550\u2550\u2550");
|
|
23556
|
+
details.push("");
|
|
23557
|
+
if (available.cacheExists) {
|
|
23558
|
+
details.push(` Providers: ${available.providers.length} (${available.providers.slice(0, 8).join(", ")}${available.providers.length > 8 ? "..." : ""})`);
|
|
23559
|
+
details.push(` Total models: ${available.modelCount}`);
|
|
23560
|
+
details.push(` Cache: ~/.cache/opencode/models.json`);
|
|
23561
|
+
details.push(` Refresh: opencode models --refresh`);
|
|
23562
|
+
} else {
|
|
23563
|
+
details.push(" \u26A0 Cache not found. Run 'opencode' to populate.");
|
|
23564
|
+
}
|
|
23565
|
+
details.push("");
|
|
23566
|
+
details.push("\u2550\u2550\u2550 Configured Models \u2550\u2550\u2550");
|
|
23567
|
+
details.push("");
|
|
23568
|
+
details.push("Agents:");
|
|
23569
|
+
for (const agent of info.agents) {
|
|
23570
|
+
const marker = agent.userOverride ? "\u25CF" : "\u25CB";
|
|
23571
|
+
const display = formatModelWithVariant(agent.effectiveModel, getEffectiveVariant(agent.requirement));
|
|
23572
|
+
details.push(` ${marker} ${agent.name}: ${display}`);
|
|
23573
|
+
}
|
|
23574
|
+
details.push("");
|
|
23575
|
+
details.push("Categories:");
|
|
23576
|
+
for (const category of info.categories) {
|
|
23577
|
+
const marker = category.userOverride ? "\u25CF" : "\u25CB";
|
|
23578
|
+
const display = formatModelWithVariant(category.effectiveModel, getEffectiveVariant(category.requirement));
|
|
23579
|
+
details.push(` ${marker} ${category.name}: ${display}`);
|
|
23580
|
+
}
|
|
23581
|
+
details.push("");
|
|
23582
|
+
details.push("\u25CF = user override, \u25CB = provider fallback");
|
|
23583
|
+
return details;
|
|
23584
|
+
}
|
|
23585
|
+
async function checkModelResolution() {
|
|
23586
|
+
const config2 = loadConfig() ?? {};
|
|
23587
|
+
const info = getModelResolutionInfoWithOverrides(config2);
|
|
23588
|
+
const available = loadAvailableModels();
|
|
23589
|
+
const agentCount = info.agents.length;
|
|
23590
|
+
const categoryCount = info.categories.length;
|
|
23591
|
+
const agentOverrides = info.agents.filter((a) => a.userOverride).length;
|
|
23592
|
+
const categoryOverrides = info.categories.filter((c) => c.userOverride).length;
|
|
23593
|
+
const totalOverrides = agentOverrides + categoryOverrides;
|
|
23594
|
+
const overrideNote = totalOverrides > 0 ? ` (${totalOverrides} override${totalOverrides > 1 ? "s" : ""})` : "";
|
|
23595
|
+
const cacheNote = available.cacheExists ? `, ${available.modelCount} available` : ", cache not found";
|
|
23596
|
+
return {
|
|
23597
|
+
name: CHECK_NAMES[CHECK_IDS.MODEL_RESOLUTION],
|
|
23598
|
+
status: available.cacheExists ? "pass" : "warn",
|
|
23599
|
+
message: `${agentCount} agents, ${categoryCount} categories${overrideNote}${cacheNote}`,
|
|
23600
|
+
details: buildDetailsArray(info, available)
|
|
23601
|
+
};
|
|
23602
|
+
}
|
|
23603
|
+
function getModelResolutionCheckDefinition() {
|
|
23604
|
+
return {
|
|
23605
|
+
id: CHECK_IDS.MODEL_RESOLUTION,
|
|
23606
|
+
name: CHECK_NAMES[CHECK_IDS.MODEL_RESOLUTION],
|
|
23607
|
+
category: "configuration",
|
|
23608
|
+
check: checkModelResolution,
|
|
23609
|
+
critical: false
|
|
23610
|
+
};
|
|
23611
|
+
}
|
|
23612
|
+
|
|
23135
23613
|
// src/cli/doctor/checks/auth.ts
|
|
23136
|
-
import { existsSync as
|
|
23137
|
-
import {
|
|
23138
|
-
import { join as join7 } from "path";
|
|
23614
|
+
import { existsSync as existsSync10, readFileSync as readFileSync9 } from "fs";
|
|
23615
|
+
import { join as join10 } from "path";
|
|
23139
23616
|
init_shared();
|
|
23140
|
-
var OPENCODE_CONFIG_DIR =
|
|
23141
|
-
var OPENCODE_JSON =
|
|
23142
|
-
var OPENCODE_JSONC =
|
|
23617
|
+
var OPENCODE_CONFIG_DIR = getOpenCodeConfigDir({ binary: "opencode" });
|
|
23618
|
+
var OPENCODE_JSON = join10(OPENCODE_CONFIG_DIR, "opencode.json");
|
|
23619
|
+
var OPENCODE_JSONC = join10(OPENCODE_CONFIG_DIR, "opencode.jsonc");
|
|
23143
23620
|
var AUTH_PLUGINS = {
|
|
23144
23621
|
anthropic: { plugin: "builtin", name: "Anthropic (Claude)" },
|
|
23145
23622
|
openai: { plugin: "opencode-openai-codex-auth", name: "OpenAI (ChatGPT)" },
|
|
23146
23623
|
google: { plugin: "opencode-antigravity-auth", name: "Google (Gemini)" }
|
|
23147
23624
|
};
|
|
23148
23625
|
function getOpenCodeConfig() {
|
|
23149
|
-
const configPath =
|
|
23150
|
-
if (!
|
|
23626
|
+
const configPath = existsSync10(OPENCODE_JSONC) ? OPENCODE_JSONC : OPENCODE_JSON;
|
|
23627
|
+
if (!existsSync10(configPath))
|
|
23151
23628
|
return null;
|
|
23152
23629
|
try {
|
|
23153
|
-
const content =
|
|
23630
|
+
const content = readFileSync9(configPath, "utf-8");
|
|
23154
23631
|
return parseJsonc(content);
|
|
23155
23632
|
} catch {
|
|
23156
23633
|
return null;
|
|
@@ -23279,9 +23756,9 @@ async function checkAstGrepCli() {
|
|
|
23279
23756
|
path: binary2.path
|
|
23280
23757
|
};
|
|
23281
23758
|
}
|
|
23282
|
-
function checkAstGrepNapi() {
|
|
23759
|
+
async function checkAstGrepNapi() {
|
|
23283
23760
|
try {
|
|
23284
|
-
|
|
23761
|
+
await import("@ast-grep/napi");
|
|
23285
23762
|
return {
|
|
23286
23763
|
name: "AST-Grep NAPI",
|
|
23287
23764
|
required: false,
|
|
@@ -23290,6 +23767,24 @@ function checkAstGrepNapi() {
|
|
|
23290
23767
|
path: null
|
|
23291
23768
|
};
|
|
23292
23769
|
} catch {
|
|
23770
|
+
const { existsSync: existsSync11 } = await import("fs");
|
|
23771
|
+
const { join: join11 } = await import("path");
|
|
23772
|
+
const { homedir: homedir7 } = await import("os");
|
|
23773
|
+
const pathsToCheck = [
|
|
23774
|
+
join11(homedir7(), ".config", "opencode", "node_modules", "@ast-grep", "napi"),
|
|
23775
|
+
join11(process.cwd(), "node_modules", "@ast-grep", "napi")
|
|
23776
|
+
];
|
|
23777
|
+
for (const napiPath of pathsToCheck) {
|
|
23778
|
+
if (existsSync11(napiPath)) {
|
|
23779
|
+
return {
|
|
23780
|
+
name: "AST-Grep NAPI",
|
|
23781
|
+
required: false,
|
|
23782
|
+
installed: true,
|
|
23783
|
+
version: null,
|
|
23784
|
+
path: napiPath
|
|
23785
|
+
};
|
|
23786
|
+
}
|
|
23787
|
+
}
|
|
23293
23788
|
return {
|
|
23294
23789
|
name: "AST-Grep NAPI",
|
|
23295
23790
|
required: false,
|
|
@@ -23342,7 +23837,7 @@ async function checkDependencyAstGrepCli() {
|
|
|
23342
23837
|
return dependencyToCheckResult(info, CHECK_NAMES[CHECK_IDS.DEP_AST_GREP_CLI]);
|
|
23343
23838
|
}
|
|
23344
23839
|
async function checkDependencyAstGrepNapi() {
|
|
23345
|
-
const info = checkAstGrepNapi();
|
|
23840
|
+
const info = await checkAstGrepNapi();
|
|
23346
23841
|
return dependencyToCheckResult(info, CHECK_NAMES[CHECK_IDS.DEP_AST_GREP_NAPI]);
|
|
23347
23842
|
}
|
|
23348
23843
|
async function checkDependencyCommentChecker() {
|
|
@@ -23509,15 +24004,15 @@ function getGhCliCheckDefinition() {
|
|
|
23509
24004
|
}
|
|
23510
24005
|
|
|
23511
24006
|
// src/tools/lsp/config.ts
|
|
23512
|
-
import { existsSync as
|
|
23513
|
-
import { join as
|
|
23514
|
-
|
|
24007
|
+
import { existsSync as existsSync11, readFileSync as readFileSync10 } from "fs";
|
|
24008
|
+
import { join as join11 } from "path";
|
|
24009
|
+
init_shared();
|
|
23515
24010
|
function isServerInstalled(command) {
|
|
23516
24011
|
if (command.length === 0)
|
|
23517
24012
|
return false;
|
|
23518
24013
|
const cmd = command[0];
|
|
23519
24014
|
if (cmd.includes("/") || cmd.includes("\\")) {
|
|
23520
|
-
if (
|
|
24015
|
+
if (existsSync11(cmd))
|
|
23521
24016
|
return true;
|
|
23522
24017
|
}
|
|
23523
24018
|
const isWindows = process.platform === "win32";
|
|
@@ -23539,20 +24034,23 @@ function isServerInstalled(command) {
|
|
|
23539
24034
|
const paths = pathEnv.split(pathSeparator);
|
|
23540
24035
|
for (const p2 of paths) {
|
|
23541
24036
|
for (const suffix of exts) {
|
|
23542
|
-
if (
|
|
24037
|
+
if (existsSync11(join11(p2, cmd + suffix))) {
|
|
23543
24038
|
return true;
|
|
23544
24039
|
}
|
|
23545
24040
|
}
|
|
23546
24041
|
}
|
|
23547
24042
|
const cwd = process.cwd();
|
|
24043
|
+
const configDir = getOpenCodeConfigDir({ binary: "opencode" });
|
|
24044
|
+
const dataDir = join11(getDataDir(), "opencode");
|
|
23548
24045
|
const additionalBases = [
|
|
23549
|
-
|
|
23550
|
-
|
|
23551
|
-
|
|
24046
|
+
join11(cwd, "node_modules", ".bin"),
|
|
24047
|
+
join11(configDir, "bin"),
|
|
24048
|
+
join11(configDir, "node_modules", ".bin"),
|
|
24049
|
+
join11(dataDir, "bin")
|
|
23552
24050
|
];
|
|
23553
24051
|
for (const base of additionalBases) {
|
|
23554
24052
|
for (const suffix of exts) {
|
|
23555
|
-
if (
|
|
24053
|
+
if (existsSync11(join11(base, cmd + suffix))) {
|
|
23556
24054
|
return true;
|
|
23557
24055
|
}
|
|
23558
24056
|
}
|
|
@@ -23625,23 +24123,23 @@ function getLspCheckDefinition() {
|
|
|
23625
24123
|
}
|
|
23626
24124
|
|
|
23627
24125
|
// src/cli/doctor/checks/mcp.ts
|
|
23628
|
-
import { existsSync as
|
|
24126
|
+
import { existsSync as existsSync12, readFileSync as readFileSync11 } from "fs";
|
|
23629
24127
|
import { homedir as homedir7 } from "os";
|
|
23630
|
-
import { join as
|
|
24128
|
+
import { join as join12 } from "path";
|
|
23631
24129
|
init_shared();
|
|
23632
24130
|
var BUILTIN_MCP_SERVERS = ["context7", "grep_app"];
|
|
23633
24131
|
var MCP_CONFIG_PATHS = [
|
|
23634
|
-
|
|
23635
|
-
|
|
23636
|
-
|
|
24132
|
+
join12(homedir7(), ".claude", ".mcp.json"),
|
|
24133
|
+
join12(process.cwd(), ".mcp.json"),
|
|
24134
|
+
join12(process.cwd(), ".claude", ".mcp.json")
|
|
23637
24135
|
];
|
|
23638
24136
|
function loadUserMcpConfig() {
|
|
23639
24137
|
const servers = {};
|
|
23640
24138
|
for (const configPath of MCP_CONFIG_PATHS) {
|
|
23641
|
-
if (!
|
|
24139
|
+
if (!existsSync12(configPath))
|
|
23642
24140
|
continue;
|
|
23643
24141
|
try {
|
|
23644
|
-
const content =
|
|
24142
|
+
const content = readFileSync11(configPath, "utf-8");
|
|
23645
24143
|
const config2 = parseJsonc(content);
|
|
23646
24144
|
if (config2.mcpServers) {
|
|
23647
24145
|
Object.assign(servers, config2.mcpServers);
|
|
@@ -23848,6 +24346,7 @@ function getAllCheckDefinitions() {
|
|
|
23848
24346
|
getOpenCodeCheckDefinition(),
|
|
23849
24347
|
getPluginCheckDefinition(),
|
|
23850
24348
|
getConfigCheckDefinition(),
|
|
24349
|
+
getModelResolutionCheckDefinition(),
|
|
23851
24350
|
...getAuthCheckDefinitions(),
|
|
23852
24351
|
...getDependencyCheckDefinitions(),
|
|
23853
24352
|
getGhCliCheckDefinition(),
|
|
@@ -24039,23 +24538,28 @@ async function doctor(options = {}) {
|
|
|
24039
24538
|
var VERSION2 = package_default.version;
|
|
24040
24539
|
var program2 = new Command;
|
|
24041
24540
|
program2.name("oh-my-opencode").description("The ultimate OpenCode plugin - multi-model orchestration, LSP tools, and more").version(VERSION2, "-v, --version", "Show version number");
|
|
24042
|
-
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("--
|
|
24541
|
+
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("--openai <value>", "OpenAI/ChatGPT subscription: no, yes (default: no)").option("--gemini <value>", "Gemini integration: no, yes").option("--copilot <value>", "GitHub Copilot subscription: no, yes").option("--opencode-zen <value>", "OpenCode Zen access: no, yes (default: no)").option("--zai-coding-plan <value>", "Z.ai Coding Plan subscription: no, yes (default: no)").option("--skip-auth", "Skip authentication setup hints").addHelpText("after", `
|
|
24043
24542
|
Examples:
|
|
24044
24543
|
$ bunx oh-my-opencode install
|
|
24045
|
-
$ bunx oh-my-opencode install --no-tui --claude=max20 --
|
|
24046
|
-
$ bunx oh-my-opencode install --no-tui --claude=no --
|
|
24544
|
+
$ bunx oh-my-opencode install --no-tui --claude=max20 --openai=yes --gemini=yes --copilot=no
|
|
24545
|
+
$ bunx oh-my-opencode install --no-tui --claude=no --gemini=no --copilot=yes --opencode-zen=yes
|
|
24047
24546
|
|
|
24048
|
-
Model Providers:
|
|
24049
|
-
Claude
|
|
24050
|
-
|
|
24051
|
-
Gemini
|
|
24547
|
+
Model Providers (Priority: Native > Copilot > OpenCode Zen > Z.ai):
|
|
24548
|
+
Claude Native anthropic/ models (Opus, Sonnet, Haiku)
|
|
24549
|
+
OpenAI Native openai/ models (GPT-5.2 for Oracle)
|
|
24550
|
+
Gemini Native google/ models (Gemini 3 Pro, Flash)
|
|
24551
|
+
Copilot github-copilot/ models (fallback)
|
|
24552
|
+
OpenCode Zen opencode/ models (opencode/claude-opus-4-5, etc.)
|
|
24553
|
+
Z.ai zai-coding-plan/glm-4.7 (Librarian priority)
|
|
24052
24554
|
`).action(async (options) => {
|
|
24053
24555
|
const args = {
|
|
24054
24556
|
tui: options.tui !== false,
|
|
24055
24557
|
claude: options.claude,
|
|
24056
|
-
|
|
24558
|
+
openai: options.openai,
|
|
24057
24559
|
gemini: options.gemini,
|
|
24058
24560
|
copilot: options.copilot,
|
|
24561
|
+
opencodeZen: options.opencodeZen,
|
|
24562
|
+
zaiCodingPlan: options.zaiCodingPlan,
|
|
24059
24563
|
skipAuth: options.skipAuth ?? false
|
|
24060
24564
|
};
|
|
24061
24565
|
const exitCode = await install(args);
|