oh-my-opencode 3.0.0-beta.9 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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/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 +886 -401
- 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/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 +12781 -13070
- 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/config-path.d.ts +1 -5
- package/dist/shared/index.d.ts +4 -0
- 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/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 +1 -1
- 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/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/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
|
@@ -4917,6 +4917,11 @@ var init_dynamic_truncator = __esm(() => {
|
|
|
4917
4917
|
var init_config_path = () => {};
|
|
4918
4918
|
|
|
4919
4919
|
// src/shared/data-path.ts
|
|
4920
|
+
import * as path2 from "path";
|
|
4921
|
+
import * as os2 from "os";
|
|
4922
|
+
function getDataDir() {
|
|
4923
|
+
return process.env.XDG_DATA_HOME ?? path2.join(os2.homedir(), ".local", "share");
|
|
4924
|
+
}
|
|
4920
4925
|
var init_data_path = () => {};
|
|
4921
4926
|
|
|
4922
4927
|
// src/shared/config-errors.ts
|
|
@@ -5832,25 +5837,23 @@ var BUILTIN_AGENT_NAMES;
|
|
|
5832
5837
|
var init_migration = __esm(() => {
|
|
5833
5838
|
init_logger();
|
|
5834
5839
|
BUILTIN_AGENT_NAMES = new Set([
|
|
5835
|
-
"
|
|
5840
|
+
"sisyphus",
|
|
5836
5841
|
"oracle",
|
|
5837
5842
|
"librarian",
|
|
5838
5843
|
"explore",
|
|
5839
|
-
"frontend-ui-ux-engineer",
|
|
5840
|
-
"document-writer",
|
|
5841
5844
|
"multimodal-looker",
|
|
5842
|
-
"
|
|
5843
|
-
"
|
|
5844
|
-
"
|
|
5845
|
-
"
|
|
5845
|
+
"metis",
|
|
5846
|
+
"momus",
|
|
5847
|
+
"prometheus",
|
|
5848
|
+
"atlas",
|
|
5846
5849
|
"build"
|
|
5847
5850
|
]);
|
|
5848
5851
|
});
|
|
5849
5852
|
|
|
5850
5853
|
// src/shared/opencode-config-dir.ts
|
|
5851
5854
|
import { existsSync as existsSync2 } from "fs";
|
|
5852
|
-
import { homedir } from "os";
|
|
5853
|
-
import { join as
|
|
5855
|
+
import { homedir as homedir2 } from "os";
|
|
5856
|
+
import { join as join3, resolve } from "path";
|
|
5854
5857
|
function isDevBuild(version) {
|
|
5855
5858
|
if (!version)
|
|
5856
5859
|
return false;
|
|
@@ -5860,15 +5863,15 @@ function getTauriConfigDir(identifier) {
|
|
|
5860
5863
|
const platform = process.platform;
|
|
5861
5864
|
switch (platform) {
|
|
5862
5865
|
case "darwin":
|
|
5863
|
-
return
|
|
5866
|
+
return join3(homedir2(), "Library", "Application Support", identifier);
|
|
5864
5867
|
case "win32": {
|
|
5865
|
-
const appData = process.env.APPDATA ||
|
|
5866
|
-
return
|
|
5868
|
+
const appData = process.env.APPDATA || join3(homedir2(), "AppData", "Roaming");
|
|
5869
|
+
return join3(appData, identifier);
|
|
5867
5870
|
}
|
|
5868
5871
|
case "linux":
|
|
5869
5872
|
default: {
|
|
5870
|
-
const xdgConfig = process.env.XDG_CONFIG_HOME ||
|
|
5871
|
-
return
|
|
5873
|
+
const xdgConfig = process.env.XDG_CONFIG_HOME || join3(homedir2(), ".config");
|
|
5874
|
+
return join3(xdgConfig, identifier);
|
|
5872
5875
|
}
|
|
5873
5876
|
}
|
|
5874
5877
|
}
|
|
@@ -5878,21 +5881,21 @@ function getCliConfigDir() {
|
|
|
5878
5881
|
return resolve(envConfigDir);
|
|
5879
5882
|
}
|
|
5880
5883
|
if (process.platform === "win32") {
|
|
5881
|
-
const crossPlatformDir =
|
|
5882
|
-
const crossPlatformConfig =
|
|
5884
|
+
const crossPlatformDir = join3(homedir2(), ".config", "opencode");
|
|
5885
|
+
const crossPlatformConfig = join3(crossPlatformDir, "opencode.json");
|
|
5883
5886
|
if (existsSync2(crossPlatformConfig)) {
|
|
5884
5887
|
return crossPlatformDir;
|
|
5885
5888
|
}
|
|
5886
|
-
const appData = process.env.APPDATA ||
|
|
5887
|
-
const appdataDir =
|
|
5888
|
-
const appdataConfig =
|
|
5889
|
+
const appData = process.env.APPDATA || join3(homedir2(), "AppData", "Roaming");
|
|
5890
|
+
const appdataDir = join3(appData, "opencode");
|
|
5891
|
+
const appdataConfig = join3(appdataDir, "opencode.json");
|
|
5889
5892
|
if (existsSync2(appdataConfig)) {
|
|
5890
5893
|
return appdataDir;
|
|
5891
5894
|
}
|
|
5892
5895
|
return crossPlatformDir;
|
|
5893
5896
|
}
|
|
5894
|
-
const xdgConfig = process.env.XDG_CONFIG_HOME ||
|
|
5895
|
-
return
|
|
5897
|
+
const xdgConfig = process.env.XDG_CONFIG_HOME || join3(homedir2(), ".config");
|
|
5898
|
+
return join3(xdgConfig, "opencode");
|
|
5896
5899
|
}
|
|
5897
5900
|
function getOpenCodeConfigDir(options) {
|
|
5898
5901
|
const { binary: binary2, version, checkExisting = true } = options;
|
|
@@ -5903,8 +5906,8 @@ function getOpenCodeConfigDir(options) {
|
|
|
5903
5906
|
const tauriDir = getTauriConfigDir(identifier);
|
|
5904
5907
|
if (checkExisting) {
|
|
5905
5908
|
const legacyDir = getCliConfigDir();
|
|
5906
|
-
const legacyConfig =
|
|
5907
|
-
const legacyConfigC =
|
|
5909
|
+
const legacyConfig = join3(legacyDir, "opencode.json");
|
|
5910
|
+
const legacyConfigC = join3(legacyDir, "opencode.jsonc");
|
|
5908
5911
|
if (existsSync2(legacyConfig) || existsSync2(legacyConfigC)) {
|
|
5909
5912
|
return legacyDir;
|
|
5910
5913
|
}
|
|
@@ -5915,10 +5918,10 @@ function getOpenCodeConfigPaths(options) {
|
|
|
5915
5918
|
const configDir = getOpenCodeConfigDir(options);
|
|
5916
5919
|
return {
|
|
5917
5920
|
configDir,
|
|
5918
|
-
configJson:
|
|
5919
|
-
configJsonc:
|
|
5920
|
-
packageJson:
|
|
5921
|
-
omoConfig:
|
|
5921
|
+
configJson: join3(configDir, "opencode.json"),
|
|
5922
|
+
configJsonc: join3(configDir, "opencode.jsonc"),
|
|
5923
|
+
packageJson: join3(configDir, "package.json"),
|
|
5924
|
+
omoConfig: join3(configDir, "oh-my-opencode.json")
|
|
5922
5925
|
};
|
|
5923
5926
|
}
|
|
5924
5927
|
var TAURI_APP_IDENTIFIER = "ai.opencode.desktop", TAURI_APP_IDENTIFIER_DEV = "ai.opencode.desktop.dev";
|
|
@@ -5937,6 +5940,9 @@ var init_external_plugin_detector = __esm(() => {
|
|
|
5937
5940
|
|
|
5938
5941
|
// src/shared/zip-extractor.ts
|
|
5939
5942
|
var init_zip_extractor = () => {};
|
|
5943
|
+
// src/shared/agent-variant.ts
|
|
5944
|
+
var init_agent_variant = () => {};
|
|
5945
|
+
|
|
5940
5946
|
// src/shared/session-cursor.ts
|
|
5941
5947
|
var sessionCursors;
|
|
5942
5948
|
var init_session_cursor = __esm(() => {
|
|
@@ -5948,6 +5954,154 @@ var init_system_directive = () => {};
|
|
|
5948
5954
|
// src/shared/agent-tool-restrictions.ts
|
|
5949
5955
|
var init_agent_tool_restrictions = () => {};
|
|
5950
5956
|
|
|
5957
|
+
// src/shared/model-requirements.ts
|
|
5958
|
+
var AGENT_MODEL_REQUIREMENTS, CATEGORY_MODEL_REQUIREMENTS;
|
|
5959
|
+
var init_model_requirements = __esm(() => {
|
|
5960
|
+
AGENT_MODEL_REQUIREMENTS = {
|
|
5961
|
+
sisyphus: {
|
|
5962
|
+
fallbackChain: [
|
|
5963
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" },
|
|
5964
|
+
{ providers: ["zai-coding-plan"], model: "glm-4.7" },
|
|
5965
|
+
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2-codex", variant: "medium" },
|
|
5966
|
+
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro" }
|
|
5967
|
+
]
|
|
5968
|
+
},
|
|
5969
|
+
oracle: {
|
|
5970
|
+
fallbackChain: [
|
|
5971
|
+
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2", variant: "high" },
|
|
5972
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" },
|
|
5973
|
+
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro" }
|
|
5974
|
+
]
|
|
5975
|
+
},
|
|
5976
|
+
librarian: {
|
|
5977
|
+
fallbackChain: [
|
|
5978
|
+
{ providers: ["zai-coding-plan"], model: "glm-4.7" },
|
|
5979
|
+
{ providers: ["opencode"], model: "big-pickle" },
|
|
5980
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-sonnet-4-5" }
|
|
5981
|
+
]
|
|
5982
|
+
},
|
|
5983
|
+
explore: {
|
|
5984
|
+
fallbackChain: [
|
|
5985
|
+
{ providers: ["anthropic", "opencode"], model: "claude-haiku-4-5" },
|
|
5986
|
+
{ providers: ["opencode"], model: "gpt-5-nano" }
|
|
5987
|
+
]
|
|
5988
|
+
},
|
|
5989
|
+
"multimodal-looker": {
|
|
5990
|
+
fallbackChain: [
|
|
5991
|
+
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-flash" },
|
|
5992
|
+
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2" },
|
|
5993
|
+
{ providers: ["zai-coding-plan"], model: "glm-4.6v" },
|
|
5994
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-haiku-4-5" },
|
|
5995
|
+
{ providers: ["opencode"], model: "gpt-5-nano" }
|
|
5996
|
+
]
|
|
5997
|
+
},
|
|
5998
|
+
prometheus: {
|
|
5999
|
+
fallbackChain: [
|
|
6000
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" },
|
|
6001
|
+
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2", variant: "high" },
|
|
6002
|
+
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro" }
|
|
6003
|
+
]
|
|
6004
|
+
},
|
|
6005
|
+
metis: {
|
|
6006
|
+
fallbackChain: [
|
|
6007
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" },
|
|
6008
|
+
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2", variant: "high" },
|
|
6009
|
+
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro", variant: "max" }
|
|
6010
|
+
]
|
|
6011
|
+
},
|
|
6012
|
+
momus: {
|
|
6013
|
+
fallbackChain: [
|
|
6014
|
+
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2", variant: "medium" },
|
|
6015
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5" },
|
|
6016
|
+
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro", variant: "max" }
|
|
6017
|
+
]
|
|
6018
|
+
},
|
|
6019
|
+
atlas: {
|
|
6020
|
+
fallbackChain: [
|
|
6021
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-sonnet-4-5" },
|
|
6022
|
+
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2" },
|
|
6023
|
+
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro" }
|
|
6024
|
+
]
|
|
6025
|
+
}
|
|
6026
|
+
};
|
|
6027
|
+
CATEGORY_MODEL_REQUIREMENTS = {
|
|
6028
|
+
"visual-engineering": {
|
|
6029
|
+
fallbackChain: [
|
|
6030
|
+
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro" },
|
|
6031
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" },
|
|
6032
|
+
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2", variant: "high" }
|
|
6033
|
+
]
|
|
6034
|
+
},
|
|
6035
|
+
ultrabrain: {
|
|
6036
|
+
fallbackChain: [
|
|
6037
|
+
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2-codex", variant: "xhigh" },
|
|
6038
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" },
|
|
6039
|
+
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro" }
|
|
6040
|
+
]
|
|
6041
|
+
},
|
|
6042
|
+
artistry: {
|
|
6043
|
+
fallbackChain: [
|
|
6044
|
+
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro", variant: "max" },
|
|
6045
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" },
|
|
6046
|
+
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2" }
|
|
6047
|
+
]
|
|
6048
|
+
},
|
|
6049
|
+
quick: {
|
|
6050
|
+
fallbackChain: [
|
|
6051
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-haiku-4-5" },
|
|
6052
|
+
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-flash" },
|
|
6053
|
+
{ providers: ["opencode"], model: "gpt-5-nano" }
|
|
6054
|
+
]
|
|
6055
|
+
},
|
|
6056
|
+
"unspecified-low": {
|
|
6057
|
+
fallbackChain: [
|
|
6058
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-sonnet-4-5" },
|
|
6059
|
+
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2-codex", variant: "medium" },
|
|
6060
|
+
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-flash" }
|
|
6061
|
+
]
|
|
6062
|
+
},
|
|
6063
|
+
"unspecified-high": {
|
|
6064
|
+
fallbackChain: [
|
|
6065
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" },
|
|
6066
|
+
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2", variant: "high" },
|
|
6067
|
+
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro" }
|
|
6068
|
+
]
|
|
6069
|
+
},
|
|
6070
|
+
writing: {
|
|
6071
|
+
fallbackChain: [
|
|
6072
|
+
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-flash" },
|
|
6073
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-sonnet-4-5" },
|
|
6074
|
+
{ providers: ["zai-coding-plan"], model: "glm-4.7" },
|
|
6075
|
+
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2" }
|
|
6076
|
+
]
|
|
6077
|
+
}
|
|
6078
|
+
};
|
|
6079
|
+
});
|
|
6080
|
+
|
|
6081
|
+
// src/shared/model-availability.ts
|
|
6082
|
+
import { existsSync as existsSync3, readFileSync as readFileSync2 } from "fs";
|
|
6083
|
+
import { homedir as homedir3 } from "os";
|
|
6084
|
+
import { join as join4 } from "path";
|
|
6085
|
+
function getOpenCodeCacheDir() {
|
|
6086
|
+
const xdgCache = process.env.XDG_CACHE_HOME;
|
|
6087
|
+
if (xdgCache)
|
|
6088
|
+
return join4(xdgCache, "opencode");
|
|
6089
|
+
return join4(homedir3(), ".cache", "opencode");
|
|
6090
|
+
}
|
|
6091
|
+
function isModelCacheAvailable() {
|
|
6092
|
+
const cacheFile = join4(getOpenCodeCacheDir(), "models.json");
|
|
6093
|
+
return existsSync3(cacheFile);
|
|
6094
|
+
}
|
|
6095
|
+
var init_model_availability = __esm(() => {
|
|
6096
|
+
init_logger();
|
|
6097
|
+
});
|
|
6098
|
+
|
|
6099
|
+
// src/shared/model-resolver.ts
|
|
6100
|
+
var init_model_resolver = __esm(() => {
|
|
6101
|
+
init_logger();
|
|
6102
|
+
init_model_availability();
|
|
6103
|
+
});
|
|
6104
|
+
|
|
5951
6105
|
// src/shared/index.ts
|
|
5952
6106
|
var init_shared = __esm(() => {
|
|
5953
6107
|
init_frontmatter();
|
|
@@ -5969,13 +6123,129 @@ var init_shared = __esm(() => {
|
|
|
5969
6123
|
init_opencode_version();
|
|
5970
6124
|
init_external_plugin_detector();
|
|
5971
6125
|
init_zip_extractor();
|
|
6126
|
+
init_agent_variant();
|
|
5972
6127
|
init_session_cursor();
|
|
5973
6128
|
init_system_directive();
|
|
5974
6129
|
init_agent_tool_restrictions();
|
|
6130
|
+
init_model_requirements();
|
|
6131
|
+
init_model_resolver();
|
|
6132
|
+
init_model_availability();
|
|
6133
|
+
});
|
|
6134
|
+
|
|
6135
|
+
// src/cli/model-fallback.ts
|
|
6136
|
+
function toProviderAvailability(config) {
|
|
6137
|
+
return {
|
|
6138
|
+
native: {
|
|
6139
|
+
claude: config.hasClaude,
|
|
6140
|
+
openai: config.hasOpenAI,
|
|
6141
|
+
gemini: config.hasGemini
|
|
6142
|
+
},
|
|
6143
|
+
opencodeZen: config.hasOpencodeZen,
|
|
6144
|
+
copilot: config.hasCopilot,
|
|
6145
|
+
zai: config.hasZaiCodingPlan,
|
|
6146
|
+
isMaxPlan: config.isMax20
|
|
6147
|
+
};
|
|
6148
|
+
}
|
|
6149
|
+
function isProviderAvailable(provider, avail) {
|
|
6150
|
+
const mapping = {
|
|
6151
|
+
anthropic: avail.native.claude,
|
|
6152
|
+
openai: avail.native.openai,
|
|
6153
|
+
google: avail.native.gemini,
|
|
6154
|
+
"github-copilot": avail.copilot,
|
|
6155
|
+
opencode: avail.opencodeZen,
|
|
6156
|
+
"zai-coding-plan": avail.zai
|
|
6157
|
+
};
|
|
6158
|
+
return mapping[provider] ?? false;
|
|
6159
|
+
}
|
|
6160
|
+
function transformModelForProvider(provider, model) {
|
|
6161
|
+
if (provider === "github-copilot") {
|
|
6162
|
+
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");
|
|
6163
|
+
}
|
|
6164
|
+
return model;
|
|
6165
|
+
}
|
|
6166
|
+
function resolveModelFromChain(fallbackChain, avail) {
|
|
6167
|
+
for (const entry of fallbackChain) {
|
|
6168
|
+
for (const provider of entry.providers) {
|
|
6169
|
+
if (isProviderAvailable(provider, avail)) {
|
|
6170
|
+
const transformedModel = transformModelForProvider(provider, entry.model);
|
|
6171
|
+
return {
|
|
6172
|
+
model: `${provider}/${transformedModel}`,
|
|
6173
|
+
variant: entry.variant
|
|
6174
|
+
};
|
|
6175
|
+
}
|
|
6176
|
+
}
|
|
6177
|
+
}
|
|
6178
|
+
return null;
|
|
6179
|
+
}
|
|
6180
|
+
function getSisyphusFallbackChain(isMaxPlan) {
|
|
6181
|
+
if (isMaxPlan) {
|
|
6182
|
+
return AGENT_MODEL_REQUIREMENTS.sisyphus.fallbackChain;
|
|
6183
|
+
}
|
|
6184
|
+
return [
|
|
6185
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-sonnet-4-5" },
|
|
6186
|
+
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2", variant: "high" },
|
|
6187
|
+
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro" }
|
|
6188
|
+
];
|
|
6189
|
+
}
|
|
6190
|
+
function generateModelConfig(config) {
|
|
6191
|
+
const avail = toProviderAvailability(config);
|
|
6192
|
+
const hasAnyProvider = avail.native.claude || avail.native.openai || avail.native.gemini || avail.opencodeZen || avail.copilot || avail.zai;
|
|
6193
|
+
if (!hasAnyProvider) {
|
|
6194
|
+
return {
|
|
6195
|
+
$schema: SCHEMA_URL,
|
|
6196
|
+
agents: Object.fromEntries(Object.keys(AGENT_MODEL_REQUIREMENTS).map((role) => [role, { model: ULTIMATE_FALLBACK }])),
|
|
6197
|
+
categories: Object.fromEntries(Object.keys(CATEGORY_MODEL_REQUIREMENTS).map((cat) => [cat, { model: ULTIMATE_FALLBACK }]))
|
|
6198
|
+
};
|
|
6199
|
+
}
|
|
6200
|
+
const agents = {};
|
|
6201
|
+
const categories = {};
|
|
6202
|
+
for (const [role, req] of Object.entries(AGENT_MODEL_REQUIREMENTS)) {
|
|
6203
|
+
if (role === "librarian" && avail.zai) {
|
|
6204
|
+
agents[role] = { model: ZAI_MODEL };
|
|
6205
|
+
continue;
|
|
6206
|
+
}
|
|
6207
|
+
if (role === "explore") {
|
|
6208
|
+
if (avail.native.claude) {
|
|
6209
|
+
agents[role] = { model: "anthropic/claude-haiku-4-5" };
|
|
6210
|
+
} else if (avail.opencodeZen) {
|
|
6211
|
+
agents[role] = { model: "opencode/claude-haiku-4-5" };
|
|
6212
|
+
} else {
|
|
6213
|
+
agents[role] = { model: "opencode/gpt-5-nano" };
|
|
6214
|
+
}
|
|
6215
|
+
continue;
|
|
6216
|
+
}
|
|
6217
|
+
const fallbackChain = role === "sisyphus" ? getSisyphusFallbackChain(avail.isMaxPlan) : req.fallbackChain;
|
|
6218
|
+
const resolved = resolveModelFromChain(fallbackChain, avail);
|
|
6219
|
+
if (resolved) {
|
|
6220
|
+
const variant = resolved.variant ?? req.variant;
|
|
6221
|
+
agents[role] = variant ? { model: resolved.model, variant } : { model: resolved.model };
|
|
6222
|
+
} else {
|
|
6223
|
+
agents[role] = { model: ULTIMATE_FALLBACK };
|
|
6224
|
+
}
|
|
6225
|
+
}
|
|
6226
|
+
for (const [cat, req] of Object.entries(CATEGORY_MODEL_REQUIREMENTS)) {
|
|
6227
|
+
const fallbackChain = cat === "unspecified-high" && !avail.isMaxPlan ? CATEGORY_MODEL_REQUIREMENTS["unspecified-low"].fallbackChain : req.fallbackChain;
|
|
6228
|
+
const resolved = resolveModelFromChain(fallbackChain, avail);
|
|
6229
|
+
if (resolved) {
|
|
6230
|
+
const variant = resolved.variant ?? req.variant;
|
|
6231
|
+
categories[cat] = variant ? { model: resolved.model, variant } : { model: resolved.model };
|
|
6232
|
+
} else {
|
|
6233
|
+
categories[cat] = { model: ULTIMATE_FALLBACK };
|
|
6234
|
+
}
|
|
6235
|
+
}
|
|
6236
|
+
return {
|
|
6237
|
+
$schema: SCHEMA_URL,
|
|
6238
|
+
agents,
|
|
6239
|
+
categories
|
|
6240
|
+
};
|
|
6241
|
+
}
|
|
6242
|
+
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";
|
|
6243
|
+
var init_model_fallback = __esm(() => {
|
|
6244
|
+
init_model_requirements();
|
|
5975
6245
|
});
|
|
5976
6246
|
|
|
5977
6247
|
// src/cli/config-manager.ts
|
|
5978
|
-
import { existsSync as
|
|
6248
|
+
import { existsSync as existsSync4, mkdirSync, readFileSync as readFileSync3, writeFileSync, statSync } from "fs";
|
|
5979
6249
|
function initConfigContext(binary2, version) {
|
|
5980
6250
|
const paths = getOpenCodeConfigPaths({ binary: binary2, version });
|
|
5981
6251
|
configContext = { binary: binary2, version, paths };
|
|
@@ -6065,10 +6335,10 @@ async function getPluginNameWithVersion(currentVersion) {
|
|
|
6065
6335
|
function detectConfigFormat() {
|
|
6066
6336
|
const configJsonc = getConfigJsonc();
|
|
6067
6337
|
const configJson = getConfigJson();
|
|
6068
|
-
if (
|
|
6338
|
+
if (existsSync4(configJsonc)) {
|
|
6069
6339
|
return { format: "jsonc", path: configJsonc };
|
|
6070
6340
|
}
|
|
6071
|
-
if (
|
|
6341
|
+
if (existsSync4(configJson)) {
|
|
6072
6342
|
return { format: "json", path: configJson };
|
|
6073
6343
|
}
|
|
6074
6344
|
return { format: "none", path: configJson };
|
|
@@ -6076,31 +6346,31 @@ function detectConfigFormat() {
|
|
|
6076
6346
|
function isEmptyOrWhitespace(content) {
|
|
6077
6347
|
return content.trim().length === 0;
|
|
6078
6348
|
}
|
|
6079
|
-
function parseConfigWithError(
|
|
6349
|
+
function parseConfigWithError(path3) {
|
|
6080
6350
|
try {
|
|
6081
|
-
const stat = statSync(
|
|
6351
|
+
const stat = statSync(path3);
|
|
6082
6352
|
if (stat.size === 0) {
|
|
6083
|
-
return { config: null, error: `Config file is empty: ${
|
|
6353
|
+
return { config: null, error: `Config file is empty: ${path3}. Delete it or add valid JSON content.` };
|
|
6084
6354
|
}
|
|
6085
|
-
const content =
|
|
6355
|
+
const content = readFileSync3(path3, "utf-8");
|
|
6086
6356
|
if (isEmptyOrWhitespace(content)) {
|
|
6087
|
-
return { config: null, error: `Config file contains only whitespace: ${
|
|
6357
|
+
return { config: null, error: `Config file contains only whitespace: ${path3}. Delete it or add valid JSON content.` };
|
|
6088
6358
|
}
|
|
6089
6359
|
const config = parseJsonc(content);
|
|
6090
6360
|
if (config === null || config === undefined) {
|
|
6091
|
-
return { config: null, error: `Config file parsed to null/undefined: ${
|
|
6361
|
+
return { config: null, error: `Config file parsed to null/undefined: ${path3}. Ensure it contains valid JSON.` };
|
|
6092
6362
|
}
|
|
6093
6363
|
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}: ${
|
|
6364
|
+
return { config: null, error: `Config file must contain a JSON object, not ${Array.isArray(config) ? "an array" : typeof config}: ${path3}` };
|
|
6095
6365
|
}
|
|
6096
6366
|
return { config };
|
|
6097
6367
|
} catch (err) {
|
|
6098
|
-
return { config: null, error: formatErrorWithSuggestion(err, `parse config file ${
|
|
6368
|
+
return { config: null, error: formatErrorWithSuggestion(err, `parse config file ${path3}`) };
|
|
6099
6369
|
}
|
|
6100
6370
|
}
|
|
6101
6371
|
function ensureConfigDir() {
|
|
6102
6372
|
const configDir = getConfigDir();
|
|
6103
|
-
if (!
|
|
6373
|
+
if (!existsSync4(configDir)) {
|
|
6104
6374
|
mkdirSync(configDir, { recursive: true });
|
|
6105
6375
|
}
|
|
6106
6376
|
}
|
|
@@ -6110,25 +6380,25 @@ async function addPluginToOpenCodeConfig(currentVersion) {
|
|
|
6110
6380
|
} catch (err) {
|
|
6111
6381
|
return { success: false, configPath: getConfigDir(), error: formatErrorWithSuggestion(err, "create config directory") };
|
|
6112
6382
|
}
|
|
6113
|
-
const { format: format2, path:
|
|
6383
|
+
const { format: format2, path: path3 } = detectConfigFormat();
|
|
6114
6384
|
const pluginEntry = await getPluginNameWithVersion(currentVersion);
|
|
6115
6385
|
try {
|
|
6116
6386
|
if (format2 === "none") {
|
|
6117
6387
|
const config2 = { plugin: [pluginEntry] };
|
|
6118
|
-
writeFileSync(
|
|
6388
|
+
writeFileSync(path3, JSON.stringify(config2, null, 2) + `
|
|
6119
6389
|
`);
|
|
6120
|
-
return { success: true, configPath:
|
|
6390
|
+
return { success: true, configPath: path3 };
|
|
6121
6391
|
}
|
|
6122
|
-
const parseResult = parseConfigWithError(
|
|
6392
|
+
const parseResult = parseConfigWithError(path3);
|
|
6123
6393
|
if (!parseResult.config) {
|
|
6124
|
-
return { success: false, configPath:
|
|
6394
|
+
return { success: false, configPath: path3, error: parseResult.error ?? "Failed to parse config file" };
|
|
6125
6395
|
}
|
|
6126
6396
|
const config = parseResult.config;
|
|
6127
6397
|
const plugins = config.plugin ?? [];
|
|
6128
6398
|
const existingIndex = plugins.findIndex((p2) => p2 === PACKAGE_NAME || p2.startsWith(`${PACKAGE_NAME}@`));
|
|
6129
6399
|
if (existingIndex !== -1) {
|
|
6130
6400
|
if (plugins[existingIndex] === pluginEntry) {
|
|
6131
|
-
return { success: true, configPath:
|
|
6401
|
+
return { success: true, configPath: path3 };
|
|
6132
6402
|
}
|
|
6133
6403
|
plugins[existingIndex] = pluginEntry;
|
|
6134
6404
|
} else {
|
|
@@ -6136,7 +6406,7 @@ async function addPluginToOpenCodeConfig(currentVersion) {
|
|
|
6136
6406
|
}
|
|
6137
6407
|
config.plugin = plugins;
|
|
6138
6408
|
if (format2 === "jsonc") {
|
|
6139
|
-
const content =
|
|
6409
|
+
const content = readFileSync3(path3, "utf-8");
|
|
6140
6410
|
const pluginArrayRegex = /"plugin"\s*:\s*\[([\s\S]*?)\]/;
|
|
6141
6411
|
const match = content.match(pluginArrayRegex);
|
|
6142
6412
|
if (match) {
|
|
@@ -6145,19 +6415,19 @@ async function addPluginToOpenCodeConfig(currentVersion) {
|
|
|
6145
6415
|
const newContent = content.replace(pluginArrayRegex, `"plugin": [
|
|
6146
6416
|
${formattedPlugins}
|
|
6147
6417
|
]`);
|
|
6148
|
-
writeFileSync(
|
|
6418
|
+
writeFileSync(path3, newContent);
|
|
6149
6419
|
} else {
|
|
6150
6420
|
const newContent = content.replace(/^(\s*\{)/, `$1
|
|
6151
6421
|
"plugin": ["${pluginEntry}"],`);
|
|
6152
|
-
writeFileSync(
|
|
6422
|
+
writeFileSync(path3, newContent);
|
|
6153
6423
|
}
|
|
6154
6424
|
} else {
|
|
6155
|
-
writeFileSync(
|
|
6425
|
+
writeFileSync(path3, JSON.stringify(config, null, 2) + `
|
|
6156
6426
|
`);
|
|
6157
6427
|
}
|
|
6158
|
-
return { success: true, configPath:
|
|
6428
|
+
return { success: true, configPath: path3 };
|
|
6159
6429
|
} catch (err) {
|
|
6160
|
-
return { success: false, configPath:
|
|
6430
|
+
return { success: false, configPath: path3, error: formatErrorWithSuggestion(err, "update opencode config") };
|
|
6161
6431
|
}
|
|
6162
6432
|
}
|
|
6163
6433
|
function deepMerge(target, source) {
|
|
@@ -6174,63 +6444,7 @@ function deepMerge(target, source) {
|
|
|
6174
6444
|
return result;
|
|
6175
6445
|
}
|
|
6176
6446
|
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;
|
|
6447
|
+
return generateModelConfig(installConfig);
|
|
6234
6448
|
}
|
|
6235
6449
|
function writeOmoConfig(installConfig) {
|
|
6236
6450
|
try {
|
|
@@ -6241,10 +6455,10 @@ function writeOmoConfig(installConfig) {
|
|
|
6241
6455
|
const omoConfigPath = getOmoConfig();
|
|
6242
6456
|
try {
|
|
6243
6457
|
const newConfig = generateOmoConfig(installConfig);
|
|
6244
|
-
if (
|
|
6458
|
+
if (existsSync4(omoConfigPath)) {
|
|
6245
6459
|
try {
|
|
6246
6460
|
const stat = statSync(omoConfigPath);
|
|
6247
|
-
const content =
|
|
6461
|
+
const content = readFileSync3(omoConfigPath, "utf-8");
|
|
6248
6462
|
if (stat.size === 0 || isEmptyOrWhitespace(content)) {
|
|
6249
6463
|
writeFileSync(omoConfigPath, JSON.stringify(newConfig, null, 2) + `
|
|
6250
6464
|
`);
|
|
@@ -6310,11 +6524,11 @@ async function addAuthPlugins(config) {
|
|
|
6310
6524
|
} catch (err) {
|
|
6311
6525
|
return { success: false, configPath: getConfigDir(), error: formatErrorWithSuggestion(err, "create config directory") };
|
|
6312
6526
|
}
|
|
6313
|
-
const { format: format2, path:
|
|
6527
|
+
const { format: format2, path: path3 } = detectConfigFormat();
|
|
6314
6528
|
try {
|
|
6315
6529
|
let existingConfig = null;
|
|
6316
6530
|
if (format2 !== "none") {
|
|
6317
|
-
const parseResult = parseConfigWithError(
|
|
6531
|
+
const parseResult = parseConfigWithError(path3);
|
|
6318
6532
|
if (parseResult.error && !parseResult.config) {
|
|
6319
6533
|
existingConfig = {};
|
|
6320
6534
|
} else {
|
|
@@ -6330,11 +6544,11 @@ async function addAuthPlugins(config) {
|
|
|
6330
6544
|
}
|
|
6331
6545
|
}
|
|
6332
6546
|
const newConfig = { ...existingConfig ?? {}, plugin: plugins };
|
|
6333
|
-
writeFileSync(
|
|
6547
|
+
writeFileSync(path3, JSON.stringify(newConfig, null, 2) + `
|
|
6334
6548
|
`);
|
|
6335
|
-
return { success: true, configPath:
|
|
6549
|
+
return { success: true, configPath: path3 };
|
|
6336
6550
|
} catch (err) {
|
|
6337
|
-
return { success: false, configPath:
|
|
6551
|
+
return { success: false, configPath: path3, error: formatErrorWithSuggestion(err, "add auth plugins to config") };
|
|
6338
6552
|
}
|
|
6339
6553
|
}
|
|
6340
6554
|
async function runBunInstall() {
|
|
@@ -6383,11 +6597,11 @@ function addProviderConfig(config) {
|
|
|
6383
6597
|
} catch (err) {
|
|
6384
6598
|
return { success: false, configPath: getConfigDir(), error: formatErrorWithSuggestion(err, "create config directory") };
|
|
6385
6599
|
}
|
|
6386
|
-
const { format: format2, path:
|
|
6600
|
+
const { format: format2, path: path3 } = detectConfigFormat();
|
|
6387
6601
|
try {
|
|
6388
6602
|
let existingConfig = null;
|
|
6389
6603
|
if (format2 !== "none") {
|
|
6390
|
-
const parseResult = parseConfigWithError(
|
|
6604
|
+
const parseResult = parseConfigWithError(path3);
|
|
6391
6605
|
if (parseResult.error && !parseResult.config) {
|
|
6392
6606
|
existingConfig = {};
|
|
6393
6607
|
} else {
|
|
@@ -6402,11 +6616,31 @@ function addProviderConfig(config) {
|
|
|
6402
6616
|
if (Object.keys(providers).length > 0) {
|
|
6403
6617
|
newConfig.provider = providers;
|
|
6404
6618
|
}
|
|
6405
|
-
writeFileSync(
|
|
6619
|
+
writeFileSync(path3, JSON.stringify(newConfig, null, 2) + `
|
|
6406
6620
|
`);
|
|
6407
|
-
return { success: true, configPath:
|
|
6621
|
+
return { success: true, configPath: path3 };
|
|
6408
6622
|
} catch (err) {
|
|
6409
|
-
return { success: false, configPath:
|
|
6623
|
+
return { success: false, configPath: path3, error: formatErrorWithSuggestion(err, "add provider config") };
|
|
6624
|
+
}
|
|
6625
|
+
}
|
|
6626
|
+
function detectProvidersFromOmoConfig() {
|
|
6627
|
+
const omoConfigPath = getOmoConfig();
|
|
6628
|
+
if (!existsSync4(omoConfigPath)) {
|
|
6629
|
+
return { hasOpenAI: true, hasOpencodeZen: true, hasZaiCodingPlan: false };
|
|
6630
|
+
}
|
|
6631
|
+
try {
|
|
6632
|
+
const content = readFileSync3(omoConfigPath, "utf-8");
|
|
6633
|
+
const omoConfig = parseJsonc(content);
|
|
6634
|
+
if (!omoConfig || typeof omoConfig !== "object") {
|
|
6635
|
+
return { hasOpenAI: true, hasOpencodeZen: true, hasZaiCodingPlan: false };
|
|
6636
|
+
}
|
|
6637
|
+
const configStr = JSON.stringify(omoConfig);
|
|
6638
|
+
const hasOpenAI = configStr.includes('"openai/');
|
|
6639
|
+
const hasOpencodeZen = configStr.includes('"opencode/');
|
|
6640
|
+
const hasZaiCodingPlan = configStr.includes('"zai-coding-plan/');
|
|
6641
|
+
return { hasOpenAI, hasOpencodeZen, hasZaiCodingPlan };
|
|
6642
|
+
} catch {
|
|
6643
|
+
return { hasOpenAI: true, hasOpencodeZen: true, hasZaiCodingPlan: false };
|
|
6410
6644
|
}
|
|
6411
6645
|
}
|
|
6412
6646
|
function detectCurrentConfig() {
|
|
@@ -6414,15 +6648,17 @@ function detectCurrentConfig() {
|
|
|
6414
6648
|
isInstalled: false,
|
|
6415
6649
|
hasClaude: true,
|
|
6416
6650
|
isMax20: true,
|
|
6417
|
-
|
|
6651
|
+
hasOpenAI: true,
|
|
6418
6652
|
hasGemini: false,
|
|
6419
|
-
hasCopilot: false
|
|
6653
|
+
hasCopilot: false,
|
|
6654
|
+
hasOpencodeZen: true,
|
|
6655
|
+
hasZaiCodingPlan: false
|
|
6420
6656
|
};
|
|
6421
|
-
const { format: format2, path:
|
|
6657
|
+
const { format: format2, path: path3 } = detectConfigFormat();
|
|
6422
6658
|
if (format2 === "none") {
|
|
6423
6659
|
return result;
|
|
6424
6660
|
}
|
|
6425
|
-
const parseResult = parseConfigWithError(
|
|
6661
|
+
const parseResult = parseConfigWithError(path3);
|
|
6426
6662
|
if (!parseResult.config) {
|
|
6427
6663
|
return result;
|
|
6428
6664
|
}
|
|
@@ -6433,44 +6669,16 @@ function detectCurrentConfig() {
|
|
|
6433
6669
|
return result;
|
|
6434
6670
|
}
|
|
6435
6671
|
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 {}
|
|
6672
|
+
const { hasOpenAI, hasOpencodeZen, hasZaiCodingPlan } = detectProvidersFromOmoConfig();
|
|
6673
|
+
result.hasOpenAI = hasOpenAI;
|
|
6674
|
+
result.hasOpencodeZen = hasOpencodeZen;
|
|
6675
|
+
result.hasZaiCodingPlan = hasZaiCodingPlan;
|
|
6469
6676
|
return result;
|
|
6470
6677
|
}
|
|
6471
6678
|
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
6679
|
var init_config_manager = __esm(() => {
|
|
6473
6680
|
init_shared();
|
|
6681
|
+
init_model_fallback();
|
|
6474
6682
|
OPENCODE_BINARIES = ["opencode", "opencode-desktop"];
|
|
6475
6683
|
BUN_INSTALL_TIMEOUT_MS = BUN_INSTALL_TIMEOUT_SECONDS * 1000;
|
|
6476
6684
|
PRIORITIZED_TAGS = ["latest", "beta", "next"];
|
|
@@ -6504,56 +6712,43 @@ var init_config_manager = __esm(() => {
|
|
|
6504
6712
|
});
|
|
6505
6713
|
|
|
6506
6714
|
// src/hooks/auto-update-checker/constants.ts
|
|
6507
|
-
import * as
|
|
6508
|
-
import * as
|
|
6509
|
-
import * as fs2 from "fs";
|
|
6715
|
+
import * as path3 from "path";
|
|
6716
|
+
import * as os3 from "os";
|
|
6510
6717
|
function getCacheDir() {
|
|
6511
6718
|
if (process.platform === "win32") {
|
|
6512
|
-
return
|
|
6719
|
+
return path3.join(process.env.LOCALAPPDATA ?? os3.homedir(), "opencode");
|
|
6513
6720
|
}
|
|
6514
|
-
return
|
|
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;
|
|
6526
|
-
}
|
|
6527
|
-
return process.env.XDG_CONFIG_HOME ?? path2.join(os2.homedir(), ".config");
|
|
6721
|
+
return path3.join(os3.homedir(), ".cache", "opencode");
|
|
6528
6722
|
}
|
|
6529
6723
|
function getWindowsAppdataDir() {
|
|
6530
6724
|
if (process.platform !== "win32")
|
|
6531
6725
|
return null;
|
|
6532
|
-
return process.env.APPDATA ??
|
|
6726
|
+
return process.env.APPDATA ?? path3.join(os3.homedir(), "AppData", "Roaming");
|
|
6533
6727
|
}
|
|
6534
6728
|
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
6729
|
var init_constants = __esm(() => {
|
|
6730
|
+
init_shared();
|
|
6536
6731
|
NPM_REGISTRY_URL = `https://registry.npmjs.org/-/package/${PACKAGE_NAME2}/dist-tags`;
|
|
6537
6732
|
CACHE_DIR = getCacheDir();
|
|
6538
|
-
VERSION_FILE =
|
|
6539
|
-
INSTALLED_PACKAGE_JSON =
|
|
6540
|
-
USER_CONFIG_DIR =
|
|
6541
|
-
USER_OPENCODE_CONFIG =
|
|
6542
|
-
USER_OPENCODE_CONFIG_JSONC =
|
|
6733
|
+
VERSION_FILE = path3.join(CACHE_DIR, "version");
|
|
6734
|
+
INSTALLED_PACKAGE_JSON = path3.join(CACHE_DIR, "node_modules", PACKAGE_NAME2, "package.json");
|
|
6735
|
+
USER_CONFIG_DIR = getOpenCodeConfigDir({ binary: "opencode" });
|
|
6736
|
+
USER_OPENCODE_CONFIG = path3.join(USER_CONFIG_DIR, "opencode.json");
|
|
6737
|
+
USER_OPENCODE_CONFIG_JSONC = path3.join(USER_CONFIG_DIR, "opencode.jsonc");
|
|
6543
6738
|
});
|
|
6544
6739
|
|
|
6545
6740
|
// src/hooks/auto-update-checker/cache.ts
|
|
6546
|
-
import * as
|
|
6547
|
-
import * as
|
|
6741
|
+
import * as fs2 from "fs";
|
|
6742
|
+
import * as path4 from "path";
|
|
6548
6743
|
function stripTrailingCommas(json2) {
|
|
6549
6744
|
return json2.replace(/,(\s*[}\]])/g, "$1");
|
|
6550
6745
|
}
|
|
6551
6746
|
function removeFromBunLock(packageName) {
|
|
6552
|
-
const lockPath =
|
|
6553
|
-
if (!
|
|
6747
|
+
const lockPath = path4.join(CACHE_DIR, "bun.lock");
|
|
6748
|
+
if (!fs2.existsSync(lockPath))
|
|
6554
6749
|
return false;
|
|
6555
6750
|
try {
|
|
6556
|
-
const content =
|
|
6751
|
+
const content = fs2.readFileSync(lockPath, "utf-8");
|
|
6557
6752
|
const lock = JSON.parse(stripTrailingCommas(content));
|
|
6558
6753
|
let modified = false;
|
|
6559
6754
|
if (lock.workspaces?.[""]?.dependencies?.[packageName]) {
|
|
@@ -6565,7 +6760,7 @@ function removeFromBunLock(packageName) {
|
|
|
6565
6760
|
modified = true;
|
|
6566
6761
|
}
|
|
6567
6762
|
if (modified) {
|
|
6568
|
-
|
|
6763
|
+
fs2.writeFileSync(lockPath, JSON.stringify(lock, null, 2));
|
|
6569
6764
|
log(`[auto-update-checker] Removed from bun.lock: ${packageName}`);
|
|
6570
6765
|
}
|
|
6571
6766
|
return modified;
|
|
@@ -6575,22 +6770,22 @@ function removeFromBunLock(packageName) {
|
|
|
6575
6770
|
}
|
|
6576
6771
|
function invalidatePackage(packageName = PACKAGE_NAME2) {
|
|
6577
6772
|
try {
|
|
6578
|
-
const pkgDir =
|
|
6579
|
-
const pkgJsonPath =
|
|
6773
|
+
const pkgDir = path4.join(CACHE_DIR, "node_modules", packageName);
|
|
6774
|
+
const pkgJsonPath = path4.join(CACHE_DIR, "package.json");
|
|
6580
6775
|
let packageRemoved = false;
|
|
6581
6776
|
let dependencyRemoved = false;
|
|
6582
6777
|
let lockRemoved = false;
|
|
6583
|
-
if (
|
|
6584
|
-
|
|
6778
|
+
if (fs2.existsSync(pkgDir)) {
|
|
6779
|
+
fs2.rmSync(pkgDir, { recursive: true, force: true });
|
|
6585
6780
|
log(`[auto-update-checker] Package removed: ${pkgDir}`);
|
|
6586
6781
|
packageRemoved = true;
|
|
6587
6782
|
}
|
|
6588
|
-
if (
|
|
6589
|
-
const content =
|
|
6783
|
+
if (fs2.existsSync(pkgJsonPath)) {
|
|
6784
|
+
const content = fs2.readFileSync(pkgJsonPath, "utf-8");
|
|
6590
6785
|
const pkgJson = JSON.parse(content);
|
|
6591
6786
|
if (pkgJson.dependencies?.[packageName]) {
|
|
6592
6787
|
delete pkgJson.dependencies[packageName];
|
|
6593
|
-
|
|
6788
|
+
fs2.writeFileSync(pkgJsonPath, JSON.stringify(pkgJson, null, 2));
|
|
6594
6789
|
log(`[auto-update-checker] Dependency removed from package.json: ${packageName}`);
|
|
6595
6790
|
dependencyRemoved = true;
|
|
6596
6791
|
}
|
|
@@ -6682,6 +6877,7 @@ v${latestVersion} available. Restart OpenCode to apply.` : `OpenCode is now on S
|
|
|
6682
6877
|
const localDevVersion = getLocalDevVersion(ctx.directory);
|
|
6683
6878
|
const displayVersion = localDevVersion ?? cachedVersion;
|
|
6684
6879
|
await showConfigErrorsIfAny(ctx);
|
|
6880
|
+
await showModelCacheWarningIfNeeded(ctx);
|
|
6685
6881
|
if (localDevVersion) {
|
|
6686
6882
|
if (showStartupToast) {
|
|
6687
6883
|
showLocalDevToast(ctx, displayVersion, isSisyphusEnabled).catch(() => {});
|
|
@@ -6755,6 +6951,19 @@ async function runBunInstallSafe() {
|
|
|
6755
6951
|
return false;
|
|
6756
6952
|
}
|
|
6757
6953
|
}
|
|
6954
|
+
async function showModelCacheWarningIfNeeded(ctx) {
|
|
6955
|
+
if (isModelCacheAvailable())
|
|
6956
|
+
return;
|
|
6957
|
+
await ctx.client.tui.showToast({
|
|
6958
|
+
body: {
|
|
6959
|
+
title: "Model Cache Not Found",
|
|
6960
|
+
message: "Run 'opencode models --refresh' or restart OpenCode to populate the models cache for optimal agent model selection.",
|
|
6961
|
+
variant: "warning",
|
|
6962
|
+
duration: 1e4
|
|
6963
|
+
}
|
|
6964
|
+
}).catch(() => {});
|
|
6965
|
+
log("[auto-update-checker] Model cache warning shown");
|
|
6966
|
+
}
|
|
6758
6967
|
async function showConfigErrorsIfAny(ctx) {
|
|
6759
6968
|
const errors = getConfigLoadErrors();
|
|
6760
6969
|
if (errors.length === 0)
|
|
@@ -6832,16 +7041,17 @@ var init_auto_update_checker = __esm(() => {
|
|
|
6832
7041
|
init_logger();
|
|
6833
7042
|
init_config_errors();
|
|
6834
7043
|
init_config_manager();
|
|
7044
|
+
init_model_availability();
|
|
6835
7045
|
init_checker();
|
|
6836
7046
|
init_cache();
|
|
6837
7047
|
SISYPHUS_SPINNER = ["\xB7", "\u2022", "\u25CF", "\u25CB", "\u25CC", "\u25E6", " "];
|
|
6838
7048
|
});
|
|
6839
7049
|
|
|
6840
7050
|
// src/hooks/auto-update-checker/checker.ts
|
|
6841
|
-
import * as
|
|
6842
|
-
import * as
|
|
7051
|
+
import * as fs3 from "fs";
|
|
7052
|
+
import * as path5 from "path";
|
|
6843
7053
|
import { fileURLToPath } from "url";
|
|
6844
|
-
import * as
|
|
7054
|
+
import * as os4 from "os";
|
|
6845
7055
|
function isLocalDevMode(directory) {
|
|
6846
7056
|
return getLocalDevPath(directory) !== null;
|
|
6847
7057
|
}
|
|
@@ -6850,18 +7060,18 @@ function stripJsonComments(json2) {
|
|
|
6850
7060
|
}
|
|
6851
7061
|
function getConfigPaths(directory) {
|
|
6852
7062
|
const paths = [
|
|
6853
|
-
|
|
6854
|
-
|
|
7063
|
+
path5.join(directory, ".opencode", "opencode.json"),
|
|
7064
|
+
path5.join(directory, ".opencode", "opencode.jsonc"),
|
|
6855
7065
|
USER_OPENCODE_CONFIG,
|
|
6856
7066
|
USER_OPENCODE_CONFIG_JSONC
|
|
6857
7067
|
];
|
|
6858
7068
|
if (process.platform === "win32") {
|
|
6859
|
-
const crossPlatformDir =
|
|
7069
|
+
const crossPlatformDir = path5.join(os4.homedir(), ".config");
|
|
6860
7070
|
const appdataDir = getWindowsAppdataDir();
|
|
6861
7071
|
if (appdataDir) {
|
|
6862
7072
|
const alternateDir = USER_CONFIG_DIR === crossPlatformDir ? appdataDir : crossPlatformDir;
|
|
6863
|
-
const alternateConfig =
|
|
6864
|
-
const alternateConfigJsonc =
|
|
7073
|
+
const alternateConfig = path5.join(alternateDir, "opencode", "opencode.json");
|
|
7074
|
+
const alternateConfigJsonc = path5.join(alternateDir, "opencode", "opencode.jsonc");
|
|
6865
7075
|
if (!paths.includes(alternateConfig)) {
|
|
6866
7076
|
paths.push(alternateConfig);
|
|
6867
7077
|
}
|
|
@@ -6875,9 +7085,9 @@ function getConfigPaths(directory) {
|
|
|
6875
7085
|
function getLocalDevPath(directory) {
|
|
6876
7086
|
for (const configPath of getConfigPaths(directory)) {
|
|
6877
7087
|
try {
|
|
6878
|
-
if (!
|
|
7088
|
+
if (!fs3.existsSync(configPath))
|
|
6879
7089
|
continue;
|
|
6880
|
-
const content =
|
|
7090
|
+
const content = fs3.readFileSync(configPath, "utf-8");
|
|
6881
7091
|
const config = JSON.parse(stripJsonComments(content));
|
|
6882
7092
|
const plugins = config.plugin ?? [];
|
|
6883
7093
|
for (const entry of plugins) {
|
|
@@ -6897,19 +7107,19 @@ function getLocalDevPath(directory) {
|
|
|
6897
7107
|
}
|
|
6898
7108
|
function findPackageJsonUp(startPath) {
|
|
6899
7109
|
try {
|
|
6900
|
-
const stat =
|
|
6901
|
-
let dir = stat.isDirectory() ? startPath :
|
|
7110
|
+
const stat = fs3.statSync(startPath);
|
|
7111
|
+
let dir = stat.isDirectory() ? startPath : path5.dirname(startPath);
|
|
6902
7112
|
for (let i2 = 0;i2 < 10; i2++) {
|
|
6903
|
-
const pkgPath =
|
|
6904
|
-
if (
|
|
7113
|
+
const pkgPath = path5.join(dir, "package.json");
|
|
7114
|
+
if (fs3.existsSync(pkgPath)) {
|
|
6905
7115
|
try {
|
|
6906
|
-
const content =
|
|
7116
|
+
const content = fs3.readFileSync(pkgPath, "utf-8");
|
|
6907
7117
|
const pkg = JSON.parse(content);
|
|
6908
7118
|
if (pkg.name === PACKAGE_NAME2)
|
|
6909
7119
|
return pkgPath;
|
|
6910
7120
|
} catch {}
|
|
6911
7121
|
}
|
|
6912
|
-
const parent =
|
|
7122
|
+
const parent = path5.dirname(dir);
|
|
6913
7123
|
if (parent === dir)
|
|
6914
7124
|
break;
|
|
6915
7125
|
dir = parent;
|
|
@@ -6925,7 +7135,7 @@ function getLocalDevVersion(directory) {
|
|
|
6925
7135
|
const pkgPath = findPackageJsonUp(localPath);
|
|
6926
7136
|
if (!pkgPath)
|
|
6927
7137
|
return null;
|
|
6928
|
-
const content =
|
|
7138
|
+
const content = fs3.readFileSync(pkgPath, "utf-8");
|
|
6929
7139
|
const pkg = JSON.parse(content);
|
|
6930
7140
|
return pkg.version ?? null;
|
|
6931
7141
|
} catch {
|
|
@@ -6935,9 +7145,9 @@ function getLocalDevVersion(directory) {
|
|
|
6935
7145
|
function findPluginEntry(directory) {
|
|
6936
7146
|
for (const configPath of getConfigPaths(directory)) {
|
|
6937
7147
|
try {
|
|
6938
|
-
if (!
|
|
7148
|
+
if (!fs3.existsSync(configPath))
|
|
6939
7149
|
continue;
|
|
6940
|
-
const content =
|
|
7150
|
+
const content = fs3.readFileSync(configPath, "utf-8");
|
|
6941
7151
|
const config = JSON.parse(stripJsonComments(content));
|
|
6942
7152
|
const plugins = config.plugin ?? [];
|
|
6943
7153
|
for (const entry of plugins) {
|
|
@@ -6958,18 +7168,18 @@ function findPluginEntry(directory) {
|
|
|
6958
7168
|
}
|
|
6959
7169
|
function getCachedVersion() {
|
|
6960
7170
|
try {
|
|
6961
|
-
if (
|
|
6962
|
-
const content =
|
|
7171
|
+
if (fs3.existsSync(INSTALLED_PACKAGE_JSON)) {
|
|
7172
|
+
const content = fs3.readFileSync(INSTALLED_PACKAGE_JSON, "utf-8");
|
|
6963
7173
|
const pkg = JSON.parse(content);
|
|
6964
7174
|
if (pkg.version)
|
|
6965
7175
|
return pkg.version;
|
|
6966
7176
|
}
|
|
6967
7177
|
} catch {}
|
|
6968
7178
|
try {
|
|
6969
|
-
const currentDir =
|
|
7179
|
+
const currentDir = path5.dirname(fileURLToPath(import.meta.url));
|
|
6970
7180
|
const pkgPath = findPackageJsonUp(currentDir);
|
|
6971
7181
|
if (pkgPath) {
|
|
6972
|
-
const content =
|
|
7182
|
+
const content = fs3.readFileSync(pkgPath, "utf-8");
|
|
6973
7183
|
const pkg = JSON.parse(content);
|
|
6974
7184
|
if (pkg.version)
|
|
6975
7185
|
return pkg.version;
|
|
@@ -6981,7 +7191,7 @@ function getCachedVersion() {
|
|
|
6981
7191
|
}
|
|
6982
7192
|
function updatePinnedVersion(configPath, oldEntry, newVersion) {
|
|
6983
7193
|
try {
|
|
6984
|
-
const content =
|
|
7194
|
+
const content = fs3.readFileSync(configPath, "utf-8");
|
|
6985
7195
|
const newEntry = `${PACKAGE_NAME2}@${newVersion}`;
|
|
6986
7196
|
const pluginMatch = content.match(/"plugin"\s*:\s*\[/);
|
|
6987
7197
|
if (!pluginMatch || pluginMatch.index === undefined) {
|
|
@@ -7013,7 +7223,7 @@ function updatePinnedVersion(configPath, oldEntry, newVersion) {
|
|
|
7013
7223
|
log(`[auto-update-checker] No changes made to ${configPath}`);
|
|
7014
7224
|
return false;
|
|
7015
7225
|
}
|
|
7016
|
-
|
|
7226
|
+
fs3.writeFileSync(configPath, updatedContent, "utf-8");
|
|
7017
7227
|
log(`[auto-update-checker] Updated ${configPath}: ${oldEntry} \u2192 ${newEntry}`);
|
|
7018
7228
|
return true;
|
|
7019
7229
|
} catch (err) {
|
|
@@ -7672,7 +7882,7 @@ var import_picocolors2 = __toESM(require_picocolors(), 1);
|
|
|
7672
7882
|
// package.json
|
|
7673
7883
|
var package_default = {
|
|
7674
7884
|
name: "oh-my-opencode",
|
|
7675
|
-
version: "3.0.0
|
|
7885
|
+
version: "3.0.0",
|
|
7676
7886
|
description: "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
|
|
7677
7887
|
main: "dist/index.js",
|
|
7678
7888
|
types: "dist/index.d.ts",
|
|
@@ -7728,18 +7938,14 @@ var package_default = {
|
|
|
7728
7938
|
"@clack/prompts": "^0.11.0",
|
|
7729
7939
|
"@code-yeongyu/comment-checker": "^0.6.1",
|
|
7730
7940
|
"@modelcontextprotocol/sdk": "^1.25.1",
|
|
7731
|
-
"@openauthjs/openauth": "^0.4.3",
|
|
7732
7941
|
"@opencode-ai/plugin": "^1.1.19",
|
|
7733
7942
|
"@opencode-ai/sdk": "^1.1.19",
|
|
7734
7943
|
commander: "^14.0.2",
|
|
7735
7944
|
"detect-libc": "^2.0.0",
|
|
7736
|
-
hono: "^4.10.4",
|
|
7737
7945
|
"js-yaml": "^4.1.1",
|
|
7738
7946
|
"jsonc-parser": "^3.3.1",
|
|
7739
|
-
open: "^11.0.0",
|
|
7740
7947
|
picocolors: "^1.1.1",
|
|
7741
7948
|
picomatch: "^4.0.2",
|
|
7742
|
-
"xdg-basedir": "^5.1.0",
|
|
7743
7949
|
zod: "^4.1.8"
|
|
7744
7950
|
},
|
|
7745
7951
|
devDependencies: {
|
|
@@ -7749,13 +7955,13 @@ var package_default = {
|
|
|
7749
7955
|
typescript: "^5.7.3"
|
|
7750
7956
|
},
|
|
7751
7957
|
optionalDependencies: {
|
|
7752
|
-
"oh-my-opencode-darwin-arm64": "3.0.0
|
|
7753
|
-
"oh-my-opencode-darwin-x64": "3.0.0
|
|
7754
|
-
"oh-my-opencode-linux-arm64": "3.0.0
|
|
7755
|
-
"oh-my-opencode-linux-arm64-musl": "3.0.0
|
|
7756
|
-
"oh-my-opencode-linux-x64": "3.0.0
|
|
7757
|
-
"oh-my-opencode-linux-x64-musl": "3.0.0
|
|
7758
|
-
"oh-my-opencode-windows-x64": "3.0.0
|
|
7958
|
+
"oh-my-opencode-darwin-arm64": "3.0.0",
|
|
7959
|
+
"oh-my-opencode-darwin-x64": "3.0.0",
|
|
7960
|
+
"oh-my-opencode-linux-arm64": "3.0.0",
|
|
7961
|
+
"oh-my-opencode-linux-arm64-musl": "3.0.0",
|
|
7962
|
+
"oh-my-opencode-linux-x64": "3.0.0",
|
|
7963
|
+
"oh-my-opencode-linux-x64-musl": "3.0.0",
|
|
7964
|
+
"oh-my-opencode-windows-x64": "3.0.0"
|
|
7759
7965
|
},
|
|
7760
7966
|
trustedDependencies: [
|
|
7761
7967
|
"@ast-grep/cli",
|
|
@@ -7767,13 +7973,13 @@ var package_default = {
|
|
|
7767
7973
|
// src/cli/install.ts
|
|
7768
7974
|
var VERSION = package_default.version;
|
|
7769
7975
|
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("
|
|
7976
|
+
check: import_picocolors2.default.green("[OK]"),
|
|
7977
|
+
cross: import_picocolors2.default.red("[X]"),
|
|
7978
|
+
arrow: import_picocolors2.default.cyan("->"),
|
|
7979
|
+
bullet: import_picocolors2.default.dim("*"),
|
|
7980
|
+
info: import_picocolors2.default.blue("[i]"),
|
|
7981
|
+
warn: import_picocolors2.default.yellow("[!]"),
|
|
7982
|
+
star: import_picocolors2.default.yellow("*")
|
|
7777
7983
|
};
|
|
7778
7984
|
function formatProvider(name, enabled, detail) {
|
|
7779
7985
|
const status = enabled ? SYMBOLS.check : import_picocolors2.default.dim("\u25CB");
|
|
@@ -7787,22 +7993,18 @@ function formatConfigSummary(config) {
|
|
|
7787
7993
|
lines.push("");
|
|
7788
7994
|
const claudeDetail = config.hasClaude ? config.isMax20 ? "max20" : "standard" : undefined;
|
|
7789
7995
|
lines.push(formatProvider("Claude", config.hasClaude, claudeDetail));
|
|
7790
|
-
lines.push(formatProvider("ChatGPT", config.
|
|
7996
|
+
lines.push(formatProvider("OpenAI/ChatGPT", config.hasOpenAI, "GPT-5.2 for Oracle"));
|
|
7791
7997
|
lines.push(formatProvider("Gemini", config.hasGemini));
|
|
7792
|
-
lines.push(formatProvider("GitHub Copilot", config.hasCopilot, "fallback
|
|
7998
|
+
lines.push(formatProvider("GitHub Copilot", config.hasCopilot, "fallback"));
|
|
7999
|
+
lines.push(formatProvider("OpenCode Zen", config.hasOpencodeZen, "opencode/ models"));
|
|
8000
|
+
lines.push(formatProvider("Z.ai Coding Plan", config.hasZaiCodingPlan, "Librarian/Multimodal"));
|
|
7793
8001
|
lines.push("");
|
|
7794
8002
|
lines.push(import_picocolors2.default.dim("\u2500".repeat(40)));
|
|
7795
8003
|
lines.push("");
|
|
7796
|
-
lines.push(import_picocolors2.default.bold(import_picocolors2.default.white("
|
|
8004
|
+
lines.push(import_picocolors2.default.bold(import_picocolors2.default.white("Model Assignment")));
|
|
7797
8005
|
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)}`);
|
|
8006
|
+
lines.push(` ${SYMBOLS.info} Models auto-configured based on provider priority`);
|
|
8007
|
+
lines.push(` ${SYMBOLS.bullet} Priority: Native > Copilot > OpenCode Zen > Z.ai`);
|
|
7806
8008
|
return lines.join(`
|
|
7807
8009
|
`);
|
|
7808
8010
|
}
|
|
@@ -7854,11 +8056,6 @@ function validateNonTuiArgs(args) {
|
|
|
7854
8056
|
} else if (!["no", "yes", "max20"].includes(args.claude)) {
|
|
7855
8057
|
errors.push(`Invalid --claude value: ${args.claude} (expected: no, yes, max20)`);
|
|
7856
8058
|
}
|
|
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
8059
|
if (args.gemini === undefined) {
|
|
7863
8060
|
errors.push("--gemini is required (values: no, yes)");
|
|
7864
8061
|
} else if (!["no", "yes"].includes(args.gemini)) {
|
|
@@ -7869,15 +8066,26 @@ function validateNonTuiArgs(args) {
|
|
|
7869
8066
|
} else if (!["no", "yes"].includes(args.copilot)) {
|
|
7870
8067
|
errors.push(`Invalid --copilot value: ${args.copilot} (expected: no, yes)`);
|
|
7871
8068
|
}
|
|
8069
|
+
if (args.openai !== undefined && !["no", "yes"].includes(args.openai)) {
|
|
8070
|
+
errors.push(`Invalid --openai value: ${args.openai} (expected: no, yes)`);
|
|
8071
|
+
}
|
|
8072
|
+
if (args.opencodeZen !== undefined && !["no", "yes"].includes(args.opencodeZen)) {
|
|
8073
|
+
errors.push(`Invalid --opencode-zen value: ${args.opencodeZen} (expected: no, yes)`);
|
|
8074
|
+
}
|
|
8075
|
+
if (args.zaiCodingPlan !== undefined && !["no", "yes"].includes(args.zaiCodingPlan)) {
|
|
8076
|
+
errors.push(`Invalid --zai-coding-plan value: ${args.zaiCodingPlan} (expected: no, yes)`);
|
|
8077
|
+
}
|
|
7872
8078
|
return { valid: errors.length === 0, errors };
|
|
7873
8079
|
}
|
|
7874
8080
|
function argsToConfig(args) {
|
|
7875
8081
|
return {
|
|
7876
8082
|
hasClaude: args.claude !== "no",
|
|
7877
8083
|
isMax20: args.claude === "max20",
|
|
7878
|
-
|
|
8084
|
+
hasOpenAI: args.openai === "yes",
|
|
7879
8085
|
hasGemini: args.gemini === "yes",
|
|
7880
|
-
hasCopilot: args.copilot === "yes"
|
|
8086
|
+
hasCopilot: args.copilot === "yes",
|
|
8087
|
+
hasOpencodeZen: args.opencodeZen === "yes",
|
|
8088
|
+
hasZaiCodingPlan: args.zaiCodingPlan === "yes"
|
|
7881
8089
|
};
|
|
7882
8090
|
}
|
|
7883
8091
|
function detectedToInitialValues(detected) {
|
|
@@ -7887,9 +8095,11 @@ function detectedToInitialValues(detected) {
|
|
|
7887
8095
|
}
|
|
7888
8096
|
return {
|
|
7889
8097
|
claude,
|
|
7890
|
-
|
|
8098
|
+
openai: detected.hasOpenAI ? "yes" : "no",
|
|
7891
8099
|
gemini: detected.hasGemini ? "yes" : "no",
|
|
7892
|
-
copilot: detected.hasCopilot ? "yes" : "no"
|
|
8100
|
+
copilot: detected.hasCopilot ? "yes" : "no",
|
|
8101
|
+
opencodeZen: detected.hasOpencodeZen ? "yes" : "no",
|
|
8102
|
+
zaiCodingPlan: detected.hasZaiCodingPlan ? "yes" : "no"
|
|
7893
8103
|
};
|
|
7894
8104
|
}
|
|
7895
8105
|
async function runTuiMode(detected) {
|
|
@@ -7897,7 +8107,7 @@ async function runTuiMode(detected) {
|
|
|
7897
8107
|
const claude = await ve({
|
|
7898
8108
|
message: "Do you have a Claude Pro/Max subscription?",
|
|
7899
8109
|
options: [
|
|
7900
|
-
{ value: "no", label: "No", hint: "Will use opencode/
|
|
8110
|
+
{ value: "no", label: "No", hint: "Will use opencode/big-pickle as fallback" },
|
|
7901
8111
|
{ value: "yes", label: "Yes (standard)", hint: "Claude Opus 4.5 for orchestration" },
|
|
7902
8112
|
{ value: "max20", label: "Yes (max20 mode)", hint: "Full power with Claude Sonnet 4.5 for Librarian" }
|
|
7903
8113
|
],
|
|
@@ -7907,15 +8117,15 @@ async function runTuiMode(detected) {
|
|
|
7907
8117
|
xe("Installation cancelled.");
|
|
7908
8118
|
return null;
|
|
7909
8119
|
}
|
|
7910
|
-
const
|
|
7911
|
-
message: "Do you have
|
|
8120
|
+
const openai = await ve({
|
|
8121
|
+
message: "Do you have an OpenAI/ChatGPT Plus subscription?",
|
|
7912
8122
|
options: [
|
|
7913
|
-
{ value: "no", label: "No", hint: "Oracle will use fallback
|
|
7914
|
-
{ value: "yes", label: "Yes", hint: "GPT-5.2 for
|
|
8123
|
+
{ value: "no", label: "No", hint: "Oracle will use fallback models" },
|
|
8124
|
+
{ value: "yes", label: "Yes", hint: "GPT-5.2 for Oracle (high-IQ debugging)" }
|
|
7915
8125
|
],
|
|
7916
|
-
initialValue: initial.
|
|
8126
|
+
initialValue: initial.openai
|
|
7917
8127
|
});
|
|
7918
|
-
if (pD(
|
|
8128
|
+
if (pD(openai)) {
|
|
7919
8129
|
xe("Installation cancelled.");
|
|
7920
8130
|
return null;
|
|
7921
8131
|
}
|
|
@@ -7943,12 +8153,38 @@ async function runTuiMode(detected) {
|
|
|
7943
8153
|
xe("Installation cancelled.");
|
|
7944
8154
|
return null;
|
|
7945
8155
|
}
|
|
8156
|
+
const opencodeZen = await ve({
|
|
8157
|
+
message: "Do you have access to OpenCode Zen (opencode/ models)?",
|
|
8158
|
+
options: [
|
|
8159
|
+
{ value: "no", label: "No", hint: "Will use other configured providers" },
|
|
8160
|
+
{ value: "yes", label: "Yes", hint: "opencode/claude-opus-4-5, opencode/gpt-5.2, etc." }
|
|
8161
|
+
],
|
|
8162
|
+
initialValue: initial.opencodeZen
|
|
8163
|
+
});
|
|
8164
|
+
if (pD(opencodeZen)) {
|
|
8165
|
+
xe("Installation cancelled.");
|
|
8166
|
+
return null;
|
|
8167
|
+
}
|
|
8168
|
+
const zaiCodingPlan = await ve({
|
|
8169
|
+
message: "Do you have a Z.ai Coding Plan subscription?",
|
|
8170
|
+
options: [
|
|
8171
|
+
{ value: "no", label: "No", hint: "Will use other configured providers" },
|
|
8172
|
+
{ value: "yes", label: "Yes", hint: "Fallback for Librarian and Multimodal Looker" }
|
|
8173
|
+
],
|
|
8174
|
+
initialValue: initial.zaiCodingPlan
|
|
8175
|
+
});
|
|
8176
|
+
if (pD(zaiCodingPlan)) {
|
|
8177
|
+
xe("Installation cancelled.");
|
|
8178
|
+
return null;
|
|
8179
|
+
}
|
|
7946
8180
|
return {
|
|
7947
8181
|
hasClaude: claude !== "no",
|
|
7948
8182
|
isMax20: claude === "max20",
|
|
7949
|
-
|
|
8183
|
+
hasOpenAI: openai === "yes",
|
|
7950
8184
|
hasGemini: gemini === "yes",
|
|
7951
|
-
hasCopilot: copilot === "yes"
|
|
8185
|
+
hasCopilot: copilot === "yes",
|
|
8186
|
+
hasOpencodeZen: opencodeZen === "yes",
|
|
8187
|
+
hasZaiCodingPlan: zaiCodingPlan === "yes"
|
|
7952
8188
|
};
|
|
7953
8189
|
}
|
|
7954
8190
|
async function runNonTuiInstall(args) {
|
|
@@ -7960,7 +8196,7 @@ async function runNonTuiInstall(args) {
|
|
|
7960
8196
|
console.log(` ${SYMBOLS.bullet} ${err}`);
|
|
7961
8197
|
}
|
|
7962
8198
|
console.log();
|
|
7963
|
-
printInfo("Usage: bunx oh-my-opencode install --no-tui --claude=<no|yes|max20> --
|
|
8199
|
+
printInfo("Usage: bunx oh-my-opencode install --no-tui --claude=<no|yes|max20> --gemini=<no|yes> --copilot=<no|yes>");
|
|
7964
8200
|
console.log();
|
|
7965
8201
|
return 1;
|
|
7966
8202
|
}
|
|
@@ -7971,16 +8207,16 @@ async function runNonTuiInstall(args) {
|
|
|
7971
8207
|
let step = 1;
|
|
7972
8208
|
printStep(step++, totalSteps, "Checking OpenCode installation...");
|
|
7973
8209
|
const installed = await isOpenCodeInstalled();
|
|
8210
|
+
const version = await getOpenCodeVersion();
|
|
7974
8211
|
if (!installed) {
|
|
7975
|
-
|
|
8212
|
+
printWarning("OpenCode binary not found. Plugin will be configured, but you'll need to install OpenCode to use it.");
|
|
7976
8213
|
printInfo("Visit https://opencode.ai/docs for installation instructions");
|
|
7977
|
-
|
|
8214
|
+
} else {
|
|
8215
|
+
printSuccess(`OpenCode ${version ?? ""} detected`);
|
|
7978
8216
|
}
|
|
7979
|
-
const version = await getOpenCodeVersion();
|
|
7980
|
-
printSuccess(`OpenCode ${version ?? ""} detected`);
|
|
7981
8217
|
if (isUpdate) {
|
|
7982
8218
|
const initial = detectedToInitialValues(detected);
|
|
7983
|
-
printInfo(`Current config: Claude=${initial.claude},
|
|
8219
|
+
printInfo(`Current config: Claude=${initial.claude}, Gemini=${initial.gemini}`);
|
|
7984
8220
|
}
|
|
7985
8221
|
const config = argsToConfig(args);
|
|
7986
8222
|
printStep(step++, totalSteps, "Adding oh-my-opencode plugin...");
|
|
@@ -8016,26 +8252,38 @@ async function runNonTuiInstall(args) {
|
|
|
8016
8252
|
}
|
|
8017
8253
|
printSuccess(`Config written ${SYMBOLS.arrow} ${import_picocolors2.default.dim(omoResult.configPath)}`);
|
|
8018
8254
|
printBox(formatConfigSummary(config), isUpdate ? "Updated Configuration" : "Installation Complete");
|
|
8019
|
-
if (!config.hasClaude
|
|
8020
|
-
|
|
8255
|
+
if (!config.hasClaude) {
|
|
8256
|
+
console.log();
|
|
8257
|
+
console.log(import_picocolors2.default.bgRed(import_picocolors2.default.white(import_picocolors2.default.bold(" CRITICAL WARNING "))));
|
|
8258
|
+
console.log();
|
|
8259
|
+
console.log(import_picocolors2.default.red(import_picocolors2.default.bold(" Sisyphus agent is STRONGLY optimized for Claude Opus 4.5.")));
|
|
8260
|
+
console.log(import_picocolors2.default.red(" Without Claude, you may experience significantly degraded performance:"));
|
|
8261
|
+
console.log(import_picocolors2.default.dim(" \u2022 Reduced orchestration quality"));
|
|
8262
|
+
console.log(import_picocolors2.default.dim(" \u2022 Weaker tool selection and delegation"));
|
|
8263
|
+
console.log(import_picocolors2.default.dim(" \u2022 Less reliable task completion"));
|
|
8264
|
+
console.log();
|
|
8265
|
+
console.log(import_picocolors2.default.yellow(" Consider subscribing to Claude Pro/Max for the best experience."));
|
|
8266
|
+
console.log();
|
|
8267
|
+
}
|
|
8268
|
+
if (!config.hasClaude && !config.hasOpenAI && !config.hasGemini && !config.hasCopilot && !config.hasOpencodeZen) {
|
|
8269
|
+
printWarning("No model providers configured. Using opencode/big-pickle as fallback.");
|
|
8021
8270
|
}
|
|
8022
8271
|
console.log(`${SYMBOLS.star} ${import_picocolors2.default.bold(import_picocolors2.default.green(isUpdate ? "Configuration updated!" : "Installation complete!"))}`);
|
|
8023
8272
|
console.log(` Run ${import_picocolors2.default.cyan("opencode")} to start!`);
|
|
8024
8273
|
console.log();
|
|
8025
8274
|
printBox(`${import_picocolors2.default.bold("Pro Tip:")} Include ${import_picocolors2.default.cyan("ultrawork")} (or ${import_picocolors2.default.cyan("ulw")}) in your prompt.
|
|
8026
8275
|
` + `All features work like magic\u2014parallel agents, background tasks,
|
|
8027
|
-
` + `deep exploration, and relentless execution until completion.`, "
|
|
8276
|
+
` + `deep exploration, and relentless execution until completion.`, "The Magic Word");
|
|
8028
8277
|
console.log(`${SYMBOLS.star} ${import_picocolors2.default.yellow("If you found this helpful, consider starring the repo!")}`);
|
|
8029
8278
|
console.log(` ${import_picocolors2.default.dim("gh repo star code-yeongyu/oh-my-opencode")}`);
|
|
8030
8279
|
console.log();
|
|
8031
8280
|
console.log(import_picocolors2.default.dim("oMoMoMoMo... Enjoy!"));
|
|
8032
8281
|
console.log();
|
|
8033
|
-
if ((config.hasClaude || config.
|
|
8282
|
+
if ((config.hasClaude || config.hasGemini || config.hasCopilot) && !args.skipAuth) {
|
|
8034
8283
|
printBox(`Run ${import_picocolors2.default.cyan("opencode auth login")} and select your provider:
|
|
8035
8284
|
` + (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
8285
|
` : "") + (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")}` : ""), "
|
|
8286
|
+
` : "") + (config.hasCopilot ? ` ${SYMBOLS.bullet} GitHub ${import_picocolors2.default.gray("\u2192 Copilot")}` : ""), "Authenticate Your Providers");
|
|
8039
8287
|
}
|
|
8040
8288
|
return 0;
|
|
8041
8289
|
}
|
|
@@ -8048,20 +8296,19 @@ async function install(args) {
|
|
|
8048
8296
|
Ie(import_picocolors2.default.bgMagenta(import_picocolors2.default.white(isUpdate ? " oMoMoMoMo... Update " : " oMoMoMoMo... ")));
|
|
8049
8297
|
if (isUpdate) {
|
|
8050
8298
|
const initial = detectedToInitialValues(detected);
|
|
8051
|
-
M2.info(`Existing configuration detected: Claude=${initial.claude},
|
|
8299
|
+
M2.info(`Existing configuration detected: Claude=${initial.claude}, Gemini=${initial.gemini}`);
|
|
8052
8300
|
}
|
|
8053
8301
|
const s = Y2();
|
|
8054
8302
|
s.start("Checking OpenCode installation");
|
|
8055
8303
|
const installed = await isOpenCodeInstalled();
|
|
8304
|
+
const version = await getOpenCodeVersion();
|
|
8056
8305
|
if (!installed) {
|
|
8057
|
-
s.stop(
|
|
8058
|
-
M2.
|
|
8306
|
+
s.stop(`OpenCode binary not found ${import_picocolors2.default.yellow("[!]")}`);
|
|
8307
|
+
M2.warn("OpenCode binary not found. Plugin will be configured, but you'll need to install OpenCode to use it.");
|
|
8059
8308
|
Me("Visit https://opencode.ai/docs for installation instructions", "Installation Guide");
|
|
8060
|
-
|
|
8061
|
-
|
|
8309
|
+
} else {
|
|
8310
|
+
s.stop(`OpenCode ${version ?? "installed"} ${import_picocolors2.default.green("[OK]")}`);
|
|
8062
8311
|
}
|
|
8063
|
-
const version = await getOpenCodeVersion();
|
|
8064
|
-
s.stop(`OpenCode ${version ?? "installed"} ${import_picocolors2.default.green("\u2713")}`);
|
|
8065
8312
|
const config = await runTuiMode(detected);
|
|
8066
8313
|
if (!config)
|
|
8067
8314
|
return 1;
|
|
@@ -8099,30 +8346,41 @@ async function install(args) {
|
|
|
8099
8346
|
return 1;
|
|
8100
8347
|
}
|
|
8101
8348
|
s.stop(`Config written to ${import_picocolors2.default.cyan(omoResult.configPath)}`);
|
|
8102
|
-
if (!config.hasClaude
|
|
8103
|
-
|
|
8349
|
+
if (!config.hasClaude) {
|
|
8350
|
+
console.log();
|
|
8351
|
+
console.log(import_picocolors2.default.bgRed(import_picocolors2.default.white(import_picocolors2.default.bold(" CRITICAL WARNING "))));
|
|
8352
|
+
console.log();
|
|
8353
|
+
console.log(import_picocolors2.default.red(import_picocolors2.default.bold(" Sisyphus agent is STRONGLY optimized for Claude Opus 4.5.")));
|
|
8354
|
+
console.log(import_picocolors2.default.red(" Without Claude, you may experience significantly degraded performance:"));
|
|
8355
|
+
console.log(import_picocolors2.default.dim(" \u2022 Reduced orchestration quality"));
|
|
8356
|
+
console.log(import_picocolors2.default.dim(" \u2022 Weaker tool selection and delegation"));
|
|
8357
|
+
console.log(import_picocolors2.default.dim(" \u2022 Less reliable task completion"));
|
|
8358
|
+
console.log();
|
|
8359
|
+
console.log(import_picocolors2.default.yellow(" Consider subscribing to Claude Pro/Max for the best experience."));
|
|
8360
|
+
console.log();
|
|
8361
|
+
}
|
|
8362
|
+
if (!config.hasClaude && !config.hasOpenAI && !config.hasGemini && !config.hasCopilot && !config.hasOpencodeZen) {
|
|
8363
|
+
M2.warn("No model providers configured. Using opencode/big-pickle as fallback.");
|
|
8104
8364
|
}
|
|
8105
8365
|
Me(formatConfigSummary(config), isUpdate ? "Updated Configuration" : "Installation Complete");
|
|
8106
8366
|
M2.success(import_picocolors2.default.bold(isUpdate ? "Configuration updated!" : "Installation complete!"));
|
|
8107
8367
|
M2.message(`Run ${import_picocolors2.default.cyan("opencode")} to start!`);
|
|
8108
8368
|
Me(`Include ${import_picocolors2.default.cyan("ultrawork")} (or ${import_picocolors2.default.cyan("ulw")}) in your prompt.
|
|
8109
8369
|
` + `All features work like magic\u2014parallel agents, background tasks,
|
|
8110
|
-
` + `deep exploration, and relentless execution until completion.`, "
|
|
8370
|
+
` + `deep exploration, and relentless execution until completion.`, "The Magic Word");
|
|
8111
8371
|
M2.message(`${import_picocolors2.default.yellow("\u2605")} If you found this helpful, consider starring the repo!`);
|
|
8112
8372
|
M2.message(` ${import_picocolors2.default.dim("gh repo star code-yeongyu/oh-my-opencode")}`);
|
|
8113
8373
|
Se(import_picocolors2.default.green("oMoMoMoMo... Enjoy!"));
|
|
8114
|
-
if ((config.hasClaude || config.
|
|
8374
|
+
if ((config.hasClaude || config.hasGemini || config.hasCopilot) && !args.skipAuth) {
|
|
8115
8375
|
const providers = [];
|
|
8116
8376
|
if (config.hasClaude)
|
|
8117
8377
|
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
8378
|
if (config.hasGemini)
|
|
8121
8379
|
providers.push(`Google ${import_picocolors2.default.gray("\u2192 OAuth with Antigravity")}`);
|
|
8122
8380
|
if (config.hasCopilot)
|
|
8123
8381
|
providers.push(`GitHub ${import_picocolors2.default.gray("\u2192 Copilot")}`);
|
|
8124
8382
|
console.log();
|
|
8125
|
-
console.log(import_picocolors2.default.bold("
|
|
8383
|
+
console.log(import_picocolors2.default.bold("Authenticate Your Providers"));
|
|
8126
8384
|
console.log();
|
|
8127
8385
|
console.log(` Run ${import_picocolors2.default.cyan("opencode auth login")} and select:`);
|
|
8128
8386
|
for (const provider of providers) {
|
|
@@ -8366,7 +8624,7 @@ var serializeObjectParam = ({ allowReserved, explode, name, style, value, valueO
|
|
|
8366
8624
|
|
|
8367
8625
|
// node_modules/@opencode-ai/sdk/dist/gen/core/utils.gen.js
|
|
8368
8626
|
var PATH_PARAM_RE = /\{[^{}]+\}/g;
|
|
8369
|
-
var defaultPathSerializer = ({ path:
|
|
8627
|
+
var defaultPathSerializer = ({ path: path3, url: _url }) => {
|
|
8370
8628
|
let url = _url;
|
|
8371
8629
|
const matches = _url.match(PATH_PARAM_RE);
|
|
8372
8630
|
if (matches) {
|
|
@@ -8385,7 +8643,7 @@ var defaultPathSerializer = ({ path: path2, url: _url }) => {
|
|
|
8385
8643
|
name = name.substring(1);
|
|
8386
8644
|
style = "matrix";
|
|
8387
8645
|
}
|
|
8388
|
-
const value =
|
|
8646
|
+
const value = path3[name];
|
|
8389
8647
|
if (value === undefined || value === null) {
|
|
8390
8648
|
continue;
|
|
8391
8649
|
}
|
|
@@ -8416,11 +8674,11 @@ var defaultPathSerializer = ({ path: path2, url: _url }) => {
|
|
|
8416
8674
|
}
|
|
8417
8675
|
return url;
|
|
8418
8676
|
};
|
|
8419
|
-
var getUrl = ({ baseUrl, path:
|
|
8677
|
+
var getUrl = ({ baseUrl, path: path3, query, querySerializer, url: _url }) => {
|
|
8420
8678
|
const pathUrl = _url.startsWith("/") ? _url : `/${_url}`;
|
|
8421
8679
|
let url = (baseUrl ?? "") + pathUrl;
|
|
8422
|
-
if (
|
|
8423
|
-
url = defaultPathSerializer({ path:
|
|
8680
|
+
if (path3) {
|
|
8681
|
+
url = defaultPathSerializer({ path: path3, url });
|
|
8424
8682
|
}
|
|
8425
8683
|
let search = query ? querySerializer(query) : "";
|
|
8426
8684
|
if (search.startsWith("?")) {
|
|
@@ -9736,7 +9994,7 @@ function logEventVerbose(ctx, payload) {
|
|
|
9736
9994
|
const toolName = toolProps?.name ?? "unknown";
|
|
9737
9995
|
const input = toolProps?.input ?? {};
|
|
9738
9996
|
const inputStr = JSON.stringify(input).slice(0, 150);
|
|
9739
|
-
console.error(import_picocolors4.default.cyan(`${sessionTag}
|
|
9997
|
+
console.error(import_picocolors4.default.cyan(`${sessionTag} TOOL.EXECUTE: ${import_picocolors4.default.bold(toolName)}`));
|
|
9740
9998
|
console.error(import_picocolors4.default.dim(` input: ${inputStr}${inputStr.length >= 150 ? "..." : ""}`));
|
|
9741
9999
|
break;
|
|
9742
10000
|
}
|
|
@@ -9744,13 +10002,13 @@ function logEventVerbose(ctx, payload) {
|
|
|
9744
10002
|
const resultProps = props;
|
|
9745
10003
|
const output = resultProps?.output ?? "";
|
|
9746
10004
|
const preview = output.slice(0, 200).replace(/\n/g, "\\n");
|
|
9747
|
-
console.error(import_picocolors4.default.green(`${sessionTag}
|
|
10005
|
+
console.error(import_picocolors4.default.green(`${sessionTag} TOOL.RESULT: "${preview}${output.length > 200 ? "..." : ""}"`));
|
|
9748
10006
|
break;
|
|
9749
10007
|
}
|
|
9750
10008
|
case "session.error": {
|
|
9751
10009
|
const errorProps = props;
|
|
9752
10010
|
const errorMsg = serializeError(errorProps?.error);
|
|
9753
|
-
console.error(import_picocolors4.default.red(`${sessionTag}
|
|
10011
|
+
console.error(import_picocolors4.default.red(`${sessionTag} SESSION.ERROR: ${errorMsg}`));
|
|
9754
10012
|
break;
|
|
9755
10013
|
}
|
|
9756
10014
|
default:
|
|
@@ -9844,7 +10102,7 @@ function handleToolExecute(ctx, payload, state) {
|
|
|
9844
10102
|
}
|
|
9845
10103
|
}
|
|
9846
10104
|
process.stdout.write(`
|
|
9847
|
-
${import_picocolors4.default.cyan("
|
|
10105
|
+
${import_picocolors4.default.cyan(">")} ${import_picocolors4.default.bold(toolName)}${inputPreview}
|
|
9848
10106
|
`);
|
|
9849
10107
|
}
|
|
9850
10108
|
function handleToolResult(ctx, payload, state) {
|
|
@@ -9870,6 +10128,8 @@ function handleToolResult(ctx, payload, state) {
|
|
|
9870
10128
|
// src/cli/run/runner.ts
|
|
9871
10129
|
var POLL_INTERVAL_MS = 500;
|
|
9872
10130
|
var DEFAULT_TIMEOUT_MS = 0;
|
|
10131
|
+
var SESSION_CREATE_MAX_RETRIES = 3;
|
|
10132
|
+
var SESSION_CREATE_RETRY_DELAY_MS = 1000;
|
|
9873
10133
|
async function run(options) {
|
|
9874
10134
|
const {
|
|
9875
10135
|
message,
|
|
@@ -9903,12 +10163,39 @@ Interrupted. Shutting down...`));
|
|
|
9903
10163
|
process.exit(130);
|
|
9904
10164
|
});
|
|
9905
10165
|
try {
|
|
9906
|
-
|
|
9907
|
-
|
|
9908
|
-
|
|
9909
|
-
|
|
10166
|
+
let sessionID;
|
|
10167
|
+
let lastError;
|
|
10168
|
+
for (let attempt = 1;attempt <= SESSION_CREATE_MAX_RETRIES; attempt++) {
|
|
10169
|
+
const sessionRes = await client3.session.create({
|
|
10170
|
+
body: { title: "oh-my-opencode run" }
|
|
10171
|
+
});
|
|
10172
|
+
if (sessionRes.error) {
|
|
10173
|
+
lastError = sessionRes.error;
|
|
10174
|
+
console.error(import_picocolors5.default.yellow(`Session create attempt ${attempt}/${SESSION_CREATE_MAX_RETRIES} failed:`));
|
|
10175
|
+
console.error(import_picocolors5.default.dim(` Error: ${serializeError(sessionRes.error)}`));
|
|
10176
|
+
if (attempt < SESSION_CREATE_MAX_RETRIES) {
|
|
10177
|
+
const delay = SESSION_CREATE_RETRY_DELAY_MS * attempt;
|
|
10178
|
+
console.log(import_picocolors5.default.dim(` Retrying in ${delay}ms...`));
|
|
10179
|
+
await new Promise((resolve2) => setTimeout(resolve2, delay));
|
|
10180
|
+
continue;
|
|
10181
|
+
}
|
|
10182
|
+
}
|
|
10183
|
+
sessionID = sessionRes.data?.id;
|
|
10184
|
+
if (sessionID) {
|
|
10185
|
+
break;
|
|
10186
|
+
}
|
|
10187
|
+
lastError = new Error(`Unexpected response: ${JSON.stringify(sessionRes, null, 2)}`);
|
|
10188
|
+
console.error(import_picocolors5.default.yellow(`Session create attempt ${attempt}/${SESSION_CREATE_MAX_RETRIES}: No session ID returned`));
|
|
10189
|
+
if (attempt < SESSION_CREATE_MAX_RETRIES) {
|
|
10190
|
+
const delay = SESSION_CREATE_RETRY_DELAY_MS * attempt;
|
|
10191
|
+
console.log(import_picocolors5.default.dim(` Retrying in ${delay}ms...`));
|
|
10192
|
+
await new Promise((resolve2) => setTimeout(resolve2, delay));
|
|
10193
|
+
}
|
|
10194
|
+
}
|
|
9910
10195
|
if (!sessionID) {
|
|
9911
|
-
console.error(import_picocolors5.default.red("Failed to create session"));
|
|
10196
|
+
console.error(import_picocolors5.default.red("Failed to create session after all retries"));
|
|
10197
|
+
console.error(import_picocolors5.default.dim(`Last error: ${serializeError(lastError)}`));
|
|
10198
|
+
cleanup();
|
|
9912
10199
|
return 1;
|
|
9913
10200
|
}
|
|
9914
10201
|
console.log(import_picocolors5.default.dim(`Session: ${sessionID}`));
|
|
@@ -9978,13 +10265,13 @@ init_checker();
|
|
|
9978
10265
|
// src/cli/get-local-version/formatter.ts
|
|
9979
10266
|
var import_picocolors6 = __toESM(require_picocolors(), 1);
|
|
9980
10267
|
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("
|
|
10268
|
+
check: import_picocolors6.default.green("[OK]"),
|
|
10269
|
+
cross: import_picocolors6.default.red("[X]"),
|
|
10270
|
+
arrow: import_picocolors6.default.cyan("->"),
|
|
10271
|
+
info: import_picocolors6.default.blue("[i]"),
|
|
10272
|
+
warn: import_picocolors6.default.yellow("[!]"),
|
|
10273
|
+
pin: import_picocolors6.default.magenta("[PINNED]"),
|
|
10274
|
+
dev: import_picocolors6.default.cyan("[DEV]")
|
|
9988
10275
|
};
|
|
9989
10276
|
function formatVersionOutput(info) {
|
|
9990
10277
|
const lines = [];
|
|
@@ -10143,6 +10430,7 @@ var CHECK_IDS = {
|
|
|
10143
10430
|
OPENCODE_INSTALLATION: "opencode-installation",
|
|
10144
10431
|
PLUGIN_REGISTRATION: "plugin-registration",
|
|
10145
10432
|
CONFIG_VALIDATION: "config-validation",
|
|
10433
|
+
MODEL_RESOLUTION: "model-resolution",
|
|
10146
10434
|
AUTH_ANTHROPIC: "auth-anthropic",
|
|
10147
10435
|
AUTH_OPENAI: "auth-openai",
|
|
10148
10436
|
AUTH_GOOGLE: "auth-google",
|
|
@@ -10159,6 +10447,7 @@ var CHECK_NAMES = {
|
|
|
10159
10447
|
[CHECK_IDS.OPENCODE_INSTALLATION]: "OpenCode Installation",
|
|
10160
10448
|
[CHECK_IDS.PLUGIN_REGISTRATION]: "Plugin Registration",
|
|
10161
10449
|
[CHECK_IDS.CONFIG_VALIDATION]: "Configuration Validity",
|
|
10450
|
+
[CHECK_IDS.MODEL_RESOLUTION]: "Model Resolution",
|
|
10162
10451
|
[CHECK_IDS.AUTH_ANTHROPIC]: "Anthropic (Claude) Auth",
|
|
10163
10452
|
[CHECK_IDS.AUTH_OPENAI]: "OpenAI (ChatGPT) Auth",
|
|
10164
10453
|
[CHECK_IDS.AUTH_GOOGLE]: "Google (Gemini) Auth",
|
|
@@ -10200,9 +10489,9 @@ function selectBinaryPath(paths, platform) {
|
|
|
10200
10489
|
return null;
|
|
10201
10490
|
if (platform !== "win32")
|
|
10202
10491
|
return paths[0];
|
|
10203
|
-
const normalized = paths.map((
|
|
10492
|
+
const normalized = paths.map((path6) => path6.toLowerCase());
|
|
10204
10493
|
for (const ext of WINDOWS_EXECUTABLE_EXTS) {
|
|
10205
|
-
const index = normalized.findIndex((
|
|
10494
|
+
const index = normalized.findIndex((path6) => path6.endsWith(ext));
|
|
10206
10495
|
if (index !== -1)
|
|
10207
10496
|
return paths[index];
|
|
10208
10497
|
}
|
|
@@ -10334,7 +10623,7 @@ function getOpenCodeCheckDefinition() {
|
|
|
10334
10623
|
}
|
|
10335
10624
|
|
|
10336
10625
|
// src/cli/doctor/checks/plugin.ts
|
|
10337
|
-
import { existsSync as existsSync7, readFileSync as
|
|
10626
|
+
import { existsSync as existsSync7, readFileSync as readFileSync6 } from "fs";
|
|
10338
10627
|
init_shared();
|
|
10339
10628
|
function detectConfigPath() {
|
|
10340
10629
|
const paths = getOpenCodeConfigPaths({ binary: "opencode", version: null });
|
|
@@ -10353,6 +10642,9 @@ function findPluginEntry2(plugins) {
|
|
|
10353
10642
|
const version = isPinned ? plugin.split("@")[1] : null;
|
|
10354
10643
|
return { entry: plugin, isPinned, version };
|
|
10355
10644
|
}
|
|
10645
|
+
if (plugin.startsWith("file://") && plugin.includes(PACKAGE_NAME3)) {
|
|
10646
|
+
return { entry: plugin, isPinned: false, version: "local-dev" };
|
|
10647
|
+
}
|
|
10356
10648
|
}
|
|
10357
10649
|
return null;
|
|
10358
10650
|
}
|
|
@@ -10368,7 +10660,7 @@ function getPluginInfo() {
|
|
|
10368
10660
|
};
|
|
10369
10661
|
}
|
|
10370
10662
|
try {
|
|
10371
|
-
const content =
|
|
10663
|
+
const content = readFileSync6(configInfo.path, "utf-8");
|
|
10372
10664
|
const config = parseJsonc(content);
|
|
10373
10665
|
const plugins = config.plugin ?? [];
|
|
10374
10666
|
const pluginEntry = findPluginEntry2(plugins);
|
|
@@ -10442,9 +10734,8 @@ function getPluginCheckDefinition() {
|
|
|
10442
10734
|
}
|
|
10443
10735
|
|
|
10444
10736
|
// src/cli/doctor/checks/config.ts
|
|
10445
|
-
import { existsSync as existsSync8, readFileSync as
|
|
10446
|
-
import {
|
|
10447
|
-
import { join as join6 } from "path";
|
|
10737
|
+
import { existsSync as existsSync8, readFileSync as readFileSync7 } from "fs";
|
|
10738
|
+
import { join as join8 } from "path";
|
|
10448
10739
|
init_shared();
|
|
10449
10740
|
|
|
10450
10741
|
// node_modules/zod/v4/classic/external.js
|
|
@@ -11176,10 +11467,10 @@ function mergeDefs(...defs) {
|
|
|
11176
11467
|
function cloneDef(schema2) {
|
|
11177
11468
|
return mergeDefs(schema2._zod.def);
|
|
11178
11469
|
}
|
|
11179
|
-
function getElementAtPath(obj,
|
|
11180
|
-
if (!
|
|
11470
|
+
function getElementAtPath(obj, path6) {
|
|
11471
|
+
if (!path6)
|
|
11181
11472
|
return obj;
|
|
11182
|
-
return
|
|
11473
|
+
return path6.reduce((acc, key) => acc?.[key], obj);
|
|
11183
11474
|
}
|
|
11184
11475
|
function promiseAllObject(promisesObj) {
|
|
11185
11476
|
const keys = Object.keys(promisesObj);
|
|
@@ -11538,11 +11829,11 @@ function aborted(x2, startIndex = 0) {
|
|
|
11538
11829
|
}
|
|
11539
11830
|
return false;
|
|
11540
11831
|
}
|
|
11541
|
-
function prefixIssues(
|
|
11832
|
+
function prefixIssues(path6, issues) {
|
|
11542
11833
|
return issues.map((iss) => {
|
|
11543
11834
|
var _a;
|
|
11544
11835
|
(_a = iss).path ?? (_a.path = []);
|
|
11545
|
-
iss.path.unshift(
|
|
11836
|
+
iss.path.unshift(path6);
|
|
11546
11837
|
return iss;
|
|
11547
11838
|
});
|
|
11548
11839
|
}
|
|
@@ -11710,7 +12001,7 @@ function treeifyError(error, _mapper) {
|
|
|
11710
12001
|
return issue2.message;
|
|
11711
12002
|
};
|
|
11712
12003
|
const result = { errors: [] };
|
|
11713
|
-
const processError = (error2,
|
|
12004
|
+
const processError = (error2, path6 = []) => {
|
|
11714
12005
|
var _a, _b;
|
|
11715
12006
|
for (const issue2 of error2.issues) {
|
|
11716
12007
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
@@ -11720,7 +12011,7 @@ function treeifyError(error, _mapper) {
|
|
|
11720
12011
|
} else if (issue2.code === "invalid_element") {
|
|
11721
12012
|
processError({ issues: issue2.issues }, issue2.path);
|
|
11722
12013
|
} else {
|
|
11723
|
-
const fullpath = [...
|
|
12014
|
+
const fullpath = [...path6, ...issue2.path];
|
|
11724
12015
|
if (fullpath.length === 0) {
|
|
11725
12016
|
result.errors.push(mapper(issue2));
|
|
11726
12017
|
continue;
|
|
@@ -11752,8 +12043,8 @@ function treeifyError(error, _mapper) {
|
|
|
11752
12043
|
}
|
|
11753
12044
|
function toDotPath(_path) {
|
|
11754
12045
|
const segs = [];
|
|
11755
|
-
const
|
|
11756
|
-
for (const seg of
|
|
12046
|
+
const path6 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
12047
|
+
for (const seg of path6) {
|
|
11757
12048
|
if (typeof seg === "number")
|
|
11758
12049
|
segs.push(`[${seg}]`);
|
|
11759
12050
|
else if (typeof seg === "symbol")
|
|
@@ -22780,16 +23071,15 @@ var AgentPermissionSchema = exports_external.object({
|
|
|
22780
23071
|
external_directory: PermissionValue.optional()
|
|
22781
23072
|
});
|
|
22782
23073
|
var BuiltinAgentNameSchema = exports_external.enum([
|
|
22783
|
-
"
|
|
23074
|
+
"sisyphus",
|
|
23075
|
+
"prometheus",
|
|
22784
23076
|
"oracle",
|
|
22785
23077
|
"librarian",
|
|
22786
23078
|
"explore",
|
|
22787
|
-
"frontend-ui-ux-engineer",
|
|
22788
|
-
"document-writer",
|
|
22789
23079
|
"multimodal-looker",
|
|
22790
|
-
"
|
|
22791
|
-
"
|
|
22792
|
-
"
|
|
23080
|
+
"metis",
|
|
23081
|
+
"momus",
|
|
23082
|
+
"atlas"
|
|
22793
23083
|
]);
|
|
22794
23084
|
var BuiltinSkillNameSchema = exports_external.enum([
|
|
22795
23085
|
"playwright",
|
|
@@ -22799,19 +23089,17 @@ var BuiltinSkillNameSchema = exports_external.enum([
|
|
|
22799
23089
|
var OverridableAgentNameSchema = exports_external.enum([
|
|
22800
23090
|
"build",
|
|
22801
23091
|
"plan",
|
|
22802
|
-
"
|
|
22803
|
-
"
|
|
23092
|
+
"sisyphus",
|
|
23093
|
+
"sisyphus-junior",
|
|
22804
23094
|
"OpenCode-Builder",
|
|
22805
|
-
"
|
|
22806
|
-
"
|
|
22807
|
-
"
|
|
23095
|
+
"prometheus",
|
|
23096
|
+
"metis",
|
|
23097
|
+
"momus",
|
|
22808
23098
|
"oracle",
|
|
22809
23099
|
"librarian",
|
|
22810
23100
|
"explore",
|
|
22811
|
-
"frontend-ui-ux-engineer",
|
|
22812
|
-
"document-writer",
|
|
22813
23101
|
"multimodal-looker",
|
|
22814
|
-
"
|
|
23102
|
+
"atlas"
|
|
22815
23103
|
]);
|
|
22816
23104
|
var HookNameSchema = exports_external.enum([
|
|
22817
23105
|
"todo-continuation-enforcer",
|
|
@@ -22843,7 +23131,7 @@ var HookNameSchema = exports_external.enum([
|
|
|
22843
23131
|
"delegate-task-retry",
|
|
22844
23132
|
"prometheus-md-only",
|
|
22845
23133
|
"start-work",
|
|
22846
|
-
"
|
|
23134
|
+
"atlas"
|
|
22847
23135
|
]);
|
|
22848
23136
|
var BuiltinCommandNameSchema = exports_external.enum([
|
|
22849
23137
|
"init-deep",
|
|
@@ -22868,19 +23156,17 @@ var AgentOverrideConfigSchema = exports_external.object({
|
|
|
22868
23156
|
var AgentOverridesSchema = exports_external.object({
|
|
22869
23157
|
build: AgentOverrideConfigSchema.optional(),
|
|
22870
23158
|
plan: AgentOverrideConfigSchema.optional(),
|
|
22871
|
-
|
|
22872
|
-
"
|
|
23159
|
+
sisyphus: AgentOverrideConfigSchema.optional(),
|
|
23160
|
+
"sisyphus-junior": AgentOverrideConfigSchema.optional(),
|
|
22873
23161
|
"OpenCode-Builder": AgentOverrideConfigSchema.optional(),
|
|
22874
|
-
|
|
22875
|
-
|
|
22876
|
-
|
|
23162
|
+
prometheus: AgentOverrideConfigSchema.optional(),
|
|
23163
|
+
metis: AgentOverrideConfigSchema.optional(),
|
|
23164
|
+
momus: AgentOverrideConfigSchema.optional(),
|
|
22877
23165
|
oracle: AgentOverrideConfigSchema.optional(),
|
|
22878
23166
|
librarian: AgentOverrideConfigSchema.optional(),
|
|
22879
23167
|
explore: AgentOverrideConfigSchema.optional(),
|
|
22880
|
-
"frontend-ui-ux-engineer": AgentOverrideConfigSchema.optional(),
|
|
22881
|
-
"document-writer": AgentOverrideConfigSchema.optional(),
|
|
22882
23168
|
"multimodal-looker": AgentOverrideConfigSchema.optional(),
|
|
22883
|
-
|
|
23169
|
+
atlas: AgentOverrideConfigSchema.optional()
|
|
22884
23170
|
});
|
|
22885
23171
|
var ClaudeCodeConfigSchema = exports_external.object({
|
|
22886
23172
|
mcp: exports_external.boolean().optional(),
|
|
@@ -22898,7 +23184,8 @@ var SisyphusAgentConfigSchema = exports_external.object({
|
|
|
22898
23184
|
replace_plan: exports_external.boolean().optional()
|
|
22899
23185
|
});
|
|
22900
23186
|
var CategoryConfigSchema = exports_external.object({
|
|
22901
|
-
|
|
23187
|
+
description: exports_external.string().optional(),
|
|
23188
|
+
model: exports_external.string().optional(),
|
|
22902
23189
|
variant: exports_external.string().optional(),
|
|
22903
23190
|
temperature: exports_external.number().min(0).max(2).optional(),
|
|
22904
23191
|
top_p: exports_external.number().min(0).max(1).optional(),
|
|
@@ -22907,19 +23194,20 @@ var CategoryConfigSchema = exports_external.object({
|
|
|
22907
23194
|
type: exports_external.enum(["enabled", "disabled"]),
|
|
22908
23195
|
budgetTokens: exports_external.number().optional()
|
|
22909
23196
|
}).optional(),
|
|
22910
|
-
reasoningEffort: exports_external.enum(["low", "medium", "high"]).optional(),
|
|
23197
|
+
reasoningEffort: exports_external.enum(["low", "medium", "high", "xhigh"]).optional(),
|
|
22911
23198
|
textVerbosity: exports_external.enum(["low", "medium", "high"]).optional(),
|
|
22912
23199
|
tools: exports_external.record(exports_external.string(), exports_external.boolean()).optional(),
|
|
22913
|
-
prompt_append: exports_external.string().optional()
|
|
23200
|
+
prompt_append: exports_external.string().optional(),
|
|
23201
|
+
is_unstable_agent: exports_external.boolean().optional()
|
|
22914
23202
|
});
|
|
22915
23203
|
var BuiltinCategoryNameSchema = exports_external.enum([
|
|
22916
23204
|
"visual-engineering",
|
|
22917
23205
|
"ultrabrain",
|
|
22918
23206
|
"artistry",
|
|
22919
23207
|
"quick",
|
|
22920
|
-
"
|
|
22921
|
-
"
|
|
22922
|
-
"
|
|
23208
|
+
"unspecified-low",
|
|
23209
|
+
"unspecified-high",
|
|
23210
|
+
"writing"
|
|
22923
23211
|
]);
|
|
22924
23212
|
var CategoriesConfigSchema = exports_external.record(exports_external.string(), CategoryConfigSchema);
|
|
22925
23213
|
var CommentCheckerConfigSchema = exports_external.object({
|
|
@@ -23002,8 +23290,8 @@ var RalphLoopConfigSchema = exports_external.object({
|
|
|
23002
23290
|
});
|
|
23003
23291
|
var BackgroundTaskConfigSchema = exports_external.object({
|
|
23004
23292
|
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(
|
|
23293
|
+
providerConcurrency: exports_external.record(exports_external.string(), exports_external.number().min(0)).optional(),
|
|
23294
|
+
modelConcurrency: exports_external.record(exports_external.string(), exports_external.number().min(0)).optional(),
|
|
23007
23295
|
staleTimeoutMs: exports_external.number().min(60000).optional()
|
|
23008
23296
|
});
|
|
23009
23297
|
var NotificationConfigSchema = exports_external.object({
|
|
@@ -23034,9 +23322,9 @@ var OhMyOpenCodeConfigSchema = exports_external.object({
|
|
|
23034
23322
|
git_master: GitMasterConfigSchema.optional()
|
|
23035
23323
|
});
|
|
23036
23324
|
// src/cli/doctor/checks/config.ts
|
|
23037
|
-
var USER_CONFIG_DIR2 =
|
|
23038
|
-
var USER_CONFIG_BASE =
|
|
23039
|
-
var PROJECT_CONFIG_BASE =
|
|
23325
|
+
var USER_CONFIG_DIR2 = getOpenCodeConfigDir({ binary: "opencode" });
|
|
23326
|
+
var USER_CONFIG_BASE = join8(USER_CONFIG_DIR2, `${PACKAGE_NAME3}`);
|
|
23327
|
+
var PROJECT_CONFIG_BASE = join8(process.cwd(), ".opencode", PACKAGE_NAME3);
|
|
23040
23328
|
function findConfigPath() {
|
|
23041
23329
|
const projectDetected = detectConfigFile(PROJECT_CONFIG_BASE);
|
|
23042
23330
|
if (projectDetected.format !== "none") {
|
|
@@ -23050,7 +23338,7 @@ function findConfigPath() {
|
|
|
23050
23338
|
}
|
|
23051
23339
|
function validateConfig(configPath) {
|
|
23052
23340
|
try {
|
|
23053
|
-
const content =
|
|
23341
|
+
const content = readFileSync7(configPath, "utf-8");
|
|
23054
23342
|
const rawConfig = parseJsonc(content);
|
|
23055
23343
|
const result = OhMyOpenCodeConfigSchema.safeParse(rawConfig);
|
|
23056
23344
|
if (!result.success) {
|
|
@@ -23132,25 +23420,195 @@ function getConfigCheckDefinition() {
|
|
|
23132
23420
|
};
|
|
23133
23421
|
}
|
|
23134
23422
|
|
|
23423
|
+
// src/cli/doctor/checks/model-resolution.ts
|
|
23424
|
+
import { readFileSync as readFileSync8, existsSync as existsSync9 } from "fs";
|
|
23425
|
+
init_shared();
|
|
23426
|
+
init_model_requirements();
|
|
23427
|
+
import { homedir as homedir6 } from "os";
|
|
23428
|
+
import { join as join9 } from "path";
|
|
23429
|
+
function getOpenCodeCacheDir2() {
|
|
23430
|
+
const xdgCache = process.env.XDG_CACHE_HOME;
|
|
23431
|
+
if (xdgCache)
|
|
23432
|
+
return join9(xdgCache, "opencode");
|
|
23433
|
+
return join9(homedir6(), ".cache", "opencode");
|
|
23434
|
+
}
|
|
23435
|
+
function loadAvailableModels() {
|
|
23436
|
+
const cacheFile = join9(getOpenCodeCacheDir2(), "models.json");
|
|
23437
|
+
if (!existsSync9(cacheFile)) {
|
|
23438
|
+
return { providers: [], modelCount: 0, cacheExists: false };
|
|
23439
|
+
}
|
|
23440
|
+
try {
|
|
23441
|
+
const content = readFileSync8(cacheFile, "utf-8");
|
|
23442
|
+
const data = JSON.parse(content);
|
|
23443
|
+
const providers = Object.keys(data);
|
|
23444
|
+
let modelCount = 0;
|
|
23445
|
+
for (const providerId of providers) {
|
|
23446
|
+
const models = data[providerId]?.models;
|
|
23447
|
+
if (models && typeof models === "object") {
|
|
23448
|
+
modelCount += Object.keys(models).length;
|
|
23449
|
+
}
|
|
23450
|
+
}
|
|
23451
|
+
return { providers, modelCount, cacheExists: true };
|
|
23452
|
+
} catch {
|
|
23453
|
+
return { providers: [], modelCount: 0, cacheExists: false };
|
|
23454
|
+
}
|
|
23455
|
+
}
|
|
23456
|
+
var PACKAGE_NAME4 = "oh-my-opencode";
|
|
23457
|
+
var USER_CONFIG_DIR3 = join9(homedir6(), ".config", "opencode");
|
|
23458
|
+
var USER_CONFIG_BASE2 = join9(USER_CONFIG_DIR3, PACKAGE_NAME4);
|
|
23459
|
+
var PROJECT_CONFIG_BASE2 = join9(process.cwd(), ".opencode", PACKAGE_NAME4);
|
|
23460
|
+
function loadConfig() {
|
|
23461
|
+
const projectDetected = detectConfigFile(PROJECT_CONFIG_BASE2);
|
|
23462
|
+
if (projectDetected.format !== "none") {
|
|
23463
|
+
try {
|
|
23464
|
+
const content = readFileSync8(projectDetected.path, "utf-8");
|
|
23465
|
+
return parseJsonc(content);
|
|
23466
|
+
} catch {
|
|
23467
|
+
return null;
|
|
23468
|
+
}
|
|
23469
|
+
}
|
|
23470
|
+
const userDetected = detectConfigFile(USER_CONFIG_BASE2);
|
|
23471
|
+
if (userDetected.format !== "none") {
|
|
23472
|
+
try {
|
|
23473
|
+
const content = readFileSync8(userDetected.path, "utf-8");
|
|
23474
|
+
return parseJsonc(content);
|
|
23475
|
+
} catch {
|
|
23476
|
+
return null;
|
|
23477
|
+
}
|
|
23478
|
+
}
|
|
23479
|
+
return null;
|
|
23480
|
+
}
|
|
23481
|
+
function formatProviderChain(providers) {
|
|
23482
|
+
return providers.join(" \u2192 ");
|
|
23483
|
+
}
|
|
23484
|
+
function getEffectiveModel(requirement, userOverride) {
|
|
23485
|
+
if (userOverride) {
|
|
23486
|
+
return userOverride;
|
|
23487
|
+
}
|
|
23488
|
+
const firstEntry = requirement.fallbackChain[0];
|
|
23489
|
+
if (!firstEntry) {
|
|
23490
|
+
return "unknown";
|
|
23491
|
+
}
|
|
23492
|
+
return `${firstEntry.providers[0]}/${firstEntry.model}`;
|
|
23493
|
+
}
|
|
23494
|
+
function buildEffectiveResolution(requirement, userOverride) {
|
|
23495
|
+
if (userOverride) {
|
|
23496
|
+
return `User override: ${userOverride}`;
|
|
23497
|
+
}
|
|
23498
|
+
const firstEntry = requirement.fallbackChain[0];
|
|
23499
|
+
if (!firstEntry) {
|
|
23500
|
+
return "No fallback chain defined";
|
|
23501
|
+
}
|
|
23502
|
+
return `Provider fallback: ${formatProviderChain(firstEntry.providers)} \u2192 ${firstEntry.model}`;
|
|
23503
|
+
}
|
|
23504
|
+
function getModelResolutionInfoWithOverrides(config2) {
|
|
23505
|
+
const agents = Object.entries(AGENT_MODEL_REQUIREMENTS).map(([name, requirement]) => {
|
|
23506
|
+
const userOverride = config2.agents?.[name]?.model;
|
|
23507
|
+
return {
|
|
23508
|
+
name,
|
|
23509
|
+
requirement,
|
|
23510
|
+
userOverride,
|
|
23511
|
+
effectiveModel: getEffectiveModel(requirement, userOverride),
|
|
23512
|
+
effectiveResolution: buildEffectiveResolution(requirement, userOverride)
|
|
23513
|
+
};
|
|
23514
|
+
});
|
|
23515
|
+
const categories = Object.entries(CATEGORY_MODEL_REQUIREMENTS).map(([name, requirement]) => {
|
|
23516
|
+
const userOverride = config2.categories?.[name]?.model;
|
|
23517
|
+
return {
|
|
23518
|
+
name,
|
|
23519
|
+
requirement,
|
|
23520
|
+
userOverride,
|
|
23521
|
+
effectiveModel: getEffectiveModel(requirement, userOverride),
|
|
23522
|
+
effectiveResolution: buildEffectiveResolution(requirement, userOverride)
|
|
23523
|
+
};
|
|
23524
|
+
});
|
|
23525
|
+
return { agents, categories };
|
|
23526
|
+
}
|
|
23527
|
+
function formatModelWithVariant(model, variant) {
|
|
23528
|
+
return variant ? `${model} (${variant})` : model;
|
|
23529
|
+
}
|
|
23530
|
+
function getEffectiveVariant(requirement) {
|
|
23531
|
+
const firstEntry = requirement.fallbackChain[0];
|
|
23532
|
+
return firstEntry?.variant ?? requirement.variant;
|
|
23533
|
+
}
|
|
23534
|
+
function buildDetailsArray(info, available) {
|
|
23535
|
+
const details = [];
|
|
23536
|
+
details.push("\u2550\u2550\u2550 Available Models (from cache) \u2550\u2550\u2550");
|
|
23537
|
+
details.push("");
|
|
23538
|
+
if (available.cacheExists) {
|
|
23539
|
+
details.push(` Providers: ${available.providers.length} (${available.providers.slice(0, 8).join(", ")}${available.providers.length > 8 ? "..." : ""})`);
|
|
23540
|
+
details.push(` Total models: ${available.modelCount}`);
|
|
23541
|
+
details.push(` Cache: ~/.cache/opencode/models.json`);
|
|
23542
|
+
details.push(` Refresh: opencode models --refresh`);
|
|
23543
|
+
} else {
|
|
23544
|
+
details.push(" \u26A0 Cache not found. Run 'opencode' to populate.");
|
|
23545
|
+
}
|
|
23546
|
+
details.push("");
|
|
23547
|
+
details.push("\u2550\u2550\u2550 Configured Models \u2550\u2550\u2550");
|
|
23548
|
+
details.push("");
|
|
23549
|
+
details.push("Agents:");
|
|
23550
|
+
for (const agent of info.agents) {
|
|
23551
|
+
const marker = agent.userOverride ? "\u25CF" : "\u25CB";
|
|
23552
|
+
const display = formatModelWithVariant(agent.effectiveModel, getEffectiveVariant(agent.requirement));
|
|
23553
|
+
details.push(` ${marker} ${agent.name}: ${display}`);
|
|
23554
|
+
}
|
|
23555
|
+
details.push("");
|
|
23556
|
+
details.push("Categories:");
|
|
23557
|
+
for (const category of info.categories) {
|
|
23558
|
+
const marker = category.userOverride ? "\u25CF" : "\u25CB";
|
|
23559
|
+
const display = formatModelWithVariant(category.effectiveModel, getEffectiveVariant(category.requirement));
|
|
23560
|
+
details.push(` ${marker} ${category.name}: ${display}`);
|
|
23561
|
+
}
|
|
23562
|
+
details.push("");
|
|
23563
|
+
details.push("\u25CF = user override, \u25CB = provider fallback");
|
|
23564
|
+
return details;
|
|
23565
|
+
}
|
|
23566
|
+
async function checkModelResolution() {
|
|
23567
|
+
const config2 = loadConfig() ?? {};
|
|
23568
|
+
const info = getModelResolutionInfoWithOverrides(config2);
|
|
23569
|
+
const available = loadAvailableModels();
|
|
23570
|
+
const agentCount = info.agents.length;
|
|
23571
|
+
const categoryCount = info.categories.length;
|
|
23572
|
+
const agentOverrides = info.agents.filter((a) => a.userOverride).length;
|
|
23573
|
+
const categoryOverrides = info.categories.filter((c) => c.userOverride).length;
|
|
23574
|
+
const totalOverrides = agentOverrides + categoryOverrides;
|
|
23575
|
+
const overrideNote = totalOverrides > 0 ? ` (${totalOverrides} override${totalOverrides > 1 ? "s" : ""})` : "";
|
|
23576
|
+
const cacheNote = available.cacheExists ? `, ${available.modelCount} available` : ", cache not found";
|
|
23577
|
+
return {
|
|
23578
|
+
name: CHECK_NAMES[CHECK_IDS.MODEL_RESOLUTION],
|
|
23579
|
+
status: available.cacheExists ? "pass" : "warn",
|
|
23580
|
+
message: `${agentCount} agents, ${categoryCount} categories${overrideNote}${cacheNote}`,
|
|
23581
|
+
details: buildDetailsArray(info, available)
|
|
23582
|
+
};
|
|
23583
|
+
}
|
|
23584
|
+
function getModelResolutionCheckDefinition() {
|
|
23585
|
+
return {
|
|
23586
|
+
id: CHECK_IDS.MODEL_RESOLUTION,
|
|
23587
|
+
name: CHECK_NAMES[CHECK_IDS.MODEL_RESOLUTION],
|
|
23588
|
+
category: "configuration",
|
|
23589
|
+
check: checkModelResolution,
|
|
23590
|
+
critical: false
|
|
23591
|
+
};
|
|
23592
|
+
}
|
|
23593
|
+
|
|
23135
23594
|
// src/cli/doctor/checks/auth.ts
|
|
23136
|
-
import { existsSync as
|
|
23137
|
-
import {
|
|
23138
|
-
import { join as join7 } from "path";
|
|
23595
|
+
import { existsSync as existsSync10, readFileSync as readFileSync9 } from "fs";
|
|
23596
|
+
import { join as join10 } from "path";
|
|
23139
23597
|
init_shared();
|
|
23140
|
-
var OPENCODE_CONFIG_DIR =
|
|
23141
|
-
var OPENCODE_JSON =
|
|
23142
|
-
var OPENCODE_JSONC =
|
|
23598
|
+
var OPENCODE_CONFIG_DIR = getOpenCodeConfigDir({ binary: "opencode" });
|
|
23599
|
+
var OPENCODE_JSON = join10(OPENCODE_CONFIG_DIR, "opencode.json");
|
|
23600
|
+
var OPENCODE_JSONC = join10(OPENCODE_CONFIG_DIR, "opencode.jsonc");
|
|
23143
23601
|
var AUTH_PLUGINS = {
|
|
23144
23602
|
anthropic: { plugin: "builtin", name: "Anthropic (Claude)" },
|
|
23145
23603
|
openai: { plugin: "opencode-openai-codex-auth", name: "OpenAI (ChatGPT)" },
|
|
23146
23604
|
google: { plugin: "opencode-antigravity-auth", name: "Google (Gemini)" }
|
|
23147
23605
|
};
|
|
23148
23606
|
function getOpenCodeConfig() {
|
|
23149
|
-
const configPath =
|
|
23150
|
-
if (!
|
|
23607
|
+
const configPath = existsSync10(OPENCODE_JSONC) ? OPENCODE_JSONC : OPENCODE_JSON;
|
|
23608
|
+
if (!existsSync10(configPath))
|
|
23151
23609
|
return null;
|
|
23152
23610
|
try {
|
|
23153
|
-
const content =
|
|
23611
|
+
const content = readFileSync9(configPath, "utf-8");
|
|
23154
23612
|
return parseJsonc(content);
|
|
23155
23613
|
} catch {
|
|
23156
23614
|
return null;
|
|
@@ -23279,9 +23737,9 @@ async function checkAstGrepCli() {
|
|
|
23279
23737
|
path: binary2.path
|
|
23280
23738
|
};
|
|
23281
23739
|
}
|
|
23282
|
-
function checkAstGrepNapi() {
|
|
23740
|
+
async function checkAstGrepNapi() {
|
|
23283
23741
|
try {
|
|
23284
|
-
|
|
23742
|
+
await import("@ast-grep/napi");
|
|
23285
23743
|
return {
|
|
23286
23744
|
name: "AST-Grep NAPI",
|
|
23287
23745
|
required: false,
|
|
@@ -23290,6 +23748,24 @@ function checkAstGrepNapi() {
|
|
|
23290
23748
|
path: null
|
|
23291
23749
|
};
|
|
23292
23750
|
} catch {
|
|
23751
|
+
const { existsSync: existsSync11 } = await import("fs");
|
|
23752
|
+
const { join: join11 } = await import("path");
|
|
23753
|
+
const { homedir: homedir7 } = await import("os");
|
|
23754
|
+
const pathsToCheck = [
|
|
23755
|
+
join11(homedir7(), ".config", "opencode", "node_modules", "@ast-grep", "napi"),
|
|
23756
|
+
join11(process.cwd(), "node_modules", "@ast-grep", "napi")
|
|
23757
|
+
];
|
|
23758
|
+
for (const napiPath of pathsToCheck) {
|
|
23759
|
+
if (existsSync11(napiPath)) {
|
|
23760
|
+
return {
|
|
23761
|
+
name: "AST-Grep NAPI",
|
|
23762
|
+
required: false,
|
|
23763
|
+
installed: true,
|
|
23764
|
+
version: null,
|
|
23765
|
+
path: napiPath
|
|
23766
|
+
};
|
|
23767
|
+
}
|
|
23768
|
+
}
|
|
23293
23769
|
return {
|
|
23294
23770
|
name: "AST-Grep NAPI",
|
|
23295
23771
|
required: false,
|
|
@@ -23342,7 +23818,7 @@ async function checkDependencyAstGrepCli() {
|
|
|
23342
23818
|
return dependencyToCheckResult(info, CHECK_NAMES[CHECK_IDS.DEP_AST_GREP_CLI]);
|
|
23343
23819
|
}
|
|
23344
23820
|
async function checkDependencyAstGrepNapi() {
|
|
23345
|
-
const info = checkAstGrepNapi();
|
|
23821
|
+
const info = await checkAstGrepNapi();
|
|
23346
23822
|
return dependencyToCheckResult(info, CHECK_NAMES[CHECK_IDS.DEP_AST_GREP_NAPI]);
|
|
23347
23823
|
}
|
|
23348
23824
|
async function checkDependencyCommentChecker() {
|
|
@@ -23509,15 +23985,15 @@ function getGhCliCheckDefinition() {
|
|
|
23509
23985
|
}
|
|
23510
23986
|
|
|
23511
23987
|
// src/tools/lsp/config.ts
|
|
23512
|
-
import { existsSync as
|
|
23513
|
-
import { join as
|
|
23514
|
-
|
|
23988
|
+
import { existsSync as existsSync11, readFileSync as readFileSync10 } from "fs";
|
|
23989
|
+
import { join as join11 } from "path";
|
|
23990
|
+
init_shared();
|
|
23515
23991
|
function isServerInstalled(command) {
|
|
23516
23992
|
if (command.length === 0)
|
|
23517
23993
|
return false;
|
|
23518
23994
|
const cmd = command[0];
|
|
23519
23995
|
if (cmd.includes("/") || cmd.includes("\\")) {
|
|
23520
|
-
if (
|
|
23996
|
+
if (existsSync11(cmd))
|
|
23521
23997
|
return true;
|
|
23522
23998
|
}
|
|
23523
23999
|
const isWindows = process.platform === "win32";
|
|
@@ -23539,20 +24015,23 @@ function isServerInstalled(command) {
|
|
|
23539
24015
|
const paths = pathEnv.split(pathSeparator);
|
|
23540
24016
|
for (const p2 of paths) {
|
|
23541
24017
|
for (const suffix of exts) {
|
|
23542
|
-
if (
|
|
24018
|
+
if (existsSync11(join11(p2, cmd + suffix))) {
|
|
23543
24019
|
return true;
|
|
23544
24020
|
}
|
|
23545
24021
|
}
|
|
23546
24022
|
}
|
|
23547
24023
|
const cwd = process.cwd();
|
|
24024
|
+
const configDir = getOpenCodeConfigDir({ binary: "opencode" });
|
|
24025
|
+
const dataDir = join11(getDataDir(), "opencode");
|
|
23548
24026
|
const additionalBases = [
|
|
23549
|
-
|
|
23550
|
-
|
|
23551
|
-
|
|
24027
|
+
join11(cwd, "node_modules", ".bin"),
|
|
24028
|
+
join11(configDir, "bin"),
|
|
24029
|
+
join11(configDir, "node_modules", ".bin"),
|
|
24030
|
+
join11(dataDir, "bin")
|
|
23552
24031
|
];
|
|
23553
24032
|
for (const base of additionalBases) {
|
|
23554
24033
|
for (const suffix of exts) {
|
|
23555
|
-
if (
|
|
24034
|
+
if (existsSync11(join11(base, cmd + suffix))) {
|
|
23556
24035
|
return true;
|
|
23557
24036
|
}
|
|
23558
24037
|
}
|
|
@@ -23625,23 +24104,23 @@ function getLspCheckDefinition() {
|
|
|
23625
24104
|
}
|
|
23626
24105
|
|
|
23627
24106
|
// src/cli/doctor/checks/mcp.ts
|
|
23628
|
-
import { existsSync as
|
|
24107
|
+
import { existsSync as existsSync12, readFileSync as readFileSync11 } from "fs";
|
|
23629
24108
|
import { homedir as homedir7 } from "os";
|
|
23630
|
-
import { join as
|
|
24109
|
+
import { join as join12 } from "path";
|
|
23631
24110
|
init_shared();
|
|
23632
24111
|
var BUILTIN_MCP_SERVERS = ["context7", "grep_app"];
|
|
23633
24112
|
var MCP_CONFIG_PATHS = [
|
|
23634
|
-
|
|
23635
|
-
|
|
23636
|
-
|
|
24113
|
+
join12(homedir7(), ".claude", ".mcp.json"),
|
|
24114
|
+
join12(process.cwd(), ".mcp.json"),
|
|
24115
|
+
join12(process.cwd(), ".claude", ".mcp.json")
|
|
23637
24116
|
];
|
|
23638
24117
|
function loadUserMcpConfig() {
|
|
23639
24118
|
const servers = {};
|
|
23640
24119
|
for (const configPath of MCP_CONFIG_PATHS) {
|
|
23641
|
-
if (!
|
|
24120
|
+
if (!existsSync12(configPath))
|
|
23642
24121
|
continue;
|
|
23643
24122
|
try {
|
|
23644
|
-
const content =
|
|
24123
|
+
const content = readFileSync11(configPath, "utf-8");
|
|
23645
24124
|
const config2 = parseJsonc(content);
|
|
23646
24125
|
if (config2.mcpServers) {
|
|
23647
24126
|
Object.assign(servers, config2.mcpServers);
|
|
@@ -23848,6 +24327,7 @@ function getAllCheckDefinitions() {
|
|
|
23848
24327
|
getOpenCodeCheckDefinition(),
|
|
23849
24328
|
getPluginCheckDefinition(),
|
|
23850
24329
|
getConfigCheckDefinition(),
|
|
24330
|
+
getModelResolutionCheckDefinition(),
|
|
23851
24331
|
...getAuthCheckDefinitions(),
|
|
23852
24332
|
...getDependencyCheckDefinitions(),
|
|
23853
24333
|
getGhCliCheckDefinition(),
|
|
@@ -24039,23 +24519,28 @@ async function doctor(options = {}) {
|
|
|
24039
24519
|
var VERSION2 = package_default.version;
|
|
24040
24520
|
var program2 = new Command;
|
|
24041
24521
|
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("--
|
|
24522
|
+
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
24523
|
Examples:
|
|
24044
24524
|
$ 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 --
|
|
24525
|
+
$ bunx oh-my-opencode install --no-tui --claude=max20 --openai=yes --gemini=yes --copilot=no
|
|
24526
|
+
$ bunx oh-my-opencode install --no-tui --claude=no --gemini=no --copilot=yes --opencode-zen=yes
|
|
24047
24527
|
|
|
24048
|
-
Model Providers:
|
|
24049
|
-
Claude
|
|
24050
|
-
|
|
24051
|
-
Gemini
|
|
24528
|
+
Model Providers (Priority: Native > Copilot > OpenCode Zen > Z.ai):
|
|
24529
|
+
Claude Native anthropic/ models (Opus, Sonnet, Haiku)
|
|
24530
|
+
OpenAI Native openai/ models (GPT-5.2 for Oracle)
|
|
24531
|
+
Gemini Native google/ models (Gemini 3 Pro, Flash)
|
|
24532
|
+
Copilot github-copilot/ models (fallback)
|
|
24533
|
+
OpenCode Zen opencode/ models (opencode/claude-opus-4-5, etc.)
|
|
24534
|
+
Z.ai zai-coding-plan/glm-4.7 (Librarian priority)
|
|
24052
24535
|
`).action(async (options) => {
|
|
24053
24536
|
const args = {
|
|
24054
24537
|
tui: options.tui !== false,
|
|
24055
24538
|
claude: options.claude,
|
|
24056
|
-
|
|
24539
|
+
openai: options.openai,
|
|
24057
24540
|
gemini: options.gemini,
|
|
24058
24541
|
copilot: options.copilot,
|
|
24542
|
+
opencodeZen: options.opencodeZen,
|
|
24543
|
+
zaiCodingPlan: options.zaiCodingPlan,
|
|
24059
24544
|
skipAuth: options.skipAuth ?? false
|
|
24060
24545
|
};
|
|
24061
24546
|
const exitCode = await install(args);
|