oh-my-opencode 3.11.2 → 3.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ja.md +18 -12
- package/README.ko.md +18 -12
- package/README.md +16 -16
- package/README.ru.md +12 -6
- package/README.zh-cn.md +18 -12
- package/dist/agents/atlas/default.d.ts +1 -1
- package/dist/agents/atlas/gemini.d.ts +1 -1
- package/dist/agents/atlas/gpt.d.ts +1 -1
- package/dist/agents/builtin-agents/general-agents.d.ts +1 -0
- package/dist/agents/dynamic-agent-prompt-builder.d.ts +2 -0
- package/dist/agents/env-context.d.ts +1 -1
- package/dist/agents/index.d.ts +1 -0
- package/dist/agents/metis.d.ts +1 -1
- package/dist/agents/prometheus/gemini.d.ts +1 -1
- package/dist/agents/prometheus/gpt.d.ts +1 -1
- package/dist/agents/prometheus/interview-mode.d.ts +1 -1
- package/dist/agents/prometheus/plan-generation.d.ts +1 -1
- package/dist/agents/prometheus/plan-template.d.ts +1 -1
- package/dist/agents/prometheus/system-prompt.d.ts +1 -1
- package/dist/agents/types.d.ts +1 -1
- package/dist/cli/config-manager/bun-install.d.ts +8 -1
- package/dist/cli/config-manager/plugin-name-with-version.d.ts +1 -1
- package/dist/cli/doctor/checks/tools-lsp.d.ts +4 -6
- package/dist/cli/doctor/types.d.ts +4 -8
- package/dist/cli/index.js +1087 -802
- package/dist/cli/install-validators.d.ts +1 -0
- package/dist/cli/model-fallback-requirements.d.ts +1 -1
- package/dist/cli/model-fallback-types.d.ts +1 -0
- package/dist/cli/openai-only-model-catalog.d.ts +3 -0
- package/dist/cli/run/index.d.ts +1 -0
- package/dist/cli/run/model-resolver.d.ts +4 -0
- package/dist/cli/run/types.d.ts +1 -0
- package/dist/cli/types.d.ts +3 -0
- package/dist/config/schema/agent-names.d.ts +3 -1
- package/dist/config/schema/background-task.d.ts +9 -0
- package/dist/config/schema/git-env-prefix.d.ts +5 -0
- package/dist/config/schema/git-master.d.ts +1 -0
- package/dist/config/schema/hooks.d.ts +2 -0
- package/dist/config/schema/oh-my-opencode-config.d.ts +10 -0
- package/dist/config/schema.d.ts +1 -0
- package/dist/create-hooks.d.ts +13 -0
- package/dist/features/background-agent/compaction-aware-message-resolver.d.ts +16 -1
- package/dist/features/background-agent/constants.d.ts +7 -2
- package/dist/features/background-agent/loop-detector.d.ts +19 -0
- package/dist/features/background-agent/manager.d.ts +20 -4
- package/dist/features/background-agent/process-cleanup.d.ts +1 -1
- package/dist/features/background-agent/remove-task-toast-tracking.d.ts +1 -0
- package/dist/features/background-agent/subagent-spawn-limits.d.ts +23 -0
- package/dist/features/background-agent/task-history.d.ts +1 -0
- package/dist/features/background-agent/task-poller.d.ts +1 -0
- package/dist/features/background-agent/types.d.ts +11 -0
- package/dist/features/builtin-commands/templates/start-work.d.ts +1 -1
- package/dist/features/claude-code-agent-loader/claude-model-mapper.d.ts +4 -0
- package/dist/features/claude-code-agent-loader/loader.d.ts +3 -3
- package/dist/features/claude-code-agent-loader/types.d.ts +8 -1
- package/dist/features/claude-code-plugin-loader/agent-loader.d.ts +2 -2
- package/dist/features/claude-code-plugin-loader/loader.d.ts +2 -2
- package/dist/features/claude-code-plugin-loader/types.d.ts +22 -3
- package/dist/features/opencode-skill-loader/git-master-template-injection.d.ts +1 -1
- package/dist/features/skill-mcp-manager/types.d.ts +4 -0
- package/dist/features/tmux-subagent/index.d.ts +1 -0
- package/dist/features/tmux-subagent/manager.d.ts +5 -0
- package/dist/features/tmux-subagent/pane-state-parser.d.ts +8 -0
- package/dist/features/tmux-subagent/tracked-session-state.d.ts +8 -0
- package/dist/features/tmux-subagent/types.d.ts +2 -0
- package/dist/hooks/atlas/boulder-session-lineage.d.ts +6 -0
- package/dist/hooks/atlas/final-wave-approval-gate.d.ts +6 -0
- package/dist/hooks/atlas/final-wave-plan-state.d.ts +5 -0
- package/dist/hooks/atlas/idle-event.d.ts +8 -0
- package/dist/hooks/atlas/resolve-active-boulder-session.d.ts +11 -0
- package/dist/hooks/atlas/tool-execute-after.d.ts +2 -0
- package/dist/hooks/atlas/types.d.ts +4 -0
- package/dist/hooks/atlas/verification-reminders.d.ts +4 -0
- package/dist/hooks/auto-slash-command/executor.d.ts +1 -0
- package/dist/hooks/auto-slash-command/hook.d.ts +7 -0
- package/dist/hooks/auto-slash-command/processed-command-store.d.ts +7 -0
- package/dist/hooks/auto-slash-command/types.d.ts +9 -0
- package/dist/hooks/auto-update-checker/checker/sync-package-json.d.ts +7 -0
- package/dist/hooks/auto-update-checker/checker.d.ts +3 -1
- package/dist/hooks/compaction-context-injector/compaction-context-prompt.d.ts +1 -0
- package/dist/hooks/compaction-context-injector/constants.d.ts +5 -0
- package/dist/hooks/compaction-context-injector/hook.d.ts +5 -1
- package/dist/hooks/compaction-context-injector/recovery-prompt-config.d.ts +6 -0
- package/dist/hooks/compaction-context-injector/recovery.d.ts +6 -0
- package/dist/hooks/compaction-context-injector/session-id.d.ts +2 -0
- package/dist/hooks/compaction-context-injector/session-prompt-config-resolver.d.ts +16 -0
- package/dist/hooks/compaction-context-injector/tail-monitor.d.ts +13 -0
- package/dist/hooks/compaction-context-injector/types.d.ts +43 -0
- package/dist/hooks/compaction-context-injector/validated-model.d.ts +13 -0
- package/dist/hooks/context-window-monitor.d.ts +2 -5
- package/dist/hooks/gpt-permission-continuation/assistant-message.d.ts +23 -0
- package/dist/hooks/gpt-permission-continuation/constants.d.ts +4 -0
- package/dist/hooks/gpt-permission-continuation/detector.d.ts +1 -0
- package/dist/hooks/gpt-permission-continuation/handler.d.ts +12 -0
- package/dist/hooks/gpt-permission-continuation/index.d.ts +13 -0
- package/dist/hooks/gpt-permission-continuation/session-state.d.ts +15 -0
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/keyword-detector/hook.d.ts +1 -0
- package/dist/hooks/preemptive-compaction.d.ts +2 -5
- package/dist/hooks/ralph-loop/pending-verification-handler.d.ts +17 -0
- package/dist/hooks/runtime-fallback/fallback-bootstrap-model.d.ts +10 -0
- package/dist/hooks/runtime-fallback/fallback-retry-dispatcher.d.ts +11 -0
- package/dist/hooks/runtime-fallback/hook.d.ts +2 -3
- package/dist/hooks/runtime-fallback/last-user-retry-parts.d.ts +4 -0
- package/dist/hooks/runtime-fallback/message-update-handler.d.ts +1 -2
- package/dist/hooks/runtime-fallback/retry-model-payload.d.ts +7 -0
- package/dist/hooks/runtime-fallback/session-messages.d.ts +9 -0
- package/dist/hooks/runtime-fallback/session-status-handler.d.ts +3 -0
- package/dist/hooks/runtime-fallback/types.d.ts +57 -3
- package/dist/hooks/runtime-fallback/visible-assistant-response.d.ts +3 -0
- package/dist/hooks/session-notification-content.d.ts +30 -0
- package/dist/hooks/session-notification-scheduler.d.ts +1 -3
- package/dist/hooks/start-work/index.d.ts +1 -1
- package/dist/hooks/start-work/worktree-detector.d.ts +7 -0
- package/dist/hooks/todo-continuation-enforcer/compaction-guard.d.ts +2 -0
- package/dist/hooks/todo-continuation-enforcer/constants.d.ts +2 -0
- package/dist/hooks/todo-continuation-enforcer/handler.d.ts +1 -0
- package/dist/hooks/todo-continuation-enforcer/idle-event.d.ts +1 -0
- package/dist/hooks/todo-continuation-enforcer/resolve-message-info.d.ts +3 -0
- package/dist/hooks/todo-continuation-enforcer/session-state.d.ts +10 -1
- package/dist/hooks/todo-continuation-enforcer/stagnation-detection.d.ts +6 -0
- package/dist/hooks/todo-continuation-enforcer/types.d.ts +10 -0
- package/dist/hooks/todo-description-override/description.d.ts +1 -0
- package/dist/hooks/todo-description-override/hook.d.ts +8 -0
- package/dist/hooks/todo-description-override/index.d.ts +1 -0
- package/dist/hooks/tool-output-truncator.d.ts +1 -0
- package/dist/index.js +10849 -6983
- package/dist/oh-my-opencode.schema.json +46 -2
- package/dist/plugin/hooks/create-continuation-hooks.d.ts +2 -1
- package/dist/plugin/hooks/create-core-hooks.d.ts +1 -0
- package/dist/plugin/hooks/create-tool-guard-hooks.d.ts +2 -1
- package/dist/plugin/normalize-tool-arg-schemas.d.ts +2 -0
- package/dist/plugin/ultrawork-model-override.d.ts +1 -15
- package/dist/plugin/ultrawork-variant-availability.d.ts +6 -0
- package/dist/plugin-dispose.d.ts +10 -0
- package/dist/plugin-handlers/agent-override-protection.d.ts +3 -0
- package/dist/plugin-state.d.ts +5 -0
- package/dist/shared/compaction-agent-config-checkpoint.d.ts +11 -0
- package/dist/shared/connected-providers-cache.d.ts +26 -29
- package/dist/shared/context-limit-resolver.d.ts +5 -0
- package/dist/shared/dynamic-truncator.d.ts +4 -7
- package/dist/shared/fallback-chain-from-models.d.ts +3 -0
- package/dist/shared/index.d.ts +3 -0
- package/dist/shared/model-error-classifier.d.ts +2 -1
- package/dist/shared/opencode-command-dirs.d.ts +3 -0
- package/dist/shared/plugin-identity.d.ts +5 -0
- package/dist/shared/question-denied-session-permission.d.ts +6 -0
- package/dist/shared/retry-status-utils.d.ts +2 -0
- package/dist/shared/shell-env.d.ts +27 -0
- package/dist/shared/tmux/tmux-utils/environment.d.ts +1 -0
- package/dist/shared/vision-capable-models-cache.d.ts +4 -0
- package/dist/tools/call-omo-agent/background-executor.d.ts +2 -1
- package/dist/tools/call-omo-agent/constants.d.ts +1 -1
- package/dist/tools/call-omo-agent/sync-executor.d.ts +11 -3
- package/dist/tools/call-omo-agent/tools.d.ts +2 -1
- package/dist/tools/delegate-task/cancel-unstable-agent-task.d.ts +2 -0
- package/dist/tools/delegate-task/model-selection.d.ts +3 -0
- package/dist/tools/delegate-task/model-string-parser.d.ts +5 -3
- package/dist/tools/hashline-edit/hash-computation.d.ts +1 -0
- package/dist/tools/hashline-edit/tool-description.d.ts +1 -1
- package/dist/tools/look-at/constants.d.ts +1 -1
- package/dist/tools/look-at/multimodal-fallback-chain.d.ts +4 -0
- package/dist/tools/lsp/constants.d.ts +1 -0
- package/dist/tools/lsp/directory-diagnostics.d.ts +1 -0
- package/dist/tools/lsp/lsp-client-transport.d.ts +4 -2
- package/dist/tools/lsp/lsp-client-wrapper.d.ts +2 -1
- package/dist/tools/lsp/server-path-bases.d.ts +1 -0
- package/package.json +18 -18
package/dist/cli/index.js
CHANGED
|
@@ -4977,6 +4977,9 @@ var init_tool_name = () => {};
|
|
|
4977
4977
|
// src/shared/file-utils.ts
|
|
4978
4978
|
var init_file_utils = () => {};
|
|
4979
4979
|
|
|
4980
|
+
// src/shared/context-limit-resolver.ts
|
|
4981
|
+
var init_context_limit_resolver = () => {};
|
|
4982
|
+
|
|
4980
4983
|
// src/shared/normalize-sdk-response.ts
|
|
4981
4984
|
function normalizeSDKResponse(response, fallback, options) {
|
|
4982
4985
|
if (response === null || response === undefined) {
|
|
@@ -5002,7 +5005,9 @@ function normalizeSDKResponse(response, fallback, options) {
|
|
|
5002
5005
|
}
|
|
5003
5006
|
|
|
5004
5007
|
// src/shared/dynamic-truncator.ts
|
|
5005
|
-
var init_dynamic_truncator = () => {
|
|
5008
|
+
var init_dynamic_truncator = __esm(() => {
|
|
5009
|
+
init_context_limit_resolver();
|
|
5010
|
+
});
|
|
5006
5011
|
|
|
5007
5012
|
// src/shared/data-path.ts
|
|
5008
5013
|
import * as path2 from "path";
|
|
@@ -6017,7 +6022,8 @@ var init_hook_names = __esm(() => {
|
|
|
6017
6022
|
"anthropic-auto-compact": "anthropic-context-window-limit-recovery",
|
|
6018
6023
|
"sisyphus-orchestrator": "atlas",
|
|
6019
6024
|
"sisyphus-gpt-hephaestus-reminder": "no-sisyphus-gpt",
|
|
6020
|
-
"empty-message-sanitizer": null
|
|
6025
|
+
"empty-message-sanitizer": null,
|
|
6026
|
+
"delegate-task-english-directive": null
|
|
6021
6027
|
};
|
|
6022
6028
|
});
|
|
6023
6029
|
|
|
@@ -6218,20 +6224,6 @@ function getCliConfigDir() {
|
|
|
6218
6224
|
if (envConfigDir) {
|
|
6219
6225
|
return resolve(envConfigDir);
|
|
6220
6226
|
}
|
|
6221
|
-
if (process.platform === "win32") {
|
|
6222
|
-
const crossPlatformDir = join3(homedir2(), ".config", "opencode");
|
|
6223
|
-
const crossPlatformConfig = join3(crossPlatformDir, "opencode.json");
|
|
6224
|
-
if (existsSync2(crossPlatformConfig)) {
|
|
6225
|
-
return crossPlatformDir;
|
|
6226
|
-
}
|
|
6227
|
-
const appData = process.env.APPDATA || join3(homedir2(), "AppData", "Roaming");
|
|
6228
|
-
const appdataDir = join3(appData, "opencode");
|
|
6229
|
-
const appdataConfig = join3(appdataDir, "opencode.json");
|
|
6230
|
-
if (existsSync2(appdataConfig)) {
|
|
6231
|
-
return appdataDir;
|
|
6232
|
-
}
|
|
6233
|
-
return crossPlatformDir;
|
|
6234
|
-
}
|
|
6235
6227
|
const xdgConfig = process.env.XDG_CONFIG_HOME || join3(homedir2(), ".config");
|
|
6236
6228
|
return join3(xdgConfig, "opencode");
|
|
6237
6229
|
}
|
|
@@ -6304,6 +6296,7 @@ var init_model_requirements = __esm(() => {
|
|
|
6304
6296
|
model: "claude-opus-4-6",
|
|
6305
6297
|
variant: "max"
|
|
6306
6298
|
},
|
|
6299
|
+
{ providers: ["opencode-go"], model: "kimi-k2.5" },
|
|
6307
6300
|
{ providers: ["kimi-for-coding"], model: "k2p5" },
|
|
6308
6301
|
{
|
|
6309
6302
|
providers: [
|
|
@@ -6349,22 +6342,22 @@ var init_model_requirements = __esm(() => {
|
|
|
6349
6342
|
providers: ["anthropic", "github-copilot", "opencode"],
|
|
6350
6343
|
model: "claude-opus-4-6",
|
|
6351
6344
|
variant: "max"
|
|
6352
|
-
}
|
|
6345
|
+
},
|
|
6346
|
+
{ providers: ["opencode-go"], model: "glm-5" }
|
|
6353
6347
|
]
|
|
6354
6348
|
},
|
|
6355
6349
|
librarian: {
|
|
6356
6350
|
fallbackChain: [
|
|
6357
|
-
{
|
|
6358
|
-
providers: ["google", "github-copilot", "opencode"],
|
|
6359
|
-
model: "gemini-3-flash"
|
|
6360
|
-
},
|
|
6351
|
+
{ providers: ["opencode-go"], model: "minimax-m2.5" },
|
|
6361
6352
|
{ providers: ["opencode"], model: "minimax-m2.5-free" },
|
|
6362
|
-
{ providers: ["opencode"], model: "
|
|
6353
|
+
{ providers: ["anthropic", "opencode"], model: "claude-haiku-4-5" },
|
|
6354
|
+
{ providers: ["opencode"], model: "gpt-5-nano" }
|
|
6363
6355
|
]
|
|
6364
6356
|
},
|
|
6365
6357
|
explore: {
|
|
6366
6358
|
fallbackChain: [
|
|
6367
6359
|
{ providers: ["github-copilot"], model: "grok-code-fast-1" },
|
|
6360
|
+
{ providers: ["opencode-go"], model: "minimax-m2.5" },
|
|
6368
6361
|
{ providers: ["opencode"], model: "minimax-m2.5-free" },
|
|
6369
6362
|
{ providers: ["anthropic", "opencode"], model: "claude-haiku-4-5" },
|
|
6370
6363
|
{ providers: ["opencode"], model: "gpt-5-nano" }
|
|
@@ -6372,21 +6365,10 @@ var init_model_requirements = __esm(() => {
|
|
|
6372
6365
|
},
|
|
6373
6366
|
"multimodal-looker": {
|
|
6374
6367
|
fallbackChain: [
|
|
6375
|
-
{
|
|
6376
|
-
|
|
6377
|
-
model: "gpt-5.4",
|
|
6378
|
-
variant: "medium"
|
|
6379
|
-
},
|
|
6380
|
-
{ providers: ["kimi-for-coding"], model: "k2p5" },
|
|
6381
|
-
{
|
|
6382
|
-
providers: ["google", "github-copilot", "opencode"],
|
|
6383
|
-
model: "gemini-3-flash"
|
|
6384
|
-
},
|
|
6368
|
+
{ providers: ["openai", "opencode"], model: "gpt-5.4", variant: "medium" },
|
|
6369
|
+
{ providers: ["opencode-go"], model: "kimi-k2.5" },
|
|
6385
6370
|
{ providers: ["zai-coding-plan"], model: "glm-4.6v" },
|
|
6386
|
-
{
|
|
6387
|
-
providers: ["openai", "github-copilot", "opencode"],
|
|
6388
|
-
model: "gpt-5-nano"
|
|
6389
|
-
}
|
|
6371
|
+
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5-nano" }
|
|
6390
6372
|
]
|
|
6391
6373
|
},
|
|
6392
6374
|
prometheus: {
|
|
@@ -6401,6 +6383,7 @@ var init_model_requirements = __esm(() => {
|
|
|
6401
6383
|
model: "gpt-5.4",
|
|
6402
6384
|
variant: "high"
|
|
6403
6385
|
},
|
|
6386
|
+
{ providers: ["opencode-go"], model: "glm-5" },
|
|
6404
6387
|
{
|
|
6405
6388
|
providers: ["google", "github-copilot", "opencode"],
|
|
6406
6389
|
model: "gemini-3.1-pro"
|
|
@@ -6419,11 +6402,8 @@ var init_model_requirements = __esm(() => {
|
|
|
6419
6402
|
model: "gpt-5.4",
|
|
6420
6403
|
variant: "high"
|
|
6421
6404
|
},
|
|
6422
|
-
{
|
|
6423
|
-
|
|
6424
|
-
model: "gemini-3.1-pro",
|
|
6425
|
-
variant: "high"
|
|
6426
|
-
}
|
|
6405
|
+
{ providers: ["opencode-go"], model: "glm-5" },
|
|
6406
|
+
{ providers: ["kimi-for-coding"], model: "k2p5" }
|
|
6427
6407
|
]
|
|
6428
6408
|
},
|
|
6429
6409
|
momus: {
|
|
@@ -6442,16 +6422,31 @@ var init_model_requirements = __esm(() => {
|
|
|
6442
6422
|
providers: ["google", "github-copilot", "opencode"],
|
|
6443
6423
|
model: "gemini-3.1-pro",
|
|
6444
6424
|
variant: "high"
|
|
6445
|
-
}
|
|
6425
|
+
},
|
|
6426
|
+
{ providers: ["opencode-go"], model: "glm-5" }
|
|
6446
6427
|
]
|
|
6447
6428
|
},
|
|
6448
6429
|
atlas: {
|
|
6449
6430
|
fallbackChain: [
|
|
6431
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-sonnet-4-6" },
|
|
6432
|
+
{ providers: ["opencode-go"], model: "kimi-k2.5" },
|
|
6450
6433
|
{
|
|
6451
|
-
providers: ["
|
|
6452
|
-
model: "
|
|
6434
|
+
providers: ["openai", "github-copilot", "opencode"],
|
|
6435
|
+
model: "gpt-5.4",
|
|
6436
|
+
variant: "medium"
|
|
6437
|
+
}
|
|
6438
|
+
]
|
|
6439
|
+
},
|
|
6440
|
+
"sisyphus-junior": {
|
|
6441
|
+
fallbackChain: [
|
|
6442
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-sonnet-4-6" },
|
|
6443
|
+
{ providers: ["opencode-go"], model: "kimi-k2.5" },
|
|
6444
|
+
{
|
|
6445
|
+
providers: ["openai", "github-copilot", "opencode"],
|
|
6446
|
+
model: "gpt-5.4",
|
|
6447
|
+
variant: "medium"
|
|
6453
6448
|
},
|
|
6454
|
-
{ providers: ["
|
|
6449
|
+
{ providers: ["opencode"], model: "big-pickle" }
|
|
6455
6450
|
]
|
|
6456
6451
|
}
|
|
6457
6452
|
};
|
|
@@ -6468,14 +6463,16 @@ var init_model_requirements = __esm(() => {
|
|
|
6468
6463
|
providers: ["anthropic", "github-copilot", "opencode"],
|
|
6469
6464
|
model: "claude-opus-4-6",
|
|
6470
6465
|
variant: "max"
|
|
6471
|
-
}
|
|
6466
|
+
},
|
|
6467
|
+
{ providers: ["opencode-go"], model: "glm-5" },
|
|
6468
|
+
{ providers: ["kimi-for-coding"], model: "k2p5" }
|
|
6472
6469
|
]
|
|
6473
6470
|
},
|
|
6474
6471
|
ultrabrain: {
|
|
6475
6472
|
fallbackChain: [
|
|
6476
6473
|
{
|
|
6477
6474
|
providers: ["openai", "opencode"],
|
|
6478
|
-
model: "gpt-5.
|
|
6475
|
+
model: "gpt-5.4",
|
|
6479
6476
|
variant: "xhigh"
|
|
6480
6477
|
},
|
|
6481
6478
|
{
|
|
@@ -6487,7 +6484,8 @@ var init_model_requirements = __esm(() => {
|
|
|
6487
6484
|
providers: ["anthropic", "github-copilot", "opencode"],
|
|
6488
6485
|
model: "claude-opus-4-6",
|
|
6489
6486
|
variant: "max"
|
|
6490
|
-
}
|
|
6487
|
+
},
|
|
6488
|
+
{ providers: ["opencode-go"], model: "glm-5" }
|
|
6491
6489
|
]
|
|
6492
6490
|
},
|
|
6493
6491
|
deep: {
|
|
@@ -6536,6 +6534,7 @@ var init_model_requirements = __esm(() => {
|
|
|
6536
6534
|
providers: ["google", "github-copilot", "opencode"],
|
|
6537
6535
|
model: "gemini-3-flash"
|
|
6538
6536
|
},
|
|
6537
|
+
{ providers: ["opencode-go"], model: "minimax-m2.5" },
|
|
6539
6538
|
{ providers: ["opencode"], model: "gpt-5-nano" }
|
|
6540
6539
|
]
|
|
6541
6540
|
},
|
|
@@ -6550,6 +6549,7 @@ var init_model_requirements = __esm(() => {
|
|
|
6550
6549
|
model: "gpt-5.3-codex",
|
|
6551
6550
|
variant: "medium"
|
|
6552
6551
|
},
|
|
6552
|
+
{ providers: ["opencode-go"], model: "kimi-k2.5" },
|
|
6553
6553
|
{
|
|
6554
6554
|
providers: ["google", "github-copilot", "opencode"],
|
|
6555
6555
|
model: "gemini-3-flash"
|
|
@@ -6558,18 +6558,20 @@ var init_model_requirements = __esm(() => {
|
|
|
6558
6558
|
},
|
|
6559
6559
|
"unspecified-high": {
|
|
6560
6560
|
fallbackChain: [
|
|
6561
|
-
{
|
|
6562
|
-
providers: ["openai", "github-copilot", "opencode"],
|
|
6563
|
-
model: "gpt-5.4",
|
|
6564
|
-
variant: "high"
|
|
6565
|
-
},
|
|
6566
6561
|
{
|
|
6567
6562
|
providers: ["anthropic", "github-copilot", "opencode"],
|
|
6568
6563
|
model: "claude-opus-4-6",
|
|
6569
6564
|
variant: "max"
|
|
6570
6565
|
},
|
|
6566
|
+
{
|
|
6567
|
+
providers: ["openai", "github-copilot", "opencode"],
|
|
6568
|
+
model: "gpt-5.4",
|
|
6569
|
+
variant: "high"
|
|
6570
|
+
},
|
|
6571
6571
|
{ providers: ["zai-coding-plan", "opencode"], model: "glm-5" },
|
|
6572
6572
|
{ providers: ["kimi-for-coding"], model: "k2p5" },
|
|
6573
|
+
{ providers: ["opencode-go"], model: "glm-5" },
|
|
6574
|
+
{ providers: ["opencode"], model: "kimi-k2.5" },
|
|
6573
6575
|
{
|
|
6574
6576
|
providers: [
|
|
6575
6577
|
"opencode",
|
|
@@ -6589,6 +6591,7 @@ var init_model_requirements = __esm(() => {
|
|
|
6589
6591
|
providers: ["google", "github-copilot", "opencode"],
|
|
6590
6592
|
model: "gemini-3-flash"
|
|
6591
6593
|
},
|
|
6594
|
+
{ providers: ["opencode-go"], model: "kimi-k2.5" },
|
|
6592
6595
|
{
|
|
6593
6596
|
providers: ["anthropic", "github-copilot", "opencode"],
|
|
6594
6597
|
model: "claude-sonnet-4-6"
|
|
@@ -6616,85 +6619,146 @@ var init_agent_tool_restrictions = () => {};
|
|
|
6616
6619
|
// src/shared/connected-providers-cache.ts
|
|
6617
6620
|
import { existsSync as existsSync3, readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync } from "fs";
|
|
6618
6621
|
import { join as join4 } from "path";
|
|
6619
|
-
function
|
|
6620
|
-
|
|
6621
|
-
|
|
6622
|
-
function ensureCacheDir() {
|
|
6623
|
-
const cacheDir = getOmoOpenCodeCacheDir();
|
|
6624
|
-
if (!existsSync3(cacheDir)) {
|
|
6625
|
-
mkdirSync(cacheDir, { recursive: true });
|
|
6622
|
+
function createConnectedProvidersCacheStore(getCacheDir2 = getOmoOpenCodeCacheDir) {
|
|
6623
|
+
function getCacheFilePath(filename) {
|
|
6624
|
+
return join4(getCacheDir2(), filename);
|
|
6626
6625
|
}
|
|
6627
|
-
|
|
6628
|
-
|
|
6629
|
-
|
|
6630
|
-
|
|
6631
|
-
|
|
6632
|
-
connected,
|
|
6633
|
-
updatedAt: new Date().toISOString()
|
|
6634
|
-
};
|
|
6635
|
-
try {
|
|
6636
|
-
writeFileSync2(cacheFile, JSON.stringify(data, null, 2));
|
|
6637
|
-
log("[connected-providers-cache] Cache written", { count: connected.length });
|
|
6638
|
-
} catch (err) {
|
|
6639
|
-
log("[connected-providers-cache] Error writing cache", { error: String(err) });
|
|
6626
|
+
function ensureCacheDir() {
|
|
6627
|
+
const cacheDir = getCacheDir2();
|
|
6628
|
+
if (!existsSync3(cacheDir)) {
|
|
6629
|
+
mkdirSync(cacheDir, { recursive: true });
|
|
6630
|
+
}
|
|
6640
6631
|
}
|
|
6641
|
-
|
|
6642
|
-
|
|
6643
|
-
|
|
6644
|
-
|
|
6645
|
-
|
|
6646
|
-
|
|
6647
|
-
|
|
6648
|
-
|
|
6649
|
-
|
|
6650
|
-
|
|
6651
|
-
|
|
6652
|
-
|
|
6653
|
-
|
|
6654
|
-
|
|
6655
|
-
|
|
6656
|
-
providerCount: Object.keys(data.models).length
|
|
6657
|
-
});
|
|
6658
|
-
} catch (err) {
|
|
6659
|
-
log("[connected-providers-cache] Error writing provider-models cache", { error: String(err) });
|
|
6632
|
+
function readConnectedProvidersCache() {
|
|
6633
|
+
const cacheFile = getCacheFilePath(CONNECTED_PROVIDERS_CACHE_FILE);
|
|
6634
|
+
if (!existsSync3(cacheFile)) {
|
|
6635
|
+
log("[connected-providers-cache] Cache file not found", { cacheFile });
|
|
6636
|
+
return null;
|
|
6637
|
+
}
|
|
6638
|
+
try {
|
|
6639
|
+
const content = readFileSync2(cacheFile, "utf-8");
|
|
6640
|
+
const data = JSON.parse(content);
|
|
6641
|
+
log("[connected-providers-cache] Read cache", { count: data.connected.length, updatedAt: data.updatedAt });
|
|
6642
|
+
return data.connected;
|
|
6643
|
+
} catch (err) {
|
|
6644
|
+
log("[connected-providers-cache] Error reading cache", { error: String(err) });
|
|
6645
|
+
return null;
|
|
6646
|
+
}
|
|
6660
6647
|
}
|
|
6661
|
-
|
|
6662
|
-
|
|
6663
|
-
|
|
6664
|
-
log("[connected-providers-cache] client.provider.list not available");
|
|
6665
|
-
return;
|
|
6648
|
+
function hasConnectedProvidersCache() {
|
|
6649
|
+
const cacheFile = getCacheFilePath(CONNECTED_PROVIDERS_CACHE_FILE);
|
|
6650
|
+
return existsSync3(cacheFile);
|
|
6666
6651
|
}
|
|
6667
|
-
|
|
6668
|
-
|
|
6669
|
-
const
|
|
6670
|
-
|
|
6671
|
-
|
|
6672
|
-
|
|
6673
|
-
|
|
6674
|
-
|
|
6675
|
-
|
|
6676
|
-
|
|
6677
|
-
|
|
6678
|
-
|
|
6679
|
-
|
|
6680
|
-
|
|
6681
|
-
|
|
6682
|
-
|
|
6683
|
-
|
|
6684
|
-
|
|
6685
|
-
|
|
6686
|
-
|
|
6687
|
-
|
|
6688
|
-
|
|
6689
|
-
|
|
6690
|
-
|
|
6691
|
-
|
|
6652
|
+
function writeConnectedProvidersCache(connected) {
|
|
6653
|
+
ensureCacheDir();
|
|
6654
|
+
const cacheFile = getCacheFilePath(CONNECTED_PROVIDERS_CACHE_FILE);
|
|
6655
|
+
const data = {
|
|
6656
|
+
connected,
|
|
6657
|
+
updatedAt: new Date().toISOString()
|
|
6658
|
+
};
|
|
6659
|
+
try {
|
|
6660
|
+
writeFileSync2(cacheFile, JSON.stringify(data, null, 2));
|
|
6661
|
+
log("[connected-providers-cache] Cache written", { count: connected.length });
|
|
6662
|
+
} catch (err) {
|
|
6663
|
+
log("[connected-providers-cache] Error writing cache", { error: String(err) });
|
|
6664
|
+
}
|
|
6665
|
+
}
|
|
6666
|
+
function readProviderModelsCache() {
|
|
6667
|
+
const cacheFile = getCacheFilePath(PROVIDER_MODELS_CACHE_FILE);
|
|
6668
|
+
if (!existsSync3(cacheFile)) {
|
|
6669
|
+
log("[connected-providers-cache] Provider-models cache file not found", { cacheFile });
|
|
6670
|
+
return null;
|
|
6671
|
+
}
|
|
6672
|
+
try {
|
|
6673
|
+
const content = readFileSync2(cacheFile, "utf-8");
|
|
6674
|
+
const data = JSON.parse(content);
|
|
6675
|
+
log("[connected-providers-cache] Read provider-models cache", {
|
|
6676
|
+
providerCount: Object.keys(data.models).length,
|
|
6677
|
+
updatedAt: data.updatedAt
|
|
6678
|
+
});
|
|
6679
|
+
return data;
|
|
6680
|
+
} catch (err) {
|
|
6681
|
+
log("[connected-providers-cache] Error reading provider-models cache", { error: String(err) });
|
|
6682
|
+
return null;
|
|
6683
|
+
}
|
|
6692
6684
|
}
|
|
6685
|
+
function hasProviderModelsCache() {
|
|
6686
|
+
const cacheFile = getCacheFilePath(PROVIDER_MODELS_CACHE_FILE);
|
|
6687
|
+
return existsSync3(cacheFile);
|
|
6688
|
+
}
|
|
6689
|
+
function writeProviderModelsCache(data) {
|
|
6690
|
+
ensureCacheDir();
|
|
6691
|
+
const cacheFile = getCacheFilePath(PROVIDER_MODELS_CACHE_FILE);
|
|
6692
|
+
const cacheData = {
|
|
6693
|
+
...data,
|
|
6694
|
+
updatedAt: new Date().toISOString()
|
|
6695
|
+
};
|
|
6696
|
+
try {
|
|
6697
|
+
writeFileSync2(cacheFile, JSON.stringify(cacheData, null, 2));
|
|
6698
|
+
log("[connected-providers-cache] Provider-models cache written", {
|
|
6699
|
+
providerCount: Object.keys(data.models).length
|
|
6700
|
+
});
|
|
6701
|
+
} catch (err) {
|
|
6702
|
+
log("[connected-providers-cache] Error writing provider-models cache", { error: String(err) });
|
|
6703
|
+
}
|
|
6704
|
+
}
|
|
6705
|
+
async function updateConnectedProvidersCache(client) {
|
|
6706
|
+
if (!client?.provider?.list) {
|
|
6707
|
+
log("[connected-providers-cache] client.provider.list not available");
|
|
6708
|
+
return;
|
|
6709
|
+
}
|
|
6710
|
+
try {
|
|
6711
|
+
const result = await client.provider.list();
|
|
6712
|
+
const connected = result.data?.connected ?? [];
|
|
6713
|
+
log("[connected-providers-cache] Fetched connected providers", {
|
|
6714
|
+
count: connected.length,
|
|
6715
|
+
providers: connected
|
|
6716
|
+
});
|
|
6717
|
+
writeConnectedProvidersCache(connected);
|
|
6718
|
+
const modelsByProvider = {};
|
|
6719
|
+
const allProviders = result.data?.all ?? [];
|
|
6720
|
+
for (const provider of allProviders) {
|
|
6721
|
+
if (provider.models) {
|
|
6722
|
+
const modelIds = Object.keys(provider.models);
|
|
6723
|
+
if (modelIds.length > 0) {
|
|
6724
|
+
modelsByProvider[provider.id] = modelIds;
|
|
6725
|
+
}
|
|
6726
|
+
}
|
|
6727
|
+
}
|
|
6728
|
+
log("[connected-providers-cache] Extracted models from provider list", {
|
|
6729
|
+
providerCount: Object.keys(modelsByProvider).length,
|
|
6730
|
+
totalModels: Object.values(modelsByProvider).reduce((sum, ids) => sum + ids.length, 0)
|
|
6731
|
+
});
|
|
6732
|
+
writeProviderModelsCache({
|
|
6733
|
+
models: modelsByProvider,
|
|
6734
|
+
connected
|
|
6735
|
+
});
|
|
6736
|
+
} catch (err) {
|
|
6737
|
+
log("[connected-providers-cache] Error updating cache", { error: String(err) });
|
|
6738
|
+
}
|
|
6739
|
+
}
|
|
6740
|
+
return {
|
|
6741
|
+
readConnectedProvidersCache,
|
|
6742
|
+
hasConnectedProvidersCache,
|
|
6743
|
+
readProviderModelsCache,
|
|
6744
|
+
hasProviderModelsCache,
|
|
6745
|
+
writeProviderModelsCache,
|
|
6746
|
+
updateConnectedProvidersCache
|
|
6747
|
+
};
|
|
6693
6748
|
}
|
|
6694
|
-
var CONNECTED_PROVIDERS_CACHE_FILE = "connected-providers.json", PROVIDER_MODELS_CACHE_FILE = "provider-models.json";
|
|
6749
|
+
var CONNECTED_PROVIDERS_CACHE_FILE = "connected-providers.json", PROVIDER_MODELS_CACHE_FILE = "provider-models.json", defaultConnectedProvidersCacheStore, readConnectedProvidersCache, hasConnectedProvidersCache, readProviderModelsCache, hasProviderModelsCache, writeProviderModelsCache, updateConnectedProvidersCache;
|
|
6695
6750
|
var init_connected_providers_cache = __esm(() => {
|
|
6696
6751
|
init_logger();
|
|
6697
6752
|
init_data_path();
|
|
6753
|
+
defaultConnectedProvidersCacheStore = createConnectedProvidersCacheStore(() => getOmoOpenCodeCacheDir());
|
|
6754
|
+
({
|
|
6755
|
+
readConnectedProvidersCache,
|
|
6756
|
+
hasConnectedProvidersCache,
|
|
6757
|
+
readProviderModelsCache,
|
|
6758
|
+
hasProviderModelsCache,
|
|
6759
|
+
writeProviderModelsCache,
|
|
6760
|
+
updateConnectedProvidersCache
|
|
6761
|
+
} = defaultConnectedProvidersCacheStore);
|
|
6698
6762
|
});
|
|
6699
6763
|
|
|
6700
6764
|
// src/shared/model-availability.ts
|
|
@@ -6940,6 +7004,11 @@ var init_git_worktree = __esm(() => {
|
|
|
6940
7004
|
var init_safe_create_hook = __esm(() => {
|
|
6941
7005
|
init_logger();
|
|
6942
7006
|
});
|
|
7007
|
+
// src/shared/opencode-command-dirs.ts
|
|
7008
|
+
var init_opencode_command_dirs = __esm(() => {
|
|
7009
|
+
init_opencode_config_dir();
|
|
7010
|
+
});
|
|
7011
|
+
|
|
6943
7012
|
// src/shared/session-directory-resolver.ts
|
|
6944
7013
|
var init_session_directory_resolver = () => {};
|
|
6945
7014
|
|
|
@@ -6975,12 +7044,22 @@ var init_skill_loader = __esm(() => {
|
|
|
6975
7044
|
init_skill_path_resolver();
|
|
6976
7045
|
init_logger();
|
|
6977
7046
|
});
|
|
7047
|
+
// src/features/claude-code-agent-loader/claude-model-mapper.ts
|
|
7048
|
+
var ANTHROPIC_PREFIX = "anthropic/", CLAUDE_CODE_ALIAS_MAP;
|
|
7049
|
+
var init_claude_model_mapper = __esm(() => {
|
|
7050
|
+
CLAUDE_CODE_ALIAS_MAP = new Map([
|
|
7051
|
+
["sonnet", `${ANTHROPIC_PREFIX}claude-sonnet-4-6`],
|
|
7052
|
+
["opus", `${ANTHROPIC_PREFIX}claude-opus-4-6`],
|
|
7053
|
+
["haiku", `${ANTHROPIC_PREFIX}claude-haiku-4-5`]
|
|
7054
|
+
]);
|
|
7055
|
+
});
|
|
6978
7056
|
|
|
6979
7057
|
// src/features/claude-code-plugin-loader/agent-loader.ts
|
|
6980
7058
|
var init_agent_loader = __esm(() => {
|
|
6981
7059
|
init_frontmatter();
|
|
6982
7060
|
init_file_utils();
|
|
6983
7061
|
init_logger();
|
|
7062
|
+
init_claude_model_mapper();
|
|
6984
7063
|
});
|
|
6985
7064
|
// src/features/claude-code-mcp-loader/transformer.ts
|
|
6986
7065
|
var init_transformer = () => {};
|
|
@@ -7034,6 +7113,9 @@ var init_session_category_registry = __esm(() => {
|
|
|
7034
7113
|
sessionCategoryMap = new Map;
|
|
7035
7114
|
});
|
|
7036
7115
|
|
|
7116
|
+
// src/shared/plugin-identity.ts
|
|
7117
|
+
var PLUGIN_NAME = "oh-my-opencode", LEGACY_PLUGIN_NAME = "oh-my-openagent";
|
|
7118
|
+
|
|
7037
7119
|
// src/shared/index.ts
|
|
7038
7120
|
var init_shared = __esm(() => {
|
|
7039
7121
|
init_model_resolver();
|
|
@@ -7068,6 +7150,7 @@ var init_shared = __esm(() => {
|
|
|
7068
7150
|
init_model_availability();
|
|
7069
7151
|
init_fallback_model_availability();
|
|
7070
7152
|
init_connected_providers_cache();
|
|
7153
|
+
init_context_limit_resolver();
|
|
7071
7154
|
init_session_utils();
|
|
7072
7155
|
init_tmux();
|
|
7073
7156
|
init_model_suggestion_retry();
|
|
@@ -7078,6 +7161,7 @@ var init_shared = __esm(() => {
|
|
|
7078
7161
|
init_safe_create_hook();
|
|
7079
7162
|
init_opencode_storage_paths();
|
|
7080
7163
|
init_opencode_message_dir();
|
|
7164
|
+
init_opencode_command_dirs();
|
|
7081
7165
|
init_session_directory_resolver();
|
|
7082
7166
|
init_prompt_tools();
|
|
7083
7167
|
init_plugin_command_discovery();
|
|
@@ -7129,26 +7213,26 @@ async function fetchNpmDistTags(packageName) {
|
|
|
7129
7213
|
var NPM_FETCH_TIMEOUT_MS = 5000;
|
|
7130
7214
|
|
|
7131
7215
|
// src/cli/config-manager/plugin-name-with-version.ts
|
|
7132
|
-
function getFallbackEntry(version) {
|
|
7216
|
+
function getFallbackEntry(version, packageName) {
|
|
7133
7217
|
const prereleaseMatch = version.match(/-([a-zA-Z][a-zA-Z0-9-]*)(?:\.|$)/);
|
|
7134
7218
|
if (prereleaseMatch) {
|
|
7135
|
-
return `${
|
|
7219
|
+
return `${packageName}@${prereleaseMatch[1]}`;
|
|
7136
7220
|
}
|
|
7137
|
-
return
|
|
7221
|
+
return packageName;
|
|
7138
7222
|
}
|
|
7139
|
-
async function getPluginNameWithVersion(currentVersion) {
|
|
7140
|
-
const distTags = await fetchNpmDistTags(
|
|
7223
|
+
async function getPluginNameWithVersion(currentVersion, packageName = DEFAULT_PACKAGE_NAME) {
|
|
7224
|
+
const distTags = await fetchNpmDistTags(packageName);
|
|
7141
7225
|
if (distTags) {
|
|
7142
7226
|
const allTags = new Set([...PRIORITIZED_TAGS, ...Object.keys(distTags)]);
|
|
7143
7227
|
for (const tag of allTags) {
|
|
7144
7228
|
if (distTags[tag] === currentVersion) {
|
|
7145
|
-
return `${
|
|
7229
|
+
return `${packageName}@${tag}`;
|
|
7146
7230
|
}
|
|
7147
7231
|
}
|
|
7148
7232
|
}
|
|
7149
|
-
return getFallbackEntry(currentVersion);
|
|
7233
|
+
return getFallbackEntry(currentVersion, packageName);
|
|
7150
7234
|
}
|
|
7151
|
-
var
|
|
7235
|
+
var DEFAULT_PACKAGE_NAME = "oh-my-opencode", PRIORITIZED_TAGS;
|
|
7152
7236
|
var init_plugin_name_with_version = __esm(() => {
|
|
7153
7237
|
PRIORITIZED_TAGS = ["latest", "beta", "next"];
|
|
7154
7238
|
});
|
|
@@ -7258,7 +7342,7 @@ async function addPluginToOpenCodeConfig(currentVersion) {
|
|
|
7258
7342
|
};
|
|
7259
7343
|
}
|
|
7260
7344
|
const { format: format2, path: path3 } = detectConfigFormat();
|
|
7261
|
-
const pluginEntry = await getPluginNameWithVersion(currentVersion);
|
|
7345
|
+
const pluginEntry = await getPluginNameWithVersion(currentVersion, PLUGIN_NAME);
|
|
7262
7346
|
try {
|
|
7263
7347
|
if (format2 === "none") {
|
|
7264
7348
|
const config2 = { plugin: [pluginEntry] };
|
|
@@ -7276,12 +7360,15 @@ async function addPluginToOpenCodeConfig(currentVersion) {
|
|
|
7276
7360
|
}
|
|
7277
7361
|
const config = parseResult.config;
|
|
7278
7362
|
const plugins = config.plugin ?? [];
|
|
7279
|
-
const
|
|
7280
|
-
|
|
7281
|
-
|
|
7363
|
+
const currentNameIndex = plugins.findIndex((plugin) => plugin === PLUGIN_NAME || plugin.startsWith(`${PLUGIN_NAME}@`));
|
|
7364
|
+
const legacyNameIndex = plugins.findIndex((plugin) => plugin === LEGACY_PLUGIN_NAME || plugin.startsWith(`${LEGACY_PLUGIN_NAME}@`));
|
|
7365
|
+
if (currentNameIndex !== -1) {
|
|
7366
|
+
if (plugins[currentNameIndex] === pluginEntry) {
|
|
7282
7367
|
return { success: true, configPath: path3 };
|
|
7283
7368
|
}
|
|
7284
|
-
plugins[
|
|
7369
|
+
plugins[currentNameIndex] = pluginEntry;
|
|
7370
|
+
} else if (legacyNameIndex !== -1) {
|
|
7371
|
+
plugins[legacyNameIndex] = pluginEntry;
|
|
7285
7372
|
} else {
|
|
7286
7373
|
plugins.push(pluginEntry);
|
|
7287
7374
|
}
|
|
@@ -7315,8 +7402,8 @@ async function addPluginToOpenCodeConfig(currentVersion) {
|
|
|
7315
7402
|
};
|
|
7316
7403
|
}
|
|
7317
7404
|
}
|
|
7318
|
-
var PACKAGE_NAME2 = "oh-my-opencode";
|
|
7319
7405
|
var init_add_plugin_to_opencode_config = __esm(() => {
|
|
7406
|
+
init_shared();
|
|
7320
7407
|
init_config_context();
|
|
7321
7408
|
init_ensure_config_directory_exists();
|
|
7322
7409
|
init_opencode_config_format();
|
|
@@ -7327,290 +7414,39 @@ var init_add_plugin_to_opencode_config = __esm(() => {
|
|
|
7327
7414
|
// src/cli/model-fallback-requirements.ts
|
|
7328
7415
|
var CLI_AGENT_MODEL_REQUIREMENTS, CLI_CATEGORY_MODEL_REQUIREMENTS;
|
|
7329
7416
|
var init_model_fallback_requirements = __esm(() => {
|
|
7330
|
-
|
|
7331
|
-
|
|
7332
|
-
|
|
7333
|
-
|
|
7334
|
-
|
|
7335
|
-
|
|
7336
|
-
|
|
7337
|
-
|
|
7338
|
-
|
|
7339
|
-
|
|
7340
|
-
|
|
7341
|
-
|
|
7342
|
-
|
|
7343
|
-
|
|
7344
|
-
|
|
7345
|
-
fallbackChain: [
|
|
7346
|
-
{
|
|
7347
|
-
providers: ["openai", "opencode"],
|
|
7348
|
-
model: "gpt-5.3-codex",
|
|
7349
|
-
variant: "medium"
|
|
7350
|
-
}
|
|
7351
|
-
],
|
|
7352
|
-
requiresProvider: ["openai", "opencode"]
|
|
7353
|
-
},
|
|
7354
|
-
oracle: {
|
|
7355
|
-
fallbackChain: [
|
|
7356
|
-
{
|
|
7357
|
-
providers: ["openai", "github-copilot", "opencode"],
|
|
7358
|
-
model: "gpt-5.4",
|
|
7359
|
-
variant: "high"
|
|
7360
|
-
},
|
|
7361
|
-
{
|
|
7362
|
-
providers: ["google", "github-copilot", "opencode"],
|
|
7363
|
-
model: "gemini-3.1-pro",
|
|
7364
|
-
variant: "high"
|
|
7365
|
-
},
|
|
7366
|
-
{
|
|
7367
|
-
providers: ["anthropic", "github-copilot", "opencode"],
|
|
7368
|
-
model: "claude-opus-4-6",
|
|
7369
|
-
variant: "max"
|
|
7370
|
-
}
|
|
7371
|
-
]
|
|
7372
|
-
},
|
|
7373
|
-
librarian: {
|
|
7374
|
-
fallbackChain: [
|
|
7375
|
-
{ providers: ["zai-coding-plan"], model: "glm-4.7" },
|
|
7376
|
-
{ providers: ["opencode"], model: "glm-4.7-free" },
|
|
7377
|
-
{
|
|
7378
|
-
providers: ["anthropic", "github-copilot", "opencode"],
|
|
7379
|
-
model: "claude-sonnet-4-5"
|
|
7380
|
-
}
|
|
7381
|
-
]
|
|
7382
|
-
},
|
|
7383
|
-
explore: {
|
|
7384
|
-
fallbackChain: [
|
|
7385
|
-
{ providers: ["github-copilot"], model: "grok-code-fast-1" },
|
|
7386
|
-
{ providers: ["anthropic", "opencode"], model: "claude-haiku-4-5" },
|
|
7387
|
-
{ providers: ["opencode"], model: "gpt-5-nano" }
|
|
7388
|
-
]
|
|
7389
|
-
},
|
|
7390
|
-
"multimodal-looker": {
|
|
7391
|
-
fallbackChain: [
|
|
7392
|
-
{
|
|
7393
|
-
providers: ["openai", "opencode"],
|
|
7394
|
-
model: "gpt-5.4",
|
|
7395
|
-
variant: "medium"
|
|
7396
|
-
},
|
|
7397
|
-
{ providers: ["kimi-for-coding"], model: "k2p5" },
|
|
7398
|
-
{
|
|
7399
|
-
providers: ["google", "github-copilot", "opencode"],
|
|
7400
|
-
model: "gemini-3-flash"
|
|
7401
|
-
},
|
|
7402
|
-
{ providers: ["zai-coding-plan"], model: "glm-4.6v" },
|
|
7403
|
-
{ providers: ["opencode"], model: "gpt-5-nano" }
|
|
7404
|
-
]
|
|
7405
|
-
},
|
|
7406
|
-
prometheus: {
|
|
7407
|
-
fallbackChain: [
|
|
7408
|
-
{
|
|
7409
|
-
providers: ["anthropic", "github-copilot", "opencode"],
|
|
7410
|
-
model: "claude-opus-4-6",
|
|
7411
|
-
variant: "max"
|
|
7412
|
-
},
|
|
7413
|
-
{ providers: ["kimi-for-coding"], model: "k2p5" },
|
|
7414
|
-
{
|
|
7415
|
-
providers: ["openai", "github-copilot", "opencode"],
|
|
7416
|
-
model: "gpt-5.4",
|
|
7417
|
-
variant: "high"
|
|
7418
|
-
},
|
|
7419
|
-
{
|
|
7420
|
-
providers: ["google", "github-copilot", "opencode"],
|
|
7421
|
-
model: "gemini-3.1-pro"
|
|
7422
|
-
}
|
|
7423
|
-
]
|
|
7424
|
-
},
|
|
7425
|
-
metis: {
|
|
7426
|
-
fallbackChain: [
|
|
7427
|
-
{
|
|
7428
|
-
providers: ["anthropic", "github-copilot", "opencode"],
|
|
7429
|
-
model: "claude-opus-4-6",
|
|
7430
|
-
variant: "max"
|
|
7431
|
-
},
|
|
7432
|
-
{ providers: ["kimi-for-coding"], model: "k2p5" },
|
|
7433
|
-
{
|
|
7434
|
-
providers: ["openai", "github-copilot", "opencode"],
|
|
7435
|
-
model: "gpt-5.4",
|
|
7436
|
-
variant: "high"
|
|
7437
|
-
},
|
|
7438
|
-
{
|
|
7439
|
-
providers: ["google", "github-copilot", "opencode"],
|
|
7440
|
-
model: "gemini-3.1-pro",
|
|
7441
|
-
variant: "high"
|
|
7442
|
-
}
|
|
7443
|
-
]
|
|
7444
|
-
},
|
|
7445
|
-
momus: {
|
|
7446
|
-
fallbackChain: [
|
|
7447
|
-
{
|
|
7448
|
-
providers: ["openai", "github-copilot", "opencode"],
|
|
7449
|
-
model: "gpt-5.4",
|
|
7450
|
-
variant: "xhigh"
|
|
7451
|
-
},
|
|
7452
|
-
{
|
|
7453
|
-
providers: ["anthropic", "github-copilot", "opencode"],
|
|
7454
|
-
model: "claude-opus-4-6",
|
|
7455
|
-
variant: "max"
|
|
7456
|
-
},
|
|
7457
|
-
{
|
|
7458
|
-
providers: ["google", "github-copilot", "opencode"],
|
|
7459
|
-
model: "gemini-3.1-pro",
|
|
7460
|
-
variant: "high"
|
|
7461
|
-
}
|
|
7462
|
-
]
|
|
7417
|
+
init_model_requirements();
|
|
7418
|
+
CLI_AGENT_MODEL_REQUIREMENTS = AGENT_MODEL_REQUIREMENTS;
|
|
7419
|
+
CLI_CATEGORY_MODEL_REQUIREMENTS = CATEGORY_MODEL_REQUIREMENTS;
|
|
7420
|
+
});
|
|
7421
|
+
|
|
7422
|
+
// src/cli/openai-only-model-catalog.ts
|
|
7423
|
+
function isOpenAiOnlyAvailability(availability) {
|
|
7424
|
+
return availability.native.openai && !availability.native.claude && !availability.native.gemini && !availability.opencodeGo && !availability.opencodeZen && !availability.copilot && !availability.zai && !availability.kimiForCoding;
|
|
7425
|
+
}
|
|
7426
|
+
function applyOpenAiOnlyModelCatalog(config) {
|
|
7427
|
+
return {
|
|
7428
|
+
...config,
|
|
7429
|
+
agents: {
|
|
7430
|
+
...config.agents,
|
|
7431
|
+
...OPENAI_ONLY_AGENT_OVERRIDES
|
|
7463
7432
|
},
|
|
7464
|
-
|
|
7465
|
-
|
|
7466
|
-
|
|
7467
|
-
{
|
|
7468
|
-
providers: ["anthropic", "github-copilot", "opencode"],
|
|
7469
|
-
model: "claude-sonnet-4-5"
|
|
7470
|
-
},
|
|
7471
|
-
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.4", variant: "medium" },
|
|
7472
|
-
{
|
|
7473
|
-
providers: ["google", "github-copilot", "opencode"],
|
|
7474
|
-
model: "gemini-3.1-pro"
|
|
7475
|
-
}
|
|
7476
|
-
]
|
|
7433
|
+
categories: {
|
|
7434
|
+
...config.categories,
|
|
7435
|
+
...OPENAI_ONLY_CATEGORY_OVERRIDES
|
|
7477
7436
|
}
|
|
7478
7437
|
};
|
|
7479
|
-
|
|
7480
|
-
|
|
7481
|
-
|
|
7482
|
-
|
|
7483
|
-
|
|
7484
|
-
|
|
7485
|
-
|
|
7486
|
-
|
|
7487
|
-
|
|
7488
|
-
|
|
7489
|
-
|
|
7490
|
-
|
|
7491
|
-
variant: "max"
|
|
7492
|
-
},
|
|
7493
|
-
{ providers: ["kimi-for-coding"], model: "k2p5" }
|
|
7494
|
-
]
|
|
7495
|
-
},
|
|
7496
|
-
ultrabrain: {
|
|
7497
|
-
fallbackChain: [
|
|
7498
|
-
{
|
|
7499
|
-
providers: ["openai", "opencode"],
|
|
7500
|
-
model: "gpt-5.3-codex",
|
|
7501
|
-
variant: "xhigh"
|
|
7502
|
-
},
|
|
7503
|
-
{
|
|
7504
|
-
providers: ["google", "github-copilot", "opencode"],
|
|
7505
|
-
model: "gemini-3.1-pro",
|
|
7506
|
-
variant: "high"
|
|
7507
|
-
},
|
|
7508
|
-
{
|
|
7509
|
-
providers: ["anthropic", "github-copilot", "opencode"],
|
|
7510
|
-
model: "claude-opus-4-6",
|
|
7511
|
-
variant: "max"
|
|
7512
|
-
}
|
|
7513
|
-
]
|
|
7514
|
-
},
|
|
7515
|
-
deep: {
|
|
7516
|
-
fallbackChain: [
|
|
7517
|
-
{
|
|
7518
|
-
providers: ["openai", "opencode"],
|
|
7519
|
-
model: "gpt-5.3-codex",
|
|
7520
|
-
variant: "medium"
|
|
7521
|
-
},
|
|
7522
|
-
{
|
|
7523
|
-
providers: ["anthropic", "github-copilot", "opencode"],
|
|
7524
|
-
model: "claude-opus-4-6",
|
|
7525
|
-
variant: "max"
|
|
7526
|
-
},
|
|
7527
|
-
{
|
|
7528
|
-
providers: ["google", "github-copilot", "opencode"],
|
|
7529
|
-
model: "gemini-3.1-pro",
|
|
7530
|
-
variant: "high"
|
|
7531
|
-
}
|
|
7532
|
-
],
|
|
7533
|
-
requiresModel: "gpt-5.3-codex"
|
|
7534
|
-
},
|
|
7535
|
-
artistry: {
|
|
7536
|
-
fallbackChain: [
|
|
7537
|
-
{
|
|
7538
|
-
providers: ["google", "github-copilot", "opencode"],
|
|
7539
|
-
model: "gemini-3.1-pro",
|
|
7540
|
-
variant: "high"
|
|
7541
|
-
},
|
|
7542
|
-
{
|
|
7543
|
-
providers: ["anthropic", "github-copilot", "opencode"],
|
|
7544
|
-
model: "claude-opus-4-6",
|
|
7545
|
-
variant: "max"
|
|
7546
|
-
},
|
|
7547
|
-
{
|
|
7548
|
-
providers: ["openai", "github-copilot", "opencode"],
|
|
7549
|
-
model: "gpt-5.4"
|
|
7550
|
-
}
|
|
7551
|
-
],
|
|
7552
|
-
requiresModel: "gemini-3.1-pro"
|
|
7553
|
-
},
|
|
7554
|
-
quick: {
|
|
7555
|
-
fallbackChain: [
|
|
7556
|
-
{
|
|
7557
|
-
providers: ["anthropic", "github-copilot", "opencode"],
|
|
7558
|
-
model: "claude-haiku-4-5"
|
|
7559
|
-
},
|
|
7560
|
-
{
|
|
7561
|
-
providers: ["google", "github-copilot", "opencode"],
|
|
7562
|
-
model: "gemini-3-flash"
|
|
7563
|
-
},
|
|
7564
|
-
{ providers: ["opencode"], model: "gpt-5-nano" }
|
|
7565
|
-
]
|
|
7566
|
-
},
|
|
7567
|
-
"unspecified-low": {
|
|
7568
|
-
fallbackChain: [
|
|
7569
|
-
{
|
|
7570
|
-
providers: ["anthropic", "github-copilot", "opencode"],
|
|
7571
|
-
model: "claude-sonnet-4-5"
|
|
7572
|
-
},
|
|
7573
|
-
{
|
|
7574
|
-
providers: ["openai", "opencode"],
|
|
7575
|
-
model: "gpt-5.3-codex",
|
|
7576
|
-
variant: "medium"
|
|
7577
|
-
},
|
|
7578
|
-
{
|
|
7579
|
-
providers: ["google", "github-copilot", "opencode"],
|
|
7580
|
-
model: "gemini-3-flash"
|
|
7581
|
-
}
|
|
7582
|
-
]
|
|
7583
|
-
},
|
|
7584
|
-
"unspecified-high": {
|
|
7585
|
-
fallbackChain: [
|
|
7586
|
-
{
|
|
7587
|
-
providers: ["openai", "github-copilot", "opencode"],
|
|
7588
|
-
model: "gpt-5.4",
|
|
7589
|
-
variant: "high"
|
|
7590
|
-
},
|
|
7591
|
-
{
|
|
7592
|
-
providers: ["anthropic", "github-copilot", "opencode"],
|
|
7593
|
-
model: "claude-opus-4-6",
|
|
7594
|
-
variant: "max"
|
|
7595
|
-
},
|
|
7596
|
-
{ providers: ["zai-coding-plan", "opencode"], model: "glm-5" },
|
|
7597
|
-
{ providers: ["kimi-for-coding"], model: "k2p5" },
|
|
7598
|
-
{ providers: ["opencode"], model: "kimi-k2.5" }
|
|
7599
|
-
]
|
|
7600
|
-
},
|
|
7601
|
-
writing: {
|
|
7602
|
-
fallbackChain: [
|
|
7603
|
-
{ providers: ["kimi-for-coding"], model: "k2p5" },
|
|
7604
|
-
{
|
|
7605
|
-
providers: ["google", "github-copilot", "opencode"],
|
|
7606
|
-
model: "gemini-3-flash"
|
|
7607
|
-
},
|
|
7608
|
-
{
|
|
7609
|
-
providers: ["anthropic", "github-copilot", "opencode"],
|
|
7610
|
-
model: "claude-sonnet-4-5"
|
|
7611
|
-
}
|
|
7612
|
-
]
|
|
7613
|
-
}
|
|
7438
|
+
}
|
|
7439
|
+
var OPENAI_ONLY_AGENT_OVERRIDES, OPENAI_ONLY_CATEGORY_OVERRIDES;
|
|
7440
|
+
var init_openai_only_model_catalog = __esm(() => {
|
|
7441
|
+
OPENAI_ONLY_AGENT_OVERRIDES = {
|
|
7442
|
+
explore: { model: "openai/gpt-5.4", variant: "medium" },
|
|
7443
|
+
librarian: { model: "openai/gpt-5.4", variant: "medium" }
|
|
7444
|
+
};
|
|
7445
|
+
OPENAI_ONLY_CATEGORY_OVERRIDES = {
|
|
7446
|
+
artistry: { model: "openai/gpt-5.4", variant: "xhigh" },
|
|
7447
|
+
quick: { model: "openai/gpt-5.3-codex", variant: "low" },
|
|
7448
|
+
"visual-engineering": { model: "openai/gpt-5.4", variant: "high" },
|
|
7449
|
+
writing: { model: "openai/gpt-5.4", variant: "medium" }
|
|
7614
7450
|
};
|
|
7615
7451
|
});
|
|
7616
7452
|
|
|
@@ -7626,6 +7462,7 @@ function toProviderAvailability(config) {
|
|
|
7626
7462
|
copilot: config.hasCopilot,
|
|
7627
7463
|
zai: config.hasZaiCodingPlan,
|
|
7628
7464
|
kimiForCoding: config.hasKimiForCoding,
|
|
7465
|
+
opencodeGo: config.hasOpencodeGo,
|
|
7629
7466
|
isMaxPlan: config.isMax20
|
|
7630
7467
|
};
|
|
7631
7468
|
}
|
|
@@ -7637,7 +7474,8 @@ function isProviderAvailable(provider, availability) {
|
|
|
7637
7474
|
"github-copilot": availability.copilot,
|
|
7638
7475
|
opencode: availability.opencodeZen,
|
|
7639
7476
|
"zai-coding-plan": availability.zai,
|
|
7640
|
-
"kimi-for-coding": availability.kimiForCoding
|
|
7477
|
+
"kimi-for-coding": availability.kimiForCoding,
|
|
7478
|
+
"opencode-go": availability.opencodeGo
|
|
7641
7479
|
};
|
|
7642
7480
|
return mapping[provider] ?? false;
|
|
7643
7481
|
}
|
|
@@ -7683,7 +7521,7 @@ var init_fallback_chain_resolution = __esm(() => {
|
|
|
7683
7521
|
// src/cli/model-fallback.ts
|
|
7684
7522
|
function generateModelConfig(config) {
|
|
7685
7523
|
const avail = toProviderAvailability(config);
|
|
7686
|
-
const hasAnyProvider = avail.native.claude || avail.native.openai || avail.native.gemini || avail.opencodeZen || avail.copilot || avail.zai || avail.kimiForCoding;
|
|
7524
|
+
const hasAnyProvider = avail.native.claude || avail.native.openai || avail.native.gemini || avail.opencodeZen || avail.copilot || avail.zai || avail.kimiForCoding || avail.opencodeGo;
|
|
7687
7525
|
if (!hasAnyProvider) {
|
|
7688
7526
|
return {
|
|
7689
7527
|
$schema: SCHEMA_URL,
|
|
@@ -7694,8 +7532,12 @@ function generateModelConfig(config) {
|
|
|
7694
7532
|
const agents = {};
|
|
7695
7533
|
const categories = {};
|
|
7696
7534
|
for (const [role, req] of Object.entries(CLI_AGENT_MODEL_REQUIREMENTS)) {
|
|
7697
|
-
if (role === "librarian"
|
|
7698
|
-
|
|
7535
|
+
if (role === "librarian") {
|
|
7536
|
+
if (avail.opencodeGo) {
|
|
7537
|
+
agents[role] = { model: "opencode-go/minimax-m2.5" };
|
|
7538
|
+
} else if (avail.zai) {
|
|
7539
|
+
agents[role] = { model: ZAI_MODEL };
|
|
7540
|
+
}
|
|
7699
7541
|
continue;
|
|
7700
7542
|
}
|
|
7701
7543
|
if (role === "explore") {
|
|
@@ -7703,6 +7545,8 @@ function generateModelConfig(config) {
|
|
|
7703
7545
|
agents[role] = { model: "anthropic/claude-haiku-4-5" };
|
|
7704
7546
|
} else if (avail.opencodeZen) {
|
|
7705
7547
|
agents[role] = { model: "opencode/claude-haiku-4-5" };
|
|
7548
|
+
} else if (avail.opencodeGo) {
|
|
7549
|
+
agents[role] = { model: "opencode-go/minimax-m2.5" };
|
|
7706
7550
|
} else if (avail.copilot) {
|
|
7707
7551
|
agents[role] = { model: "github-copilot/gpt-5-mini" };
|
|
7708
7552
|
} else {
|
|
@@ -7752,15 +7596,17 @@ function generateModelConfig(config) {
|
|
|
7752
7596
|
categories[cat] = { model: ULTIMATE_FALLBACK };
|
|
7753
7597
|
}
|
|
7754
7598
|
}
|
|
7755
|
-
|
|
7599
|
+
const generatedConfig = {
|
|
7756
7600
|
$schema: SCHEMA_URL,
|
|
7757
7601
|
agents,
|
|
7758
7602
|
categories
|
|
7759
7603
|
};
|
|
7604
|
+
return isOpenAiOnlyAvailability(avail) ? applyOpenAiOnlyModelCatalog(generatedConfig) : generatedConfig;
|
|
7760
7605
|
}
|
|
7761
|
-
var ZAI_MODEL = "zai-coding-plan/glm-4.7", ULTIMATE_FALLBACK = "opencode/
|
|
7606
|
+
var ZAI_MODEL = "zai-coding-plan/glm-4.7", ULTIMATE_FALLBACK = "opencode/gpt-5-nano", SCHEMA_URL = "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json";
|
|
7762
7607
|
var init_model_fallback = __esm(() => {
|
|
7763
7608
|
init_model_fallback_requirements();
|
|
7609
|
+
init_openai_only_model_catalog();
|
|
7764
7610
|
init_fallback_chain_resolution();
|
|
7765
7611
|
});
|
|
7766
7612
|
|
|
@@ -7954,24 +7800,46 @@ import { existsSync as existsSync8, readFileSync as readFileSync7 } from "fs";
|
|
|
7954
7800
|
function detectProvidersFromOmoConfig() {
|
|
7955
7801
|
const omoConfigPath = getOmoConfigPath();
|
|
7956
7802
|
if (!existsSync8(omoConfigPath)) {
|
|
7957
|
-
return {
|
|
7803
|
+
return {
|
|
7804
|
+
hasOpenAI: true,
|
|
7805
|
+
hasOpencodeZen: true,
|
|
7806
|
+
hasZaiCodingPlan: false,
|
|
7807
|
+
hasKimiForCoding: false,
|
|
7808
|
+
hasOpencodeGo: false
|
|
7809
|
+
};
|
|
7958
7810
|
}
|
|
7959
7811
|
try {
|
|
7960
7812
|
const content = readFileSync7(omoConfigPath, "utf-8");
|
|
7961
7813
|
const omoConfig = parseJsonc(content);
|
|
7962
7814
|
if (!omoConfig || typeof omoConfig !== "object") {
|
|
7963
|
-
return {
|
|
7815
|
+
return {
|
|
7816
|
+
hasOpenAI: true,
|
|
7817
|
+
hasOpencodeZen: true,
|
|
7818
|
+
hasZaiCodingPlan: false,
|
|
7819
|
+
hasKimiForCoding: false,
|
|
7820
|
+
hasOpencodeGo: false
|
|
7821
|
+
};
|
|
7964
7822
|
}
|
|
7965
7823
|
const configStr = JSON.stringify(omoConfig);
|
|
7966
7824
|
const hasOpenAI = configStr.includes('"openai/');
|
|
7967
7825
|
const hasOpencodeZen = configStr.includes('"opencode/');
|
|
7968
7826
|
const hasZaiCodingPlan = configStr.includes('"zai-coding-plan/');
|
|
7969
7827
|
const hasKimiForCoding = configStr.includes('"kimi-for-coding/');
|
|
7970
|
-
|
|
7828
|
+
const hasOpencodeGo = configStr.includes('"opencode-go/');
|
|
7829
|
+
return { hasOpenAI, hasOpencodeZen, hasZaiCodingPlan, hasKimiForCoding, hasOpencodeGo };
|
|
7971
7830
|
} catch {
|
|
7972
|
-
return {
|
|
7831
|
+
return {
|
|
7832
|
+
hasOpenAI: true,
|
|
7833
|
+
hasOpencodeZen: true,
|
|
7834
|
+
hasZaiCodingPlan: false,
|
|
7835
|
+
hasKimiForCoding: false,
|
|
7836
|
+
hasOpencodeGo: false
|
|
7837
|
+
};
|
|
7973
7838
|
}
|
|
7974
7839
|
}
|
|
7840
|
+
function isOurPlugin(plugin) {
|
|
7841
|
+
return plugin === PLUGIN_NAME || plugin.startsWith(`${PLUGIN_NAME}@`) || plugin === LEGACY_PLUGIN_NAME || plugin.startsWith(`${LEGACY_PLUGIN_NAME}@`);
|
|
7842
|
+
}
|
|
7975
7843
|
function detectCurrentConfig() {
|
|
7976
7844
|
const result = {
|
|
7977
7845
|
isInstalled: false,
|
|
@@ -7982,7 +7850,8 @@ function detectCurrentConfig() {
|
|
|
7982
7850
|
hasCopilot: false,
|
|
7983
7851
|
hasOpencodeZen: true,
|
|
7984
7852
|
hasZaiCodingPlan: false,
|
|
7985
|
-
hasKimiForCoding: false
|
|
7853
|
+
hasKimiForCoding: false,
|
|
7854
|
+
hasOpencodeGo: false
|
|
7986
7855
|
};
|
|
7987
7856
|
const { format: format2, path: path3 } = detectConfigFormat();
|
|
7988
7857
|
if (format2 === "none") {
|
|
@@ -7994,17 +7863,18 @@ function detectCurrentConfig() {
|
|
|
7994
7863
|
}
|
|
7995
7864
|
const openCodeConfig = parseResult.config;
|
|
7996
7865
|
const plugins = openCodeConfig.plugin ?? [];
|
|
7997
|
-
result.isInstalled = plugins.some(
|
|
7866
|
+
result.isInstalled = plugins.some(isOurPlugin);
|
|
7998
7867
|
if (!result.isInstalled) {
|
|
7999
7868
|
return result;
|
|
8000
7869
|
}
|
|
8001
7870
|
const providers = openCodeConfig.provider;
|
|
8002
7871
|
result.hasGemini = providers ? "google" in providers : false;
|
|
8003
|
-
const { hasOpenAI, hasOpencodeZen, hasZaiCodingPlan, hasKimiForCoding } = detectProvidersFromOmoConfig();
|
|
7872
|
+
const { hasOpenAI, hasOpencodeZen, hasZaiCodingPlan, hasKimiForCoding, hasOpencodeGo } = detectProvidersFromOmoConfig();
|
|
8004
7873
|
result.hasOpenAI = hasOpenAI;
|
|
8005
7874
|
result.hasOpencodeZen = hasOpencodeZen;
|
|
8006
7875
|
result.hasZaiCodingPlan = hasZaiCodingPlan;
|
|
8007
7876
|
result.hasKimiForCoding = hasKimiForCoding;
|
|
7877
|
+
result.hasOpencodeGo = hasOpencodeGo;
|
|
8008
7878
|
return result;
|
|
8009
7879
|
}
|
|
8010
7880
|
var init_detect_current_config = __esm(() => {
|
|
@@ -8015,35 +7885,75 @@ var init_detect_current_config = __esm(() => {
|
|
|
8015
7885
|
});
|
|
8016
7886
|
|
|
8017
7887
|
// src/cli/config-manager/bun-install.ts
|
|
8018
|
-
|
|
8019
|
-
|
|
8020
|
-
|
|
7888
|
+
import { existsSync as existsSync9 } from "fs";
|
|
7889
|
+
function readProcessOutput(stream) {
|
|
7890
|
+
if (!stream) {
|
|
7891
|
+
return Promise.resolve("");
|
|
7892
|
+
}
|
|
7893
|
+
return Bun.readableStreamToText(stream);
|
|
7894
|
+
}
|
|
7895
|
+
function logCapturedOutputOnFailure(outputMode, output) {
|
|
7896
|
+
if (outputMode !== "pipe") {
|
|
7897
|
+
return;
|
|
7898
|
+
}
|
|
7899
|
+
const stdout = output.stdout.trim();
|
|
7900
|
+
const stderr = output.stderr.trim();
|
|
7901
|
+
if (!stdout && !stderr) {
|
|
7902
|
+
return;
|
|
7903
|
+
}
|
|
7904
|
+
log("[bun-install] Captured output from failed bun install", {
|
|
7905
|
+
stdout,
|
|
7906
|
+
stderr
|
|
7907
|
+
});
|
|
8021
7908
|
}
|
|
8022
|
-
async function runBunInstallWithDetails() {
|
|
7909
|
+
async function runBunInstallWithDetails(options) {
|
|
7910
|
+
const outputMode = options?.outputMode ?? "pipe";
|
|
7911
|
+
const cacheDir = options?.workspaceDir ?? getOpenCodeCacheDir();
|
|
7912
|
+
const packageJsonPath = `${cacheDir}/package.json`;
|
|
7913
|
+
if (!existsSync9(packageJsonPath)) {
|
|
7914
|
+
return {
|
|
7915
|
+
success: false,
|
|
7916
|
+
error: `Workspace not initialized: ${packageJsonPath} not found. OpenCode should create this on first run.`
|
|
7917
|
+
};
|
|
7918
|
+
}
|
|
8023
7919
|
try {
|
|
8024
7920
|
const proc = spawnWithWindowsHide(["bun", "install"], {
|
|
8025
|
-
cwd:
|
|
8026
|
-
stdout:
|
|
8027
|
-
stderr:
|
|
7921
|
+
cwd: cacheDir,
|
|
7922
|
+
stdout: outputMode,
|
|
7923
|
+
stderr: outputMode
|
|
8028
7924
|
});
|
|
7925
|
+
const outputPromise = Promise.all([readProcessOutput(proc.stdout), readProcessOutput(proc.stderr)]).then(([stdout, stderr]) => ({ stdout, stderr }));
|
|
8029
7926
|
let timeoutId;
|
|
8030
7927
|
const timeoutPromise = new Promise((resolve2) => {
|
|
8031
7928
|
timeoutId = setTimeout(() => resolve2("timeout"), BUN_INSTALL_TIMEOUT_MS);
|
|
8032
7929
|
});
|
|
8033
7930
|
const exitPromise = proc.exited.then(() => "completed");
|
|
8034
7931
|
const result = await Promise.race([exitPromise, timeoutPromise]);
|
|
8035
|
-
|
|
7932
|
+
if (timeoutId) {
|
|
7933
|
+
clearTimeout(timeoutId);
|
|
7934
|
+
}
|
|
8036
7935
|
if (result === "timeout") {
|
|
8037
7936
|
try {
|
|
8038
7937
|
proc.kill();
|
|
8039
|
-
} catch {
|
|
7938
|
+
} catch (err) {
|
|
7939
|
+
log("[cli/install] Failed to kill timed out bun install process:", err);
|
|
7940
|
+
}
|
|
7941
|
+
if (outputMode === "pipe") {
|
|
7942
|
+
outputPromise.then((output2) => {
|
|
7943
|
+
logCapturedOutputOnFailure(outputMode, output2);
|
|
7944
|
+
}).catch((err) => {
|
|
7945
|
+
log("[bun-install] Failed to read captured output after timeout:", err);
|
|
7946
|
+
});
|
|
7947
|
+
}
|
|
8040
7948
|
return {
|
|
8041
7949
|
success: false,
|
|
8042
7950
|
timedOut: true,
|
|
8043
|
-
error: `bun install timed out after ${BUN_INSTALL_TIMEOUT_SECONDS} seconds. Try running manually: cd ${
|
|
7951
|
+
error: `bun install timed out after ${BUN_INSTALL_TIMEOUT_SECONDS} seconds. Try running manually: cd "${cacheDir}" && bun i`
|
|
8044
7952
|
};
|
|
8045
7953
|
}
|
|
7954
|
+
const output = await outputPromise;
|
|
8046
7955
|
if (proc.exitCode !== 0) {
|
|
7956
|
+
logCapturedOutputOnFailure(outputMode, output);
|
|
8047
7957
|
return {
|
|
8048
7958
|
success: false,
|
|
8049
7959
|
error: `bun install failed with exit code ${proc.exitCode}`
|
|
@@ -8060,7 +7970,8 @@ async function runBunInstallWithDetails() {
|
|
|
8060
7970
|
}
|
|
8061
7971
|
var BUN_INSTALL_TIMEOUT_SECONDS = 60, BUN_INSTALL_TIMEOUT_MS;
|
|
8062
7972
|
var init_bun_install = __esm(() => {
|
|
8063
|
-
|
|
7973
|
+
init_data_path();
|
|
7974
|
+
init_logger();
|
|
8064
7975
|
init_spawn_with_windows_hide();
|
|
8065
7976
|
BUN_INSTALL_TIMEOUT_MS = BUN_INSTALL_TIMEOUT_SECONDS * 1000;
|
|
8066
7977
|
});
|
|
@@ -8138,27 +8049,22 @@ var require_src = __commonJS((exports, module) => {
|
|
|
8138
8049
|
// src/hooks/auto-update-checker/constants.ts
|
|
8139
8050
|
import * as path4 from "path";
|
|
8140
8051
|
import * as os3 from "os";
|
|
8141
|
-
function getCacheDir2() {
|
|
8142
|
-
if (process.platform === "win32") {
|
|
8143
|
-
return path4.join(process.env.LOCALAPPDATA ?? os3.homedir(), "opencode");
|
|
8144
|
-
}
|
|
8145
|
-
return path4.join(os3.homedir(), ".cache", "opencode");
|
|
8146
|
-
}
|
|
8147
8052
|
function getWindowsAppdataDir() {
|
|
8148
8053
|
if (process.platform !== "win32")
|
|
8149
8054
|
return null;
|
|
8150
8055
|
return process.env.APPDATA ?? path4.join(os3.homedir(), "AppData", "Roaming");
|
|
8151
8056
|
}
|
|
8152
|
-
var
|
|
8057
|
+
var PACKAGE_NAME = "oh-my-opencode", NPM_REGISTRY_URL, NPM_FETCH_TIMEOUT = 5000, CACHE_DIR, VERSION_FILE, USER_CONFIG_DIR, USER_OPENCODE_CONFIG, USER_OPENCODE_CONFIG_JSONC, INSTALLED_PACKAGE_JSON;
|
|
8153
8058
|
var init_constants3 = __esm(() => {
|
|
8154
|
-
|
|
8155
|
-
|
|
8156
|
-
|
|
8059
|
+
init_data_path();
|
|
8060
|
+
init_opencode_config_dir();
|
|
8061
|
+
NPM_REGISTRY_URL = `https://registry.npmjs.org/-/package/${PACKAGE_NAME}/dist-tags`;
|
|
8062
|
+
CACHE_DIR = getOpenCodeCacheDir();
|
|
8157
8063
|
VERSION_FILE = path4.join(CACHE_DIR, "version");
|
|
8158
8064
|
USER_CONFIG_DIR = getOpenCodeConfigDir({ binary: "opencode" });
|
|
8159
8065
|
USER_OPENCODE_CONFIG = path4.join(USER_CONFIG_DIR, "opencode.json");
|
|
8160
8066
|
USER_OPENCODE_CONFIG_JSONC = path4.join(USER_CONFIG_DIR, "opencode.jsonc");
|
|
8161
|
-
INSTALLED_PACKAGE_JSON = path4.join(
|
|
8067
|
+
INSTALLED_PACKAGE_JSON = path4.join(CACHE_DIR, "node_modules", PACKAGE_NAME, "package.json");
|
|
8162
8068
|
});
|
|
8163
8069
|
|
|
8164
8070
|
// src/hooks/auto-update-checker/checker/config-paths.ts
|
|
@@ -8212,7 +8118,7 @@ function getLocalDevPath(directory) {
|
|
|
8212
8118
|
const config2 = JSON.parse(stripJsonComments(content));
|
|
8213
8119
|
const plugins = config2.plugin ?? [];
|
|
8214
8120
|
for (const entry of plugins) {
|
|
8215
|
-
if (entry.startsWith("file://") && entry.includes(
|
|
8121
|
+
if (entry.startsWith("file://") && entry.includes(PACKAGE_NAME)) {
|
|
8216
8122
|
try {
|
|
8217
8123
|
return fileURLToPath(entry);
|
|
8218
8124
|
} catch {
|
|
@@ -8244,7 +8150,7 @@ function findPackageJsonUp(startPath) {
|
|
|
8244
8150
|
try {
|
|
8245
8151
|
const content = fs5.readFileSync(pkgPath, "utf-8");
|
|
8246
8152
|
const pkg = JSON.parse(content);
|
|
8247
|
-
if (pkg.name ===
|
|
8153
|
+
if (pkg.name === PACKAGE_NAME)
|
|
8248
8154
|
return pkgPath;
|
|
8249
8155
|
} catch {}
|
|
8250
8156
|
}
|
|
@@ -8284,9 +8190,6 @@ var init_local_dev_version = __esm(() => {
|
|
|
8284
8190
|
|
|
8285
8191
|
// src/hooks/auto-update-checker/checker/plugin-entry.ts
|
|
8286
8192
|
import * as fs7 from "fs";
|
|
8287
|
-
function isExplicitVersionPin(pinnedVersion) {
|
|
8288
|
-
return /^\d+\.\d+\.\d+/.test(pinnedVersion);
|
|
8289
|
-
}
|
|
8290
8193
|
function findPluginEntry(directory) {
|
|
8291
8194
|
for (const configPath of getConfigPaths(directory)) {
|
|
8292
8195
|
try {
|
|
@@ -8296,12 +8199,12 @@ function findPluginEntry(directory) {
|
|
|
8296
8199
|
const config2 = JSON.parse(stripJsonComments(content));
|
|
8297
8200
|
const plugins = config2.plugin ?? [];
|
|
8298
8201
|
for (const entry of plugins) {
|
|
8299
|
-
if (entry ===
|
|
8202
|
+
if (entry === PACKAGE_NAME) {
|
|
8300
8203
|
return { entry, isPinned: false, pinnedVersion: null, configPath };
|
|
8301
8204
|
}
|
|
8302
|
-
if (entry.startsWith(`${
|
|
8303
|
-
const pinnedVersion = entry.slice(
|
|
8304
|
-
const isPinned =
|
|
8205
|
+
if (entry.startsWith(`${PACKAGE_NAME}@`)) {
|
|
8206
|
+
const pinnedVersion = entry.slice(PACKAGE_NAME.length + 1);
|
|
8207
|
+
const isPinned = EXACT_SEMVER_REGEX.test(pinnedVersion.trim());
|
|
8305
8208
|
return { entry, isPinned, pinnedVersion, configPath };
|
|
8306
8209
|
}
|
|
8307
8210
|
}
|
|
@@ -8311,9 +8214,11 @@ function findPluginEntry(directory) {
|
|
|
8311
8214
|
}
|
|
8312
8215
|
return null;
|
|
8313
8216
|
}
|
|
8217
|
+
var EXACT_SEMVER_REGEX;
|
|
8314
8218
|
var init_plugin_entry = __esm(() => {
|
|
8315
8219
|
init_constants3();
|
|
8316
8220
|
init_config_paths();
|
|
8221
|
+
EXACT_SEMVER_REGEX = /^\d+\.\d+\.\d+(-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?(\+[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?$/;
|
|
8317
8222
|
});
|
|
8318
8223
|
|
|
8319
8224
|
// src/hooks/auto-update-checker/checker/cached-version.ts
|
|
@@ -8362,52 +8267,6 @@ var init_cached_version = __esm(() => {
|
|
|
8362
8267
|
});
|
|
8363
8268
|
|
|
8364
8269
|
// src/hooks/auto-update-checker/checker/pinned-version-updater.ts
|
|
8365
|
-
import * as fs9 from "fs";
|
|
8366
|
-
function replacePluginEntry(configPath, oldEntry, newEntry) {
|
|
8367
|
-
try {
|
|
8368
|
-
const content = fs9.readFileSync(configPath, "utf-8");
|
|
8369
|
-
const pluginMatch = content.match(/"plugin"\s*:\s*\[/);
|
|
8370
|
-
if (!pluginMatch || pluginMatch.index === undefined) {
|
|
8371
|
-
log(`[auto-update-checker] No "plugin" array found in ${configPath}`);
|
|
8372
|
-
return false;
|
|
8373
|
-
}
|
|
8374
|
-
const startIndex = pluginMatch.index + pluginMatch[0].length;
|
|
8375
|
-
let bracketCount = 1;
|
|
8376
|
-
let endIndex = startIndex;
|
|
8377
|
-
for (let i2 = startIndex;i2 < content.length && bracketCount > 0; i2++) {
|
|
8378
|
-
if (content[i2] === "[")
|
|
8379
|
-
bracketCount++;
|
|
8380
|
-
else if (content[i2] === "]")
|
|
8381
|
-
bracketCount--;
|
|
8382
|
-
endIndex = i2;
|
|
8383
|
-
}
|
|
8384
|
-
const before = content.slice(0, startIndex);
|
|
8385
|
-
const pluginArrayContent = content.slice(startIndex, endIndex);
|
|
8386
|
-
const after = content.slice(endIndex);
|
|
8387
|
-
const escapedOldEntry = oldEntry.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
8388
|
-
const regex = new RegExp(`["']${escapedOldEntry}["']`);
|
|
8389
|
-
if (!regex.test(pluginArrayContent)) {
|
|
8390
|
-
log(`[auto-update-checker] Entry "${oldEntry}" not found in plugin array of ${configPath}`);
|
|
8391
|
-
return false;
|
|
8392
|
-
}
|
|
8393
|
-
const updatedPluginArray = pluginArrayContent.replace(regex, `"${newEntry}"`);
|
|
8394
|
-
const updatedContent = before + updatedPluginArray + after;
|
|
8395
|
-
if (updatedContent === content) {
|
|
8396
|
-
log(`[auto-update-checker] No changes made to ${configPath}`);
|
|
8397
|
-
return false;
|
|
8398
|
-
}
|
|
8399
|
-
fs9.writeFileSync(configPath, updatedContent, "utf-8");
|
|
8400
|
-
log(`[auto-update-checker] Updated ${configPath}: ${oldEntry} \u2192 ${newEntry}`);
|
|
8401
|
-
return true;
|
|
8402
|
-
} catch (err) {
|
|
8403
|
-
log(`[auto-update-checker] Failed to update config file ${configPath}:`, err);
|
|
8404
|
-
return false;
|
|
8405
|
-
}
|
|
8406
|
-
}
|
|
8407
|
-
function revertPinnedVersion(configPath, failedVersion, originalEntry) {
|
|
8408
|
-
const failedEntry = `${PACKAGE_NAME3}@${failedVersion}`;
|
|
8409
|
-
return replacePluginEntry(configPath, failedEntry, originalEntry);
|
|
8410
|
-
}
|
|
8411
8270
|
var init_pinned_version_updater = __esm(() => {
|
|
8412
8271
|
init_logger();
|
|
8413
8272
|
init_constants3();
|
|
@@ -8531,6 +8390,79 @@ var init_check_for_update = __esm(() => {
|
|
|
8531
8390
|
init_latest_version();
|
|
8532
8391
|
});
|
|
8533
8392
|
|
|
8393
|
+
// src/hooks/auto-update-checker/checker/sync-package-json.ts
|
|
8394
|
+
import * as crypto from "crypto";
|
|
8395
|
+
import * as fs9 from "fs";
|
|
8396
|
+
import * as path8 from "path";
|
|
8397
|
+
function safeUnlink(filePath) {
|
|
8398
|
+
try {
|
|
8399
|
+
fs9.unlinkSync(filePath);
|
|
8400
|
+
} catch (err) {
|
|
8401
|
+
log(`[auto-update-checker] Failed to cleanup temp file: ${filePath}`, err);
|
|
8402
|
+
}
|
|
8403
|
+
}
|
|
8404
|
+
function getIntentVersion(pluginInfo) {
|
|
8405
|
+
if (!pluginInfo.pinnedVersion) {
|
|
8406
|
+
return "latest";
|
|
8407
|
+
}
|
|
8408
|
+
return pluginInfo.pinnedVersion;
|
|
8409
|
+
}
|
|
8410
|
+
function syncCachePackageJsonToIntent(pluginInfo) {
|
|
8411
|
+
const cachePackageJsonPath = path8.join(CACHE_DIR, "package.json");
|
|
8412
|
+
if (!fs9.existsSync(cachePackageJsonPath)) {
|
|
8413
|
+
log("[auto-update-checker] Cache package.json not found, nothing to sync");
|
|
8414
|
+
return { synced: false, error: "file_not_found", message: "Cache package.json not found" };
|
|
8415
|
+
}
|
|
8416
|
+
let content;
|
|
8417
|
+
let pkgJson;
|
|
8418
|
+
try {
|
|
8419
|
+
content = fs9.readFileSync(cachePackageJsonPath, "utf-8");
|
|
8420
|
+
} catch (err) {
|
|
8421
|
+
log("[auto-update-checker] Failed to read cache package.json:", err);
|
|
8422
|
+
return { synced: false, error: "parse_error", message: "Failed to read cache package.json" };
|
|
8423
|
+
}
|
|
8424
|
+
try {
|
|
8425
|
+
pkgJson = JSON.parse(content);
|
|
8426
|
+
} catch (err) {
|
|
8427
|
+
log("[auto-update-checker] Failed to parse cache package.json:", err);
|
|
8428
|
+
return { synced: false, error: "parse_error", message: "Failed to parse cache package.json (malformed JSON)" };
|
|
8429
|
+
}
|
|
8430
|
+
if (!pkgJson || !pkgJson.dependencies?.[PACKAGE_NAME]) {
|
|
8431
|
+
log("[auto-update-checker] Plugin not in cache package.json dependencies, nothing to sync");
|
|
8432
|
+
return { synced: false, error: "plugin_not_in_deps", message: "Plugin not in cache package.json dependencies" };
|
|
8433
|
+
}
|
|
8434
|
+
const currentVersion = pkgJson.dependencies[PACKAGE_NAME];
|
|
8435
|
+
const intentVersion = getIntentVersion(pluginInfo);
|
|
8436
|
+
if (currentVersion === intentVersion) {
|
|
8437
|
+
log("[auto-update-checker] Cache package.json already matches intent:", intentVersion);
|
|
8438
|
+
return { synced: false, error: null, message: `Already matches intent: ${intentVersion}` };
|
|
8439
|
+
}
|
|
8440
|
+
const intentIsTag = !EXACT_SEMVER_REGEX2.test(intentVersion.trim());
|
|
8441
|
+
const currentIsSemver = EXACT_SEMVER_REGEX2.test(String(currentVersion).trim());
|
|
8442
|
+
if (intentIsTag && currentIsSemver) {
|
|
8443
|
+
log(`[auto-update-checker] Syncing cache package.json: "${currentVersion}" \u2192 "${intentVersion}" (opencode.json intent)`);
|
|
8444
|
+
} else {
|
|
8445
|
+
log(`[auto-update-checker] Updating cache package.json: "${currentVersion}" \u2192 "${intentVersion}"`);
|
|
8446
|
+
}
|
|
8447
|
+
pkgJson.dependencies[PACKAGE_NAME] = intentVersion;
|
|
8448
|
+
const tmpPath = `${cachePackageJsonPath}.${crypto.randomUUID()}`;
|
|
8449
|
+
try {
|
|
8450
|
+
fs9.writeFileSync(tmpPath, JSON.stringify(pkgJson, null, 2));
|
|
8451
|
+
fs9.renameSync(tmpPath, cachePackageJsonPath);
|
|
8452
|
+
return { synced: true, error: null, message: `Updated: "${currentVersion}" \u2192 "${intentVersion}"` };
|
|
8453
|
+
} catch (err) {
|
|
8454
|
+
log("[auto-update-checker] Failed to write cache package.json:", err);
|
|
8455
|
+
safeUnlink(tmpPath);
|
|
8456
|
+
return { synced: false, error: "write_error", message: "Failed to write cache package.json" };
|
|
8457
|
+
}
|
|
8458
|
+
}
|
|
8459
|
+
var EXACT_SEMVER_REGEX2;
|
|
8460
|
+
var init_sync_package_json = __esm(() => {
|
|
8461
|
+
init_constants3();
|
|
8462
|
+
init_logger();
|
|
8463
|
+
EXACT_SEMVER_REGEX2 = /^\d+\.\d+\.\d+(-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?(\+[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?$/;
|
|
8464
|
+
});
|
|
8465
|
+
|
|
8534
8466
|
// src/hooks/auto-update-checker/checker.ts
|
|
8535
8467
|
var init_checker = __esm(() => {
|
|
8536
8468
|
init_local_dev_path();
|
|
@@ -8540,48 +8472,57 @@ var init_checker = __esm(() => {
|
|
|
8540
8472
|
init_pinned_version_updater();
|
|
8541
8473
|
init_latest_version();
|
|
8542
8474
|
init_check_for_update();
|
|
8475
|
+
init_sync_package_json();
|
|
8543
8476
|
});
|
|
8544
8477
|
|
|
8545
8478
|
// src/hooks/auto-update-checker/cache.ts
|
|
8546
8479
|
import * as fs10 from "fs";
|
|
8547
|
-
import * as
|
|
8480
|
+
import * as path9 from "path";
|
|
8548
8481
|
function stripTrailingCommas(json3) {
|
|
8549
8482
|
return json3.replace(/,(\s*[}\]])/g, "$1");
|
|
8550
8483
|
}
|
|
8551
|
-
function
|
|
8552
|
-
const lockPath = path8.join(USER_CONFIG_DIR, "bun.lock");
|
|
8553
|
-
if (!fs10.existsSync(lockPath))
|
|
8554
|
-
return false;
|
|
8484
|
+
function removeFromTextBunLock(lockPath, packageName) {
|
|
8555
8485
|
try {
|
|
8556
8486
|
const content = fs10.readFileSync(lockPath, "utf-8");
|
|
8557
8487
|
const lock = JSON.parse(stripTrailingCommas(content));
|
|
8558
|
-
let modified = false;
|
|
8559
|
-
if (lock.workspaces?.[""]?.dependencies?.[packageName]) {
|
|
8560
|
-
delete lock.workspaces[""].dependencies[packageName];
|
|
8561
|
-
modified = true;
|
|
8562
|
-
}
|
|
8563
8488
|
if (lock.packages?.[packageName]) {
|
|
8564
8489
|
delete lock.packages[packageName];
|
|
8565
|
-
modified = true;
|
|
8566
|
-
}
|
|
8567
|
-
if (modified) {
|
|
8568
8490
|
fs10.writeFileSync(lockPath, JSON.stringify(lock, null, 2));
|
|
8569
8491
|
log(`[auto-update-checker] Removed from bun.lock: ${packageName}`);
|
|
8492
|
+
return true;
|
|
8570
8493
|
}
|
|
8571
|
-
return
|
|
8494
|
+
return false;
|
|
8495
|
+
} catch {
|
|
8496
|
+
return false;
|
|
8497
|
+
}
|
|
8498
|
+
}
|
|
8499
|
+
function deleteBinaryBunLock(lockPath) {
|
|
8500
|
+
try {
|
|
8501
|
+
fs10.unlinkSync(lockPath);
|
|
8502
|
+
log(`[auto-update-checker] Removed bun.lockb to force re-resolution`);
|
|
8503
|
+
return true;
|
|
8572
8504
|
} catch {
|
|
8573
8505
|
return false;
|
|
8574
8506
|
}
|
|
8575
8507
|
}
|
|
8576
|
-
function
|
|
8508
|
+
function removeFromBunLock(packageName) {
|
|
8509
|
+
const textLockPath = path9.join(CACHE_DIR, "bun.lock");
|
|
8510
|
+
const binaryLockPath = path9.join(CACHE_DIR, "bun.lockb");
|
|
8511
|
+
if (fs10.existsSync(textLockPath)) {
|
|
8512
|
+
return removeFromTextBunLock(textLockPath, packageName);
|
|
8513
|
+
}
|
|
8514
|
+
if (fs10.existsSync(binaryLockPath)) {
|
|
8515
|
+
return deleteBinaryBunLock(binaryLockPath);
|
|
8516
|
+
}
|
|
8517
|
+
return false;
|
|
8518
|
+
}
|
|
8519
|
+
function invalidatePackage(packageName = PACKAGE_NAME) {
|
|
8577
8520
|
try {
|
|
8578
8521
|
const pkgDirs = [
|
|
8579
|
-
|
|
8580
|
-
|
|
8522
|
+
path9.join(USER_CONFIG_DIR, "node_modules", packageName),
|
|
8523
|
+
path9.join(CACHE_DIR, "node_modules", packageName)
|
|
8581
8524
|
];
|
|
8582
|
-
const pkgJsonPath = path8.join(USER_CONFIG_DIR, "package.json");
|
|
8583
8525
|
let packageRemoved = false;
|
|
8584
|
-
let dependencyRemoved = false;
|
|
8585
8526
|
let lockRemoved = false;
|
|
8586
8527
|
for (const pkgDir of pkgDirs) {
|
|
8587
8528
|
if (fs10.existsSync(pkgDir)) {
|
|
@@ -8590,18 +8531,8 @@ function invalidatePackage(packageName = PACKAGE_NAME3) {
|
|
|
8590
8531
|
packageRemoved = true;
|
|
8591
8532
|
}
|
|
8592
8533
|
}
|
|
8593
|
-
if (fs10.existsSync(pkgJsonPath)) {
|
|
8594
|
-
const content = fs10.readFileSync(pkgJsonPath, "utf-8");
|
|
8595
|
-
const pkgJson = JSON.parse(content);
|
|
8596
|
-
if (pkgJson.dependencies?.[packageName]) {
|
|
8597
|
-
delete pkgJson.dependencies[packageName];
|
|
8598
|
-
fs10.writeFileSync(pkgJsonPath, JSON.stringify(pkgJson, null, 2));
|
|
8599
|
-
log(`[auto-update-checker] Dependency removed from package.json: ${packageName}`);
|
|
8600
|
-
dependencyRemoved = true;
|
|
8601
|
-
}
|
|
8602
|
-
}
|
|
8603
8534
|
lockRemoved = removeFromBunLock(packageName);
|
|
8604
|
-
if (!packageRemoved && !
|
|
8535
|
+
if (!packageRemoved && !lockRemoved) {
|
|
8605
8536
|
log(`[auto-update-checker] Package not found, nothing to invalidate: ${packageName}`);
|
|
8606
8537
|
return false;
|
|
8607
8538
|
}
|
|
@@ -8649,12 +8580,34 @@ var init_update_toasts = __esm(() => {
|
|
|
8649
8580
|
});
|
|
8650
8581
|
|
|
8651
8582
|
// src/hooks/auto-update-checker/hook/background-update-check.ts
|
|
8583
|
+
import { existsSync as existsSync20 } from "fs";
|
|
8584
|
+
import { join as join17 } from "path";
|
|
8652
8585
|
function getPinnedVersionToastMessage(latestVersion) {
|
|
8653
8586
|
return `Update available: ${latestVersion} (version pinned, update manually)`;
|
|
8654
8587
|
}
|
|
8655
|
-
|
|
8588
|
+
function resolveActiveInstallWorkspace() {
|
|
8589
|
+
const configPaths = getOpenCodeConfigPaths({ binary: "opencode" });
|
|
8590
|
+
const cacheDir = getOpenCodeCacheDir();
|
|
8591
|
+
const configInstallPath = join17(configPaths.configDir, "node_modules", PACKAGE_NAME, "package.json");
|
|
8592
|
+
const cacheInstallPath = join17(cacheDir, "node_modules", PACKAGE_NAME, "package.json");
|
|
8593
|
+
if (existsSync20(configInstallPath)) {
|
|
8594
|
+
log(`[auto-update-checker] Active workspace: config-dir (${configPaths.configDir})`);
|
|
8595
|
+
return configPaths.configDir;
|
|
8596
|
+
}
|
|
8597
|
+
if (existsSync20(cacheInstallPath)) {
|
|
8598
|
+
log(`[auto-update-checker] Active workspace: cache-dir (${cacheDir})`);
|
|
8599
|
+
return cacheDir;
|
|
8600
|
+
}
|
|
8601
|
+
log(`[auto-update-checker] Active workspace: config-dir (default, no install detected)`);
|
|
8602
|
+
return configPaths.configDir;
|
|
8603
|
+
}
|
|
8604
|
+
async function runBunInstallSafe(workspaceDir) {
|
|
8656
8605
|
try {
|
|
8657
|
-
|
|
8606
|
+
const result = await runBunInstallWithDetails({ outputMode: "pipe", workspaceDir });
|
|
8607
|
+
if (!result.success && result.error) {
|
|
8608
|
+
log("[auto-update-checker] bun install error:", result.error);
|
|
8609
|
+
}
|
|
8610
|
+
return result.success;
|
|
8658
8611
|
} catch (err) {
|
|
8659
8612
|
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
8660
8613
|
log("[auto-update-checker] bun install error:", errorMessage);
|
|
@@ -8694,23 +8647,27 @@ async function runBackgroundUpdateCheck(ctx, autoUpdate, getToastMessage) {
|
|
|
8694
8647
|
log(`[auto-update-checker] User-pinned version detected (${pluginInfo.entry}), skipping auto-update. Notification only.`);
|
|
8695
8648
|
return;
|
|
8696
8649
|
}
|
|
8697
|
-
|
|
8698
|
-
|
|
8650
|
+
const syncResult = syncCachePackageJsonToIntent(pluginInfo);
|
|
8651
|
+
if (syncResult.error) {
|
|
8652
|
+
log(`[auto-update-checker] Sync failed with error: ${syncResult.error}`, syncResult.message);
|
|
8653
|
+
await showUpdateAvailableToast(ctx, latestVersion, getToastMessage);
|
|
8654
|
+
return;
|
|
8655
|
+
}
|
|
8656
|
+
invalidatePackage(PACKAGE_NAME);
|
|
8657
|
+
const activeWorkspace = resolveActiveInstallWorkspace();
|
|
8658
|
+
const installSuccess = await runBunInstallSafe(activeWorkspace);
|
|
8699
8659
|
if (installSuccess) {
|
|
8700
8660
|
await showAutoUpdatedToast(ctx, currentVersion, latestVersion);
|
|
8701
8661
|
log(`[auto-update-checker] Update installed: ${currentVersion} \u2192 ${latestVersion}`);
|
|
8702
8662
|
return;
|
|
8703
8663
|
}
|
|
8704
|
-
if (pluginInfo.isPinned) {
|
|
8705
|
-
revertPinnedVersion(pluginInfo.configPath, latestVersion, pluginInfo.entry);
|
|
8706
|
-
log("[auto-update-checker] Config reverted due to install failure");
|
|
8707
|
-
}
|
|
8708
8664
|
await showUpdateAvailableToast(ctx, latestVersion, getToastMessage);
|
|
8709
8665
|
log("[auto-update-checker] bun install failed; update not installed (falling back to notification-only)");
|
|
8710
8666
|
}
|
|
8711
8667
|
var init_background_update_check = __esm(() => {
|
|
8712
8668
|
init_config_manager();
|
|
8713
8669
|
init_logger();
|
|
8670
|
+
init_shared();
|
|
8714
8671
|
init_cache();
|
|
8715
8672
|
init_constants3();
|
|
8716
8673
|
init_checker();
|
|
@@ -8940,7 +8897,7 @@ var {
|
|
|
8940
8897
|
// package.json
|
|
8941
8898
|
var package_default = {
|
|
8942
8899
|
name: "oh-my-opencode",
|
|
8943
|
-
version: "3.
|
|
8900
|
+
version: "3.12.1",
|
|
8944
8901
|
description: "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
|
|
8945
8902
|
main: "dist/index.js",
|
|
8946
8903
|
types: "dist/index.d.ts",
|
|
@@ -8992,13 +8949,13 @@ var package_default = {
|
|
|
8992
8949
|
},
|
|
8993
8950
|
homepage: "https://github.com/code-yeongyu/oh-my-openagent#readme",
|
|
8994
8951
|
dependencies: {
|
|
8995
|
-
"@ast-grep/cli": "^0.
|
|
8996
|
-
"@ast-grep/napi": "^0.
|
|
8952
|
+
"@ast-grep/cli": "^0.41.1",
|
|
8953
|
+
"@ast-grep/napi": "^0.41.1",
|
|
8997
8954
|
"@clack/prompts": "^0.11.0",
|
|
8998
8955
|
"@code-yeongyu/comment-checker": "^0.7.0",
|
|
8999
8956
|
"@modelcontextprotocol/sdk": "^1.25.2",
|
|
9000
|
-
"@opencode-ai/plugin": "^1.2.
|
|
9001
|
-
"@opencode-ai/sdk": "^1.2.
|
|
8957
|
+
"@opencode-ai/plugin": "^1.2.24",
|
|
8958
|
+
"@opencode-ai/sdk": "^1.2.24",
|
|
9002
8959
|
commander: "^14.0.2",
|
|
9003
8960
|
"detect-libc": "^2.0.0",
|
|
9004
8961
|
diff: "^8.0.3",
|
|
@@ -9012,24 +8969,24 @@ var package_default = {
|
|
|
9012
8969
|
devDependencies: {
|
|
9013
8970
|
"@types/js-yaml": "^4.0.9",
|
|
9014
8971
|
"@types/picomatch": "^3.0.2",
|
|
9015
|
-
"bun-types": "1.3.
|
|
8972
|
+
"bun-types": "1.3.10",
|
|
9016
8973
|
typescript: "^5.7.3"
|
|
9017
8974
|
},
|
|
9018
8975
|
optionalDependencies: {
|
|
9019
|
-
"oh-my-opencode-darwin-arm64": "3.
|
|
9020
|
-
"oh-my-opencode-darwin-x64": "3.
|
|
9021
|
-
"oh-my-opencode-darwin-x64-baseline": "3.
|
|
9022
|
-
"oh-my-opencode-linux-arm64": "3.
|
|
9023
|
-
"oh-my-opencode-linux-arm64-musl": "3.
|
|
9024
|
-
"oh-my-opencode-linux-x64": "3.
|
|
9025
|
-
"oh-my-opencode-linux-x64-baseline": "3.
|
|
9026
|
-
"oh-my-opencode-linux-x64-musl": "3.
|
|
9027
|
-
"oh-my-opencode-linux-x64-musl-baseline": "3.
|
|
9028
|
-
"oh-my-opencode-windows-x64": "3.
|
|
9029
|
-
"oh-my-opencode-windows-x64-baseline": "3.
|
|
8976
|
+
"oh-my-opencode-darwin-arm64": "3.12.1",
|
|
8977
|
+
"oh-my-opencode-darwin-x64": "3.12.1",
|
|
8978
|
+
"oh-my-opencode-darwin-x64-baseline": "3.12.1",
|
|
8979
|
+
"oh-my-opencode-linux-arm64": "3.12.1",
|
|
8980
|
+
"oh-my-opencode-linux-arm64-musl": "3.12.1",
|
|
8981
|
+
"oh-my-opencode-linux-x64": "3.12.1",
|
|
8982
|
+
"oh-my-opencode-linux-x64-baseline": "3.12.1",
|
|
8983
|
+
"oh-my-opencode-linux-x64-musl": "3.12.1",
|
|
8984
|
+
"oh-my-opencode-linux-x64-musl-baseline": "3.12.1",
|
|
8985
|
+
"oh-my-opencode-windows-x64": "3.12.1",
|
|
8986
|
+
"oh-my-opencode-windows-x64-baseline": "3.12.1"
|
|
9030
8987
|
},
|
|
9031
8988
|
overrides: {
|
|
9032
|
-
"@opencode-ai/sdk": "^1.2.
|
|
8989
|
+
"@opencode-ai/sdk": "^1.2.24"
|
|
9033
8990
|
},
|
|
9034
8991
|
trustedDependencies: [
|
|
9035
8992
|
"@ast-grep/cli",
|
|
@@ -9053,6 +9010,7 @@ var SYMBOLS = {
|
|
|
9053
9010
|
warn: import_picocolors.default.yellow("[!]"),
|
|
9054
9011
|
star: import_picocolors.default.yellow("*")
|
|
9055
9012
|
};
|
|
9013
|
+
var ANSI_COLOR_PATTERN = new RegExp("\x1B\\[[0-9;]*m", "g");
|
|
9056
9014
|
function formatProvider(name, enabled, detail) {
|
|
9057
9015
|
const status = enabled ? SYMBOLS.check : import_picocolors.default.dim("\u25CB");
|
|
9058
9016
|
const label = enabled ? import_picocolors.default.white(name) : import_picocolors.default.dim(name);
|
|
@@ -9106,7 +9064,7 @@ function printWarning(message) {
|
|
|
9106
9064
|
function printBox(content, title) {
|
|
9107
9065
|
const lines = content.split(`
|
|
9108
9066
|
`);
|
|
9109
|
-
const maxWidth = Math.max(...lines.map((line) => line.replace(
|
|
9067
|
+
const maxWidth = Math.max(...lines.map((line) => line.replace(ANSI_COLOR_PATTERN, "").length), title?.length ?? 0) + 4;
|
|
9110
9068
|
const border = import_picocolors.default.dim("\u2500".repeat(maxWidth));
|
|
9111
9069
|
console.log();
|
|
9112
9070
|
if (title) {
|
|
@@ -9115,7 +9073,7 @@ function printBox(content, title) {
|
|
|
9115
9073
|
console.log(import_picocolors.default.dim("\u250C") + border + import_picocolors.default.dim("\u2510"));
|
|
9116
9074
|
}
|
|
9117
9075
|
for (const line of lines) {
|
|
9118
|
-
const stripped = line.replace(
|
|
9076
|
+
const stripped = line.replace(ANSI_COLOR_PATTERN, "");
|
|
9119
9077
|
const padding = maxWidth - stripped.length;
|
|
9120
9078
|
console.log(import_picocolors.default.dim("\u2502") + ` ${line}${" ".repeat(padding - 1)}` + import_picocolors.default.dim("\u2502"));
|
|
9121
9079
|
}
|
|
@@ -9142,6 +9100,9 @@ function validateNonTuiArgs(args) {
|
|
|
9142
9100
|
if (args.openai !== undefined && !["no", "yes"].includes(args.openai)) {
|
|
9143
9101
|
errors.push(`Invalid --openai value: ${args.openai} (expected: no, yes)`);
|
|
9144
9102
|
}
|
|
9103
|
+
if (args.opencodeGo !== undefined && !["no", "yes"].includes(args.opencodeGo)) {
|
|
9104
|
+
errors.push(`Invalid --opencode-go value: ${args.opencodeGo} (expected: no, yes)`);
|
|
9105
|
+
}
|
|
9145
9106
|
if (args.opencodeZen !== undefined && !["no", "yes"].includes(args.opencodeZen)) {
|
|
9146
9107
|
errors.push(`Invalid --opencode-zen value: ${args.opencodeZen} (expected: no, yes)`);
|
|
9147
9108
|
}
|
|
@@ -9162,7 +9123,8 @@ function argsToConfig(args) {
|
|
|
9162
9123
|
hasCopilot: args.copilot === "yes",
|
|
9163
9124
|
hasOpencodeZen: args.opencodeZen === "yes",
|
|
9164
9125
|
hasZaiCodingPlan: args.zaiCodingPlan === "yes",
|
|
9165
|
-
hasKimiForCoding: args.kimiForCoding === "yes"
|
|
9126
|
+
hasKimiForCoding: args.kimiForCoding === "yes",
|
|
9127
|
+
hasOpencodeGo: args.opencodeGo === "yes"
|
|
9166
9128
|
};
|
|
9167
9129
|
}
|
|
9168
9130
|
function detectedToInitialValues(detected) {
|
|
@@ -9177,7 +9139,8 @@ function detectedToInitialValues(detected) {
|
|
|
9177
9139
|
copilot: detected.hasCopilot ? "yes" : "no",
|
|
9178
9140
|
opencodeZen: detected.hasOpencodeZen ? "yes" : "no",
|
|
9179
9141
|
zaiCodingPlan: detected.hasZaiCodingPlan ? "yes" : "no",
|
|
9180
|
-
kimiForCoding: detected.hasKimiForCoding ? "yes" : "no"
|
|
9142
|
+
kimiForCoding: detected.hasKimiForCoding ? "yes" : "no",
|
|
9143
|
+
opencodeGo: detected.hasOpencodeGo ? "yes" : "no"
|
|
9181
9144
|
};
|
|
9182
9145
|
}
|
|
9183
9146
|
|
|
@@ -9252,7 +9215,7 @@ async function runCliInstaller(args, version) {
|
|
|
9252
9215
|
` + `All features work like magic\u2014parallel agents, background tasks,
|
|
9253
9216
|
` + `deep exploration, and relentless execution until completion.`, "The Magic Word");
|
|
9254
9217
|
console.log(`${SYMBOLS.star} ${import_picocolors2.default.yellow("If you found this helpful, consider starring the repo!")}`);
|
|
9255
|
-
console.log(` ${import_picocolors2.default.dim("gh api --silent --method PUT /user/starred/code-yeongyu/oh-my-
|
|
9218
|
+
console.log(` ${import_picocolors2.default.dim("gh api --silent --method PUT /user/starred/code-yeongyu/oh-my-openagent >/dev/null 2>&1 || true")}`);
|
|
9256
9219
|
console.log();
|
|
9257
9220
|
console.log(import_picocolors2.default.dim("oMoMoMoMo... Enjoy!"));
|
|
9258
9221
|
console.log();
|
|
@@ -9937,6 +9900,16 @@ async function promptInstallConfig(detected) {
|
|
|
9937
9900
|
});
|
|
9938
9901
|
if (!kimiForCoding)
|
|
9939
9902
|
return null;
|
|
9903
|
+
const opencodeGo = await selectOrCancel({
|
|
9904
|
+
message: "Do you have an OpenCode Go subscription?",
|
|
9905
|
+
options: [
|
|
9906
|
+
{ value: "no", label: "No", hint: "Will use other configured providers" },
|
|
9907
|
+
{ value: "yes", label: "Yes", hint: "OpenCode Go for quick tasks" }
|
|
9908
|
+
],
|
|
9909
|
+
initialValue: initial.opencodeGo
|
|
9910
|
+
});
|
|
9911
|
+
if (!opencodeGo)
|
|
9912
|
+
return null;
|
|
9940
9913
|
return {
|
|
9941
9914
|
hasClaude: claude !== "no",
|
|
9942
9915
|
isMax20: claude === "max20",
|
|
@@ -9945,7 +9918,8 @@ async function promptInstallConfig(detected) {
|
|
|
9945
9918
|
hasCopilot: copilot === "yes",
|
|
9946
9919
|
hasOpencodeZen: opencodeZen === "yes",
|
|
9947
9920
|
hasZaiCodingPlan: zaiCodingPlan === "yes",
|
|
9948
|
-
hasKimiForCoding: kimiForCoding === "yes"
|
|
9921
|
+
hasKimiForCoding: kimiForCoding === "yes",
|
|
9922
|
+
hasOpencodeGo: opencodeGo === "yes"
|
|
9949
9923
|
};
|
|
9950
9924
|
}
|
|
9951
9925
|
|
|
@@ -10015,7 +9989,7 @@ async function runTuiInstaller(args, version) {
|
|
|
10015
9989
|
` + `All features work like magic\u2014parallel agents, background tasks,
|
|
10016
9990
|
` + `deep exploration, and relentless execution until completion.`, "The Magic Word");
|
|
10017
9991
|
M2.message(`${import_picocolors4.default.yellow("\u2605")} If you found this helpful, consider starring the repo!`);
|
|
10018
|
-
M2.message(` ${import_picocolors4.default.dim("gh api --silent --method PUT /user/starred/code-yeongyu/oh-my-
|
|
9992
|
+
M2.message(` ${import_picocolors4.default.dim("gh api --silent --method PUT /user/starred/code-yeongyu/oh-my-openagent >/dev/null 2>&1 || true")}`);
|
|
10019
9993
|
Se(import_picocolors4.default.green("oMoMoMoMo... Enjoy!"));
|
|
10020
9994
|
if ((config.hasClaude || config.hasGemini || config.hasCopilot) && !args.skipAuth) {
|
|
10021
9995
|
const providers = [];
|
|
@@ -10044,7 +10018,7 @@ async function install(args) {
|
|
|
10044
10018
|
}
|
|
10045
10019
|
|
|
10046
10020
|
// src/cli/run/runner.ts
|
|
10047
|
-
var
|
|
10021
|
+
var import_picocolors14 = __toESM(require_picocolors(), 1);
|
|
10048
10022
|
|
|
10049
10023
|
// src/cli/run/event-state.ts
|
|
10050
10024
|
function createEventState() {
|
|
@@ -24286,7 +24260,8 @@ var BuiltinAgentNameSchema = exports_external.enum([
|
|
|
24286
24260
|
"multimodal-looker",
|
|
24287
24261
|
"metis",
|
|
24288
24262
|
"momus",
|
|
24289
|
-
"atlas"
|
|
24263
|
+
"atlas",
|
|
24264
|
+
"sisyphus-junior"
|
|
24290
24265
|
]);
|
|
24291
24266
|
var BuiltinSkillNameSchema = exports_external.enum([
|
|
24292
24267
|
"playwright",
|
|
@@ -24386,13 +24361,23 @@ var BabysittingConfigSchema = exports_external.object({
|
|
|
24386
24361
|
timeout_ms: exports_external.number().default(120000)
|
|
24387
24362
|
});
|
|
24388
24363
|
// src/config/schema/background-task.ts
|
|
24364
|
+
var CircuitBreakerConfigSchema = exports_external.object({
|
|
24365
|
+
enabled: exports_external.boolean().optional(),
|
|
24366
|
+
maxToolCalls: exports_external.number().int().min(10).optional(),
|
|
24367
|
+
windowSize: exports_external.number().int().min(5).optional(),
|
|
24368
|
+
repetitionThresholdPercent: exports_external.number().gt(0).max(100).optional()
|
|
24369
|
+
});
|
|
24389
24370
|
var BackgroundTaskConfigSchema = exports_external.object({
|
|
24390
24371
|
defaultConcurrency: exports_external.number().min(1).optional(),
|
|
24391
24372
|
providerConcurrency: exports_external.record(exports_external.string(), exports_external.number().min(0)).optional(),
|
|
24392
24373
|
modelConcurrency: exports_external.record(exports_external.string(), exports_external.number().min(0)).optional(),
|
|
24374
|
+
maxDepth: exports_external.number().int().min(1).optional(),
|
|
24375
|
+
maxDescendants: exports_external.number().int().min(1).optional(),
|
|
24393
24376
|
staleTimeoutMs: exports_external.number().min(60000).optional(),
|
|
24394
24377
|
messageStalenessTimeoutMs: exports_external.number().min(60000).optional(),
|
|
24395
|
-
syncPollTimeoutMs: exports_external.number().min(60000).optional()
|
|
24378
|
+
syncPollTimeoutMs: exports_external.number().min(60000).optional(),
|
|
24379
|
+
maxToolCalls: exports_external.number().int().min(10).optional(),
|
|
24380
|
+
circuitBreaker: CircuitBreakerConfigSchema.optional()
|
|
24396
24381
|
});
|
|
24397
24382
|
// src/config/schema/browser-automation.ts
|
|
24398
24383
|
var BrowserAutomationProviderSchema = exports_external.enum([
|
|
@@ -24505,13 +24490,25 @@ var ExperimentalConfigSchema = exports_external.object({
|
|
|
24505
24490
|
hashline_edit: exports_external.boolean().optional(),
|
|
24506
24491
|
model_fallback_title: exports_external.boolean().optional()
|
|
24507
24492
|
});
|
|
24493
|
+
// src/config/schema/git-env-prefix.ts
|
|
24494
|
+
var GIT_ENV_ASSIGNMENT_PATTERN = /^(?:[A-Za-z_][A-Za-z0-9_]*=[A-Za-z0-9_-]*)(?: [A-Za-z_][A-Za-z0-9_]*=[A-Za-z0-9_-]*)*$/;
|
|
24495
|
+
var GIT_ENV_PREFIX_VALIDATION_MESSAGE = 'git_env_prefix must be empty or use shell-safe env assignments like "GIT_MASTER=1"';
|
|
24496
|
+
function isValidGitEnvPrefix(value) {
|
|
24497
|
+
if (value === "") {
|
|
24498
|
+
return true;
|
|
24499
|
+
}
|
|
24500
|
+
return GIT_ENV_ASSIGNMENT_PATTERN.test(value);
|
|
24501
|
+
}
|
|
24502
|
+
var GitEnvPrefixSchema = exports_external.string().refine(isValidGitEnvPrefix, { message: GIT_ENV_PREFIX_VALIDATION_MESSAGE }).default("GIT_MASTER=1");
|
|
24508
24503
|
// src/config/schema/git-master.ts
|
|
24509
24504
|
var GitMasterConfigSchema = exports_external.object({
|
|
24510
24505
|
commit_footer: exports_external.union([exports_external.boolean(), exports_external.string()]).default(true),
|
|
24511
|
-
include_co_authored_by: exports_external.boolean().default(true)
|
|
24506
|
+
include_co_authored_by: exports_external.boolean().default(true),
|
|
24507
|
+
git_env_prefix: GitEnvPrefixSchema
|
|
24512
24508
|
});
|
|
24513
24509
|
// src/config/schema/hooks.ts
|
|
24514
24510
|
var HookNameSchema = exports_external.enum([
|
|
24511
|
+
"gpt-permission-continuation",
|
|
24515
24512
|
"todo-continuation-enforcer",
|
|
24516
24513
|
"context-window-monitor",
|
|
24517
24514
|
"session-recovery",
|
|
@@ -24558,7 +24555,8 @@ var HookNameSchema = exports_external.enum([
|
|
|
24558
24555
|
"write-existing-file-guard",
|
|
24559
24556
|
"anthropic-effort",
|
|
24560
24557
|
"hashline-read-enhancer",
|
|
24561
|
-
"read-image-resizer"
|
|
24558
|
+
"read-image-resizer",
|
|
24559
|
+
"todo-description-override"
|
|
24562
24560
|
]);
|
|
24563
24561
|
// src/config/schema/notification.ts
|
|
24564
24562
|
var NotificationConfigSchema = exports_external.object({
|
|
@@ -24700,6 +24698,14 @@ var OhMyOpenCodeConfigSchema = exports_external.object({
|
|
|
24700
24698
|
});
|
|
24701
24699
|
// src/plugin-config.ts
|
|
24702
24700
|
init_shared();
|
|
24701
|
+
var PARTIAL_STRING_ARRAY_KEYS = new Set([
|
|
24702
|
+
"disabled_mcps",
|
|
24703
|
+
"disabled_agents",
|
|
24704
|
+
"disabled_skills",
|
|
24705
|
+
"disabled_hooks",
|
|
24706
|
+
"disabled_commands",
|
|
24707
|
+
"disabled_tools"
|
|
24708
|
+
]);
|
|
24703
24709
|
function parseConfigPartially(rawConfig) {
|
|
24704
24710
|
const fullResult = OhMyOpenCodeConfigSchema.safeParse(rawConfig);
|
|
24705
24711
|
if (fullResult.success) {
|
|
@@ -24708,6 +24714,13 @@ function parseConfigPartially(rawConfig) {
|
|
|
24708
24714
|
const partialConfig = {};
|
|
24709
24715
|
const invalidSections = [];
|
|
24710
24716
|
for (const key of Object.keys(rawConfig)) {
|
|
24717
|
+
if (PARTIAL_STRING_ARRAY_KEYS.has(key)) {
|
|
24718
|
+
const sectionValue = rawConfig[key];
|
|
24719
|
+
if (Array.isArray(sectionValue) && sectionValue.every((value) => typeof value === "string")) {
|
|
24720
|
+
partialConfig[key] = sectionValue;
|
|
24721
|
+
}
|
|
24722
|
+
continue;
|
|
24723
|
+
}
|
|
24711
24724
|
const sectionResult = OhMyOpenCodeConfigSchema.safeParse({ [key]: rawConfig[key] });
|
|
24712
24725
|
if (sectionResult.success) {
|
|
24713
24726
|
const parsed = sectionResult.data;
|
|
@@ -24793,6 +24806,12 @@ function mergeConfigs(base, override) {
|
|
|
24793
24806
|
...override.disabled_skills ?? []
|
|
24794
24807
|
])
|
|
24795
24808
|
],
|
|
24809
|
+
disabled_tools: [
|
|
24810
|
+
...new Set([
|
|
24811
|
+
...base.disabled_tools ?? [],
|
|
24812
|
+
...override.disabled_tools ?? []
|
|
24813
|
+
])
|
|
24814
|
+
],
|
|
24796
24815
|
claude_code: deepMerge(base.claude_code, override.claude_code)
|
|
24797
24816
|
};
|
|
24798
24817
|
}
|
|
@@ -26506,14 +26525,28 @@ function createJsonOutputManager(options = {}) {
|
|
|
26506
26525
|
|
|
26507
26526
|
// src/cli/run/on-complete-hook.ts
|
|
26508
26527
|
init_spawn_with_windows_hide();
|
|
26509
|
-
|
|
26528
|
+
init_shared();
|
|
26529
|
+
async function readOutput(stream, streamName) {
|
|
26530
|
+
if (!stream) {
|
|
26531
|
+
return "";
|
|
26532
|
+
}
|
|
26533
|
+
try {
|
|
26534
|
+
return await new Response(stream).text();
|
|
26535
|
+
} catch (error48) {
|
|
26536
|
+
log("Failed to read on-complete hook output", {
|
|
26537
|
+
stream: streamName,
|
|
26538
|
+
error: error48 instanceof Error ? error48.message : String(error48)
|
|
26539
|
+
});
|
|
26540
|
+
return "";
|
|
26541
|
+
}
|
|
26542
|
+
}
|
|
26510
26543
|
async function executeOnCompleteHook(options) {
|
|
26511
26544
|
const { command, sessionId, exitCode, durationMs, messageCount } = options;
|
|
26512
26545
|
const trimmedCommand = command.trim();
|
|
26513
26546
|
if (!trimmedCommand) {
|
|
26514
26547
|
return;
|
|
26515
26548
|
}
|
|
26516
|
-
|
|
26549
|
+
log("Running on-complete hook", { command: trimmedCommand });
|
|
26517
26550
|
try {
|
|
26518
26551
|
const proc = spawnWithWindowsHide(["sh", "-c", trimmedCommand], {
|
|
26519
26552
|
env: {
|
|
@@ -26523,21 +26556,37 @@ async function executeOnCompleteHook(options) {
|
|
|
26523
26556
|
DURATION_MS: String(durationMs),
|
|
26524
26557
|
MESSAGE_COUNT: String(messageCount)
|
|
26525
26558
|
},
|
|
26526
|
-
stdout: "
|
|
26527
|
-
stderr: "
|
|
26559
|
+
stdout: "pipe",
|
|
26560
|
+
stderr: "pipe"
|
|
26528
26561
|
});
|
|
26529
|
-
const hookExitCode = await
|
|
26562
|
+
const [hookExitCode, stdout, stderr] = await Promise.all([
|
|
26563
|
+
proc.exited,
|
|
26564
|
+
readOutput(proc.stdout, "stdout"),
|
|
26565
|
+
readOutput(proc.stderr, "stderr")
|
|
26566
|
+
]);
|
|
26567
|
+
if (stdout.trim()) {
|
|
26568
|
+
log("On-complete hook stdout", { command: trimmedCommand, stdout: stdout.trim() });
|
|
26569
|
+
}
|
|
26570
|
+
if (stderr.trim()) {
|
|
26571
|
+
log("On-complete hook stderr", { command: trimmedCommand, stderr: stderr.trim() });
|
|
26572
|
+
}
|
|
26530
26573
|
if (hookExitCode !== 0) {
|
|
26531
|
-
|
|
26574
|
+
log("On-complete hook exited with non-zero code", {
|
|
26575
|
+
command: trimmedCommand,
|
|
26576
|
+
exitCode: hookExitCode
|
|
26577
|
+
});
|
|
26532
26578
|
}
|
|
26533
26579
|
} catch (error48) {
|
|
26534
|
-
|
|
26580
|
+
log("Failed to execute on-complete hook", {
|
|
26581
|
+
command: trimmedCommand,
|
|
26582
|
+
error: error48 instanceof Error ? error48.message : String(error48)
|
|
26583
|
+
});
|
|
26535
26584
|
}
|
|
26536
26585
|
}
|
|
26537
26586
|
|
|
26538
26587
|
// src/cli/run/agent-resolver.ts
|
|
26539
26588
|
init_agent_display_names();
|
|
26540
|
-
var
|
|
26589
|
+
var import_picocolors11 = __toESM(require_picocolors(), 1);
|
|
26541
26590
|
var CORE_AGENT_ORDER = ["sisyphus", "hephaestus", "prometheus", "atlas"];
|
|
26542
26591
|
var DEFAULT_AGENT = "sisyphus";
|
|
26543
26592
|
var normalizeAgentName = (agent) => {
|
|
@@ -26582,21 +26631,45 @@ var resolveRunAgent = (options, pluginConfig, env = process.env) => {
|
|
|
26582
26631
|
const fallbackName = getAgentDisplayName(fallback);
|
|
26583
26632
|
const fallbackDisabled = isAgentDisabled(fallback, pluginConfig);
|
|
26584
26633
|
if (fallbackDisabled) {
|
|
26585
|
-
console.log(
|
|
26634
|
+
console.log(import_picocolors11.default.yellow(`Requested agent "${resolved.resolvedName}" is disabled and no enabled core agent was found. Proceeding with "${fallbackName}".`));
|
|
26586
26635
|
return fallbackName;
|
|
26587
26636
|
}
|
|
26588
|
-
console.log(
|
|
26637
|
+
console.log(import_picocolors11.default.yellow(`Requested agent "${resolved.resolvedName}" is disabled. Falling back to "${fallbackName}".`));
|
|
26589
26638
|
return fallbackName;
|
|
26590
26639
|
}
|
|
26591
26640
|
return resolved.resolvedName;
|
|
26592
26641
|
};
|
|
26593
26642
|
|
|
26643
|
+
// src/cli/run/model-resolver.ts
|
|
26644
|
+
function resolveRunModel(modelString) {
|
|
26645
|
+
if (modelString === undefined) {
|
|
26646
|
+
return;
|
|
26647
|
+
}
|
|
26648
|
+
const trimmed = modelString.trim();
|
|
26649
|
+
if (trimmed.length === 0) {
|
|
26650
|
+
throw new Error("Model string cannot be empty");
|
|
26651
|
+
}
|
|
26652
|
+
const parts = trimmed.split("/");
|
|
26653
|
+
if (parts.length < 2) {
|
|
26654
|
+
throw new Error("Model string must be in 'provider/model' format");
|
|
26655
|
+
}
|
|
26656
|
+
const providerID = parts[0];
|
|
26657
|
+
if (providerID.length === 0) {
|
|
26658
|
+
throw new Error("Provider cannot be empty");
|
|
26659
|
+
}
|
|
26660
|
+
const modelID = parts.slice(1).join("/");
|
|
26661
|
+
if (modelID.length === 0) {
|
|
26662
|
+
throw new Error("Model ID cannot be empty");
|
|
26663
|
+
}
|
|
26664
|
+
return { providerID, modelID };
|
|
26665
|
+
}
|
|
26666
|
+
|
|
26594
26667
|
// src/cli/run/poll-for-completion.ts
|
|
26595
|
-
var
|
|
26668
|
+
var import_picocolors13 = __toESM(require_picocolors(), 1);
|
|
26596
26669
|
|
|
26597
26670
|
// src/cli/run/completion.ts
|
|
26598
26671
|
init_shared();
|
|
26599
|
-
var
|
|
26672
|
+
var import_picocolors12 = __toESM(require_picocolors(), 1);
|
|
26600
26673
|
// src/features/boulder-state/constants.ts
|
|
26601
26674
|
var BOULDER_DIR = ".sisyphus";
|
|
26602
26675
|
var BOULDER_FILE = "boulder.json";
|
|
@@ -26604,14 +26677,14 @@ var BOULDER_STATE_PATH = `${BOULDER_DIR}/${BOULDER_FILE}`;
|
|
|
26604
26677
|
var NOTEPAD_DIR = "notepads";
|
|
26605
26678
|
var NOTEPAD_BASE_PATH = `${BOULDER_DIR}/${NOTEPAD_DIR}`;
|
|
26606
26679
|
// src/features/boulder-state/storage.ts
|
|
26607
|
-
import { existsSync as
|
|
26680
|
+
import { existsSync as existsSync11, readFileSync as readFileSync9, writeFileSync as writeFileSync5, mkdirSync as mkdirSync3, readdirSync } from "fs";
|
|
26608
26681
|
import { dirname as dirname2, join as join9, basename } from "path";
|
|
26609
26682
|
function getBoulderFilePath(directory) {
|
|
26610
26683
|
return join9(directory, BOULDER_DIR, BOULDER_FILE);
|
|
26611
26684
|
}
|
|
26612
26685
|
function readBoulderState(directory) {
|
|
26613
26686
|
const filePath = getBoulderFilePath(directory);
|
|
26614
|
-
if (!
|
|
26687
|
+
if (!existsSync11(filePath)) {
|
|
26615
26688
|
return null;
|
|
26616
26689
|
}
|
|
26617
26690
|
try {
|
|
@@ -26629,7 +26702,7 @@ function readBoulderState(directory) {
|
|
|
26629
26702
|
}
|
|
26630
26703
|
}
|
|
26631
26704
|
function getPlanProgress(planPath) {
|
|
26632
|
-
if (!
|
|
26705
|
+
if (!existsSync11(planPath)) {
|
|
26633
26706
|
return { total: 0, completed: 0, isComplete: true };
|
|
26634
26707
|
}
|
|
26635
26708
|
try {
|
|
@@ -26650,14 +26723,14 @@ function getPlanProgress(planPath) {
|
|
|
26650
26723
|
// src/features/run-continuation-state/constants.ts
|
|
26651
26724
|
var CONTINUATION_MARKER_DIR = ".sisyphus/run-continuation";
|
|
26652
26725
|
// src/features/run-continuation-state/storage.ts
|
|
26653
|
-
import { existsSync as
|
|
26726
|
+
import { existsSync as existsSync12, mkdirSync as mkdirSync4, readFileSync as readFileSync10, rmSync, writeFileSync as writeFileSync6 } from "fs";
|
|
26654
26727
|
import { join as join10 } from "path";
|
|
26655
26728
|
function getMarkerPath(directory, sessionID) {
|
|
26656
26729
|
return join10(directory, CONTINUATION_MARKER_DIR, `${sessionID}.json`);
|
|
26657
26730
|
}
|
|
26658
26731
|
function readContinuationMarker(directory, sessionID) {
|
|
26659
26732
|
const markerPath = getMarkerPath(directory, sessionID);
|
|
26660
|
-
if (!
|
|
26733
|
+
if (!existsSync12(markerPath))
|
|
26661
26734
|
return null;
|
|
26662
26735
|
try {
|
|
26663
26736
|
const raw = readFileSync10(markerPath, "utf-8");
|
|
@@ -26685,7 +26758,7 @@ function getActiveContinuationMarkerReason(marker) {
|
|
|
26685
26758
|
}
|
|
26686
26759
|
// src/hooks/ralph-loop/storage.ts
|
|
26687
26760
|
init_frontmatter();
|
|
26688
|
-
import { existsSync as
|
|
26761
|
+
import { existsSync as existsSync13, readFileSync as readFileSync11, writeFileSync as writeFileSync7, unlinkSync, mkdirSync as mkdirSync5 } from "fs";
|
|
26689
26762
|
import { dirname as dirname3, join as join11 } from "path";
|
|
26690
26763
|
|
|
26691
26764
|
// src/hooks/ralph-loop/constants.ts
|
|
@@ -26699,7 +26772,7 @@ function getStateFilePath(directory, customPath) {
|
|
|
26699
26772
|
}
|
|
26700
26773
|
function readState(directory, customPath) {
|
|
26701
26774
|
const filePath = getStateFilePath(directory, customPath);
|
|
26702
|
-
if (!
|
|
26775
|
+
if (!existsSync13(filePath)) {
|
|
26703
26776
|
return null;
|
|
26704
26777
|
}
|
|
26705
26778
|
try {
|
|
@@ -26793,7 +26866,7 @@ async function checkCompletionConditions(ctx) {
|
|
|
26793
26866
|
}
|
|
26794
26867
|
return true;
|
|
26795
26868
|
} catch (err) {
|
|
26796
|
-
console.error(
|
|
26869
|
+
console.error(import_picocolors12.default.red(`[completion] API error: ${err}`));
|
|
26797
26870
|
return false;
|
|
26798
26871
|
}
|
|
26799
26872
|
}
|
|
@@ -26854,7 +26927,7 @@ function logWaiting(ctx, message) {
|
|
|
26854
26927
|
if (!ctx.verbose) {
|
|
26855
26928
|
return;
|
|
26856
26929
|
}
|
|
26857
|
-
console.log(
|
|
26930
|
+
console.log(import_picocolors12.default.dim(` Waiting: ${message}`));
|
|
26858
26931
|
}
|
|
26859
26932
|
|
|
26860
26933
|
// src/cli/run/poll-for-completion.ts
|
|
@@ -26885,10 +26958,10 @@ async function pollForCompletion(ctx, eventState, abortController, options = {})
|
|
|
26885
26958
|
if (eventState.mainSessionError) {
|
|
26886
26959
|
errorCycleCount++;
|
|
26887
26960
|
if (errorCycleCount >= ERROR_GRACE_CYCLES) {
|
|
26888
|
-
console.error(
|
|
26961
|
+
console.error(import_picocolors13.default.red(`
|
|
26889
26962
|
|
|
26890
26963
|
Session ended with error: ${eventState.lastError}`));
|
|
26891
|
-
console.error(
|
|
26964
|
+
console.error(import_picocolors13.default.yellow("Check if todos were completed before the error."));
|
|
26892
26965
|
return 1;
|
|
26893
26966
|
}
|
|
26894
26967
|
continue;
|
|
@@ -26899,7 +26972,7 @@ Session ended with error: ${eventState.lastError}`));
|
|
|
26899
26972
|
if (eventState.lastEventTimestamp !== null) {
|
|
26900
26973
|
const timeSinceLastEvent = Date.now() - eventState.lastEventTimestamp;
|
|
26901
26974
|
if (timeSinceLastEvent > eventWatchdogMs) {
|
|
26902
|
-
console.log(
|
|
26975
|
+
console.log(import_picocolors13.default.yellow(`
|
|
26903
26976
|
No events for ${Math.round(timeSinceLastEvent / 1000)}s, verifying session status...`));
|
|
26904
26977
|
mainSessionStatus = await getMainSessionStatus(ctx);
|
|
26905
26978
|
if (mainSessionStatus === "idle") {
|
|
@@ -26948,7 +27021,7 @@ Session ended with error: ${eventState.lastError}`));
|
|
|
26948
27021
|
const hasActiveWork = hasActiveChildren || hasActiveTodos;
|
|
26949
27022
|
if (hasActiveWork) {
|
|
26950
27023
|
eventState.hasReceivedMeaningfulWork = true;
|
|
26951
|
-
console.log(
|
|
27024
|
+
console.log(import_picocolors13.default.yellow(`
|
|
26952
27025
|
No meaningful work events for ${Math.round(secondaryMeaningfulWorkTimeoutMs / 1000)}s but session has active work - assuming in progress`));
|
|
26953
27026
|
}
|
|
26954
27027
|
}
|
|
@@ -26968,7 +27041,7 @@ Session ended with error: ${eventState.lastError}`));
|
|
|
26968
27041
|
}
|
|
26969
27042
|
consecutiveCompleteChecks++;
|
|
26970
27043
|
if (consecutiveCompleteChecks >= requiredConsecutive) {
|
|
26971
|
-
console.log(
|
|
27044
|
+
console.log(import_picocolors13.default.green(`
|
|
26972
27045
|
|
|
26973
27046
|
All tasks completed.`));
|
|
26974
27047
|
return 0;
|
|
@@ -27125,6 +27198,7 @@ async function run(options) {
|
|
|
27125
27198
|
const resolvedAgent = resolveRunAgent(options, pluginConfig);
|
|
27126
27199
|
const abortController = new AbortController;
|
|
27127
27200
|
try {
|
|
27201
|
+
const resolvedModel = resolveRunModel(options.model);
|
|
27128
27202
|
const { client: client3, cleanup: serverCleanup } = await createServerConnection({
|
|
27129
27203
|
port: options.port,
|
|
27130
27204
|
attach: options.attach,
|
|
@@ -27135,7 +27209,7 @@ async function run(options) {
|
|
|
27135
27209
|
};
|
|
27136
27210
|
const restoreInput = suppressRunInput();
|
|
27137
27211
|
const handleSigint = () => {
|
|
27138
|
-
console.log(
|
|
27212
|
+
console.log(import_picocolors14.default.yellow(`
|
|
27139
27213
|
Interrupted. Shutting down...`));
|
|
27140
27214
|
restoreInput();
|
|
27141
27215
|
cleanup();
|
|
@@ -27148,7 +27222,10 @@ Interrupted. Shutting down...`));
|
|
|
27148
27222
|
sessionId: options.sessionId,
|
|
27149
27223
|
directory
|
|
27150
27224
|
});
|
|
27151
|
-
console.log(
|
|
27225
|
+
console.log(import_picocolors14.default.dim(`Session: ${sessionID}`));
|
|
27226
|
+
if (resolvedModel) {
|
|
27227
|
+
console.log(import_picocolors14.default.dim(`Model: ${resolvedModel.providerID}/${resolvedModel.modelID}`));
|
|
27228
|
+
}
|
|
27152
27229
|
const ctx = {
|
|
27153
27230
|
client: client3,
|
|
27154
27231
|
sessionID,
|
|
@@ -27164,6 +27241,7 @@ Interrupted. Shutting down...`));
|
|
|
27164
27241
|
path: { id: sessionID },
|
|
27165
27242
|
body: {
|
|
27166
27243
|
agent: resolvedAgent,
|
|
27244
|
+
...resolvedModel ? { model: resolvedModel } : {},
|
|
27167
27245
|
tools: {
|
|
27168
27246
|
question: false
|
|
27169
27247
|
},
|
|
@@ -27209,7 +27287,7 @@ Interrupted. Shutting down...`));
|
|
|
27209
27287
|
if (err instanceof Error && err.name === "AbortError") {
|
|
27210
27288
|
return 130;
|
|
27211
27289
|
}
|
|
27212
|
-
console.error(
|
|
27290
|
+
console.error(import_picocolors14.default.red(`Error: ${serializeError(err)}`));
|
|
27213
27291
|
return 1;
|
|
27214
27292
|
} finally {
|
|
27215
27293
|
timestampOutput?.restore();
|
|
@@ -27219,53 +27297,53 @@ Interrupted. Shutting down...`));
|
|
|
27219
27297
|
init_checker();
|
|
27220
27298
|
|
|
27221
27299
|
// src/cli/get-local-version/formatter.ts
|
|
27222
|
-
var
|
|
27300
|
+
var import_picocolors15 = __toESM(require_picocolors(), 1);
|
|
27223
27301
|
var SYMBOLS2 = {
|
|
27224
|
-
check:
|
|
27225
|
-
cross:
|
|
27226
|
-
arrow:
|
|
27227
|
-
info:
|
|
27228
|
-
warn:
|
|
27229
|
-
pin:
|
|
27230
|
-
dev:
|
|
27302
|
+
check: import_picocolors15.default.green("[OK]"),
|
|
27303
|
+
cross: import_picocolors15.default.red("[X]"),
|
|
27304
|
+
arrow: import_picocolors15.default.cyan("->"),
|
|
27305
|
+
info: import_picocolors15.default.blue("[i]"),
|
|
27306
|
+
warn: import_picocolors15.default.yellow("[!]"),
|
|
27307
|
+
pin: import_picocolors15.default.magenta("[PINNED]"),
|
|
27308
|
+
dev: import_picocolors15.default.cyan("[DEV]")
|
|
27231
27309
|
};
|
|
27232
27310
|
function formatVersionOutput(info) {
|
|
27233
27311
|
const lines = [];
|
|
27234
27312
|
lines.push("");
|
|
27235
|
-
lines.push(
|
|
27236
|
-
lines.push(
|
|
27313
|
+
lines.push(import_picocolors15.default.bold(import_picocolors15.default.white("oh-my-opencode Version Information")));
|
|
27314
|
+
lines.push(import_picocolors15.default.dim("\u2500".repeat(50)));
|
|
27237
27315
|
lines.push("");
|
|
27238
27316
|
if (info.currentVersion) {
|
|
27239
|
-
lines.push(` Current Version: ${
|
|
27317
|
+
lines.push(` Current Version: ${import_picocolors15.default.cyan(info.currentVersion)}`);
|
|
27240
27318
|
} else {
|
|
27241
|
-
lines.push(` Current Version: ${
|
|
27319
|
+
lines.push(` Current Version: ${import_picocolors15.default.dim("unknown")}`);
|
|
27242
27320
|
}
|
|
27243
27321
|
if (!info.isLocalDev && info.latestVersion) {
|
|
27244
|
-
lines.push(` Latest Version: ${
|
|
27322
|
+
lines.push(` Latest Version: ${import_picocolors15.default.cyan(info.latestVersion)}`);
|
|
27245
27323
|
}
|
|
27246
27324
|
lines.push("");
|
|
27247
27325
|
switch (info.status) {
|
|
27248
27326
|
case "up-to-date":
|
|
27249
|
-
lines.push(` ${SYMBOLS2.check} ${
|
|
27327
|
+
lines.push(` ${SYMBOLS2.check} ${import_picocolors15.default.green("You're up to date!")}`);
|
|
27250
27328
|
break;
|
|
27251
27329
|
case "outdated":
|
|
27252
|
-
lines.push(` ${SYMBOLS2.warn} ${
|
|
27253
|
-
lines.push(` ${
|
|
27330
|
+
lines.push(` ${SYMBOLS2.warn} ${import_picocolors15.default.yellow("Update available")}`);
|
|
27331
|
+
lines.push(` ${import_picocolors15.default.dim("Run:")} ${import_picocolors15.default.cyan("cd ~/.config/opencode && bun update oh-my-opencode")}`);
|
|
27254
27332
|
break;
|
|
27255
27333
|
case "local-dev":
|
|
27256
|
-
lines.push(` ${SYMBOLS2.dev} ${
|
|
27257
|
-
lines.push(` ${
|
|
27334
|
+
lines.push(` ${SYMBOLS2.dev} ${import_picocolors15.default.cyan("Running in local development mode")}`);
|
|
27335
|
+
lines.push(` ${import_picocolors15.default.dim("Using file:// protocol from config")}`);
|
|
27258
27336
|
break;
|
|
27259
27337
|
case "pinned":
|
|
27260
|
-
lines.push(` ${SYMBOLS2.pin} ${
|
|
27261
|
-
lines.push(` ${
|
|
27338
|
+
lines.push(` ${SYMBOLS2.pin} ${import_picocolors15.default.magenta(`Version pinned to ${info.pinnedVersion}`)}`);
|
|
27339
|
+
lines.push(` ${import_picocolors15.default.dim("Update check skipped for pinned versions")}`);
|
|
27262
27340
|
break;
|
|
27263
27341
|
case "error":
|
|
27264
|
-
lines.push(` ${SYMBOLS2.cross} ${
|
|
27265
|
-
lines.push(` ${
|
|
27342
|
+
lines.push(` ${SYMBOLS2.cross} ${import_picocolors15.default.red("Unable to check for updates")}`);
|
|
27343
|
+
lines.push(` ${import_picocolors15.default.dim("Network error or npm registry unavailable")}`);
|
|
27266
27344
|
break;
|
|
27267
27345
|
case "unknown":
|
|
27268
|
-
lines.push(` ${SYMBOLS2.info} ${
|
|
27346
|
+
lines.push(` ${SYMBOLS2.info} ${import_picocolors15.default.yellow("Version information unavailable")}`);
|
|
27269
27347
|
break;
|
|
27270
27348
|
}
|
|
27271
27349
|
lines.push("");
|
|
@@ -27365,21 +27443,21 @@ async function getLocalVersion(options = {}) {
|
|
|
27365
27443
|
}
|
|
27366
27444
|
}
|
|
27367
27445
|
// src/cli/doctor/constants.ts
|
|
27368
|
-
var
|
|
27446
|
+
var import_picocolors16 = __toESM(require_picocolors(), 1);
|
|
27369
27447
|
var SYMBOLS3 = {
|
|
27370
|
-
check:
|
|
27371
|
-
cross:
|
|
27372
|
-
warn:
|
|
27373
|
-
info:
|
|
27374
|
-
arrow:
|
|
27375
|
-
bullet:
|
|
27376
|
-
skip:
|
|
27448
|
+
check: import_picocolors16.default.green("\u2713"),
|
|
27449
|
+
cross: import_picocolors16.default.red("\u2717"),
|
|
27450
|
+
warn: import_picocolors16.default.yellow("\u26A0"),
|
|
27451
|
+
info: import_picocolors16.default.blue("\u2139"),
|
|
27452
|
+
arrow: import_picocolors16.default.cyan("\u2192"),
|
|
27453
|
+
bullet: import_picocolors16.default.dim("\u2022"),
|
|
27454
|
+
skip: import_picocolors16.default.dim("\u25CB")
|
|
27377
27455
|
};
|
|
27378
27456
|
var STATUS_COLORS = {
|
|
27379
|
-
pass:
|
|
27380
|
-
fail:
|
|
27381
|
-
warn:
|
|
27382
|
-
skip:
|
|
27457
|
+
pass: import_picocolors16.default.green,
|
|
27458
|
+
fail: import_picocolors16.default.red,
|
|
27459
|
+
warn: import_picocolors16.default.yellow,
|
|
27460
|
+
skip: import_picocolors16.default.dim
|
|
27383
27461
|
};
|
|
27384
27462
|
var CHECK_IDS = {
|
|
27385
27463
|
SYSTEM: "system",
|
|
@@ -27398,34 +27476,34 @@ var EXIT_CODES = {
|
|
|
27398
27476
|
FAILURE: 1
|
|
27399
27477
|
};
|
|
27400
27478
|
var MIN_OPENCODE_VERSION = "1.0.150";
|
|
27401
|
-
var
|
|
27479
|
+
var PACKAGE_NAME2 = "oh-my-opencode";
|
|
27402
27480
|
var OPENCODE_BINARIES2 = ["opencode", "opencode-desktop"];
|
|
27403
27481
|
|
|
27404
27482
|
// src/cli/doctor/checks/system.ts
|
|
27405
|
-
import { existsSync as
|
|
27483
|
+
import { existsSync as existsSync24, readFileSync as readFileSync21 } from "fs";
|
|
27406
27484
|
|
|
27407
27485
|
// src/cli/doctor/checks/system-binary.ts
|
|
27408
27486
|
init_spawn_with_windows_hide();
|
|
27409
|
-
import { existsSync as
|
|
27487
|
+
import { existsSync as existsSync21 } from "fs";
|
|
27410
27488
|
import { homedir as homedir5 } from "os";
|
|
27411
|
-
import { join as
|
|
27489
|
+
import { join as join18 } from "path";
|
|
27412
27490
|
function getDesktopAppPaths(platform) {
|
|
27413
27491
|
const home = homedir5();
|
|
27414
27492
|
switch (platform) {
|
|
27415
27493
|
case "darwin":
|
|
27416
27494
|
return [
|
|
27417
27495
|
"/Applications/OpenCode.app/Contents/MacOS/OpenCode",
|
|
27418
|
-
|
|
27496
|
+
join18(home, "Applications", "OpenCode.app", "Contents", "MacOS", "OpenCode")
|
|
27419
27497
|
];
|
|
27420
27498
|
case "win32": {
|
|
27421
27499
|
const programFiles = process.env.ProgramFiles;
|
|
27422
27500
|
const localAppData = process.env.LOCALAPPDATA;
|
|
27423
27501
|
const paths = [];
|
|
27424
27502
|
if (programFiles) {
|
|
27425
|
-
paths.push(
|
|
27503
|
+
paths.push(join18(programFiles, "OpenCode", "OpenCode.exe"));
|
|
27426
27504
|
}
|
|
27427
27505
|
if (localAppData) {
|
|
27428
|
-
paths.push(
|
|
27506
|
+
paths.push(join18(localAppData, "OpenCode", "OpenCode.exe"));
|
|
27429
27507
|
}
|
|
27430
27508
|
return paths;
|
|
27431
27509
|
}
|
|
@@ -27433,8 +27511,8 @@ function getDesktopAppPaths(platform) {
|
|
|
27433
27511
|
return [
|
|
27434
27512
|
"/usr/bin/opencode",
|
|
27435
27513
|
"/usr/lib/opencode/opencode",
|
|
27436
|
-
|
|
27437
|
-
|
|
27514
|
+
join18(home, "Applications", "opencode-desktop-linux-x86_64.AppImage"),
|
|
27515
|
+
join18(home, "Applications", "opencode-desktop-linux-aarch64.AppImage")
|
|
27438
27516
|
];
|
|
27439
27517
|
default:
|
|
27440
27518
|
return [];
|
|
@@ -27446,7 +27524,7 @@ function buildVersionCommand(binaryPath, platform) {
|
|
|
27446
27524
|
}
|
|
27447
27525
|
return [binaryPath, "--version"];
|
|
27448
27526
|
}
|
|
27449
|
-
function findDesktopBinary(platform = process.platform, checkExists =
|
|
27527
|
+
function findDesktopBinary(platform = process.platform, checkExists = existsSync21) {
|
|
27450
27528
|
for (const desktopPath of getDesktopAppPaths(platform)) {
|
|
27451
27529
|
if (checkExists(desktopPath)) {
|
|
27452
27530
|
return { binary: "opencode", path: desktopPath };
|
|
@@ -27456,9 +27534,9 @@ function findDesktopBinary(platform = process.platform, checkExists = existsSync
|
|
|
27456
27534
|
}
|
|
27457
27535
|
async function findOpenCodeBinary() {
|
|
27458
27536
|
for (const binary2 of OPENCODE_BINARIES2) {
|
|
27459
|
-
const
|
|
27460
|
-
if (
|
|
27461
|
-
return { binary: binary2, path:
|
|
27537
|
+
const path10 = Bun.which(binary2);
|
|
27538
|
+
if (path10) {
|
|
27539
|
+
return { binary: binary2, path: path10 };
|
|
27462
27540
|
}
|
|
27463
27541
|
}
|
|
27464
27542
|
return findDesktopBinary();
|
|
@@ -27493,30 +27571,40 @@ function compareVersions(current, minimum) {
|
|
|
27493
27571
|
}
|
|
27494
27572
|
|
|
27495
27573
|
// src/cli/doctor/checks/system-plugin.ts
|
|
27496
|
-
import { existsSync as existsSync19, readFileSync as readFileSync19 } from "fs";
|
|
27497
27574
|
init_shared();
|
|
27575
|
+
import { existsSync as existsSync22, readFileSync as readFileSync19 } from "fs";
|
|
27498
27576
|
function detectConfigPath() {
|
|
27499
27577
|
const paths = getOpenCodeConfigPaths({ binary: "opencode", version: null });
|
|
27500
|
-
if (
|
|
27578
|
+
if (existsSync22(paths.configJsonc))
|
|
27501
27579
|
return paths.configJsonc;
|
|
27502
|
-
if (
|
|
27580
|
+
if (existsSync22(paths.configJson))
|
|
27503
27581
|
return paths.configJson;
|
|
27504
27582
|
return null;
|
|
27505
27583
|
}
|
|
27506
27584
|
function parsePluginVersion(entry) {
|
|
27507
|
-
if (
|
|
27508
|
-
|
|
27509
|
-
|
|
27510
|
-
|
|
27511
|
-
return
|
|
27512
|
-
|
|
27585
|
+
if (entry.startsWith(`${PLUGIN_NAME}@`)) {
|
|
27586
|
+
const value = entry.slice(PLUGIN_NAME.length + 1);
|
|
27587
|
+
if (!value || value === "latest")
|
|
27588
|
+
return null;
|
|
27589
|
+
return value;
|
|
27590
|
+
}
|
|
27591
|
+
if (entry.startsWith(`${LEGACY_PLUGIN_NAME}@`)) {
|
|
27592
|
+
const value = entry.slice(LEGACY_PLUGIN_NAME.length + 1);
|
|
27593
|
+
if (!value || value === "latest")
|
|
27594
|
+
return null;
|
|
27595
|
+
return value;
|
|
27596
|
+
}
|
|
27597
|
+
return null;
|
|
27513
27598
|
}
|
|
27514
27599
|
function findPluginEntry2(entries) {
|
|
27515
27600
|
for (const entry of entries) {
|
|
27516
|
-
if (entry ===
|
|
27601
|
+
if (entry === PLUGIN_NAME || entry.startsWith(`${PLUGIN_NAME}@`)) {
|
|
27602
|
+
return { entry, isLocalDev: false };
|
|
27603
|
+
}
|
|
27604
|
+
if (entry === LEGACY_PLUGIN_NAME || entry.startsWith(`${LEGACY_PLUGIN_NAME}@`)) {
|
|
27517
27605
|
return { entry, isLocalDev: false };
|
|
27518
27606
|
}
|
|
27519
|
-
if (entry.startsWith("file://") && entry.includes(
|
|
27607
|
+
if (entry.startsWith("file://") && (entry.includes(PLUGIN_NAME) || entry.includes(LEGACY_PLUGIN_NAME))) {
|
|
27520
27608
|
return { entry, isLocalDev: true };
|
|
27521
27609
|
}
|
|
27522
27610
|
}
|
|
@@ -27553,7 +27641,7 @@ function getPluginInfo() {
|
|
|
27553
27641
|
registered: true,
|
|
27554
27642
|
configPath,
|
|
27555
27643
|
entry: pluginEntry.entry,
|
|
27556
|
-
isPinned: pinnedVersion !== null && /^\d+\.\d+\.\d+/.test(pinnedVersion),
|
|
27644
|
+
isPinned: pinnedVersion !== null && /^\d+\.\d+\.\d+/.test(pinnedVersion ?? ""),
|
|
27557
27645
|
pinnedVersion,
|
|
27558
27646
|
isLocalDev: pluginEntry.isLocalDev
|
|
27559
27647
|
};
|
|
@@ -27572,29 +27660,29 @@ function getPluginInfo() {
|
|
|
27572
27660
|
// src/cli/doctor/checks/system-loaded-version.ts
|
|
27573
27661
|
init_checker();
|
|
27574
27662
|
init_auto_update_checker();
|
|
27575
|
-
import { existsSync as
|
|
27663
|
+
import { existsSync as existsSync23, readFileSync as readFileSync20 } from "fs";
|
|
27576
27664
|
import { homedir as homedir6 } from "os";
|
|
27577
|
-
import { join as
|
|
27665
|
+
import { join as join19 } from "path";
|
|
27578
27666
|
init_shared();
|
|
27579
27667
|
function getPlatformDefaultCacheDir(platform = process.platform) {
|
|
27580
27668
|
if (platform === "darwin")
|
|
27581
|
-
return
|
|
27669
|
+
return join19(homedir6(), "Library", "Caches");
|
|
27582
27670
|
if (platform === "win32")
|
|
27583
|
-
return process.env.LOCALAPPDATA ??
|
|
27584
|
-
return
|
|
27671
|
+
return process.env.LOCALAPPDATA ?? join19(homedir6(), "AppData", "Local");
|
|
27672
|
+
return join19(homedir6(), ".cache");
|
|
27585
27673
|
}
|
|
27586
27674
|
function resolveOpenCodeCacheDir() {
|
|
27587
27675
|
const xdgCacheHome = process.env.XDG_CACHE_HOME;
|
|
27588
27676
|
if (xdgCacheHome)
|
|
27589
|
-
return
|
|
27677
|
+
return join19(xdgCacheHome, "opencode");
|
|
27590
27678
|
const fromShared = getOpenCodeCacheDir();
|
|
27591
|
-
const platformDefault =
|
|
27592
|
-
if (
|
|
27679
|
+
const platformDefault = join19(getPlatformDefaultCacheDir(), "opencode");
|
|
27680
|
+
if (existsSync23(fromShared) || !existsSync23(platformDefault))
|
|
27593
27681
|
return fromShared;
|
|
27594
27682
|
return platformDefault;
|
|
27595
27683
|
}
|
|
27596
27684
|
function readPackageJson(filePath) {
|
|
27597
|
-
if (!
|
|
27685
|
+
if (!existsSync23(filePath))
|
|
27598
27686
|
return null;
|
|
27599
27687
|
try {
|
|
27600
27688
|
const content = readFileSync20(filePath, "utf-8");
|
|
@@ -27610,15 +27698,28 @@ function normalizeVersion(value) {
|
|
|
27610
27698
|
return match?.[0] ?? null;
|
|
27611
27699
|
}
|
|
27612
27700
|
function getLoadedPluginVersion() {
|
|
27701
|
+
const configPaths = getOpenCodeConfigPaths({ binary: "opencode" });
|
|
27613
27702
|
const cacheDir = resolveOpenCodeCacheDir();
|
|
27614
|
-
const
|
|
27615
|
-
|
|
27703
|
+
const candidates = [
|
|
27704
|
+
{
|
|
27705
|
+
cacheDir: configPaths.configDir,
|
|
27706
|
+
cachePackagePath: configPaths.packageJson,
|
|
27707
|
+
installedPackagePath: join19(configPaths.configDir, "node_modules", PACKAGE_NAME2, "package.json")
|
|
27708
|
+
},
|
|
27709
|
+
{
|
|
27710
|
+
cacheDir,
|
|
27711
|
+
cachePackagePath: join19(cacheDir, "package.json"),
|
|
27712
|
+
installedPackagePath: join19(cacheDir, "node_modules", PACKAGE_NAME2, "package.json")
|
|
27713
|
+
}
|
|
27714
|
+
];
|
|
27715
|
+
const selectedCandidate = candidates.find((candidate) => existsSync23(candidate.installedPackagePath)) ?? candidates[0];
|
|
27716
|
+
const { cacheDir: selectedDir, cachePackagePath, installedPackagePath } = selectedCandidate;
|
|
27616
27717
|
const cachePackage = readPackageJson(cachePackagePath);
|
|
27617
27718
|
const installedPackage = readPackageJson(installedPackagePath);
|
|
27618
|
-
const expectedVersion = normalizeVersion(cachePackage?.dependencies?.[
|
|
27719
|
+
const expectedVersion = normalizeVersion(cachePackage?.dependencies?.[PACKAGE_NAME2]);
|
|
27619
27720
|
const loadedVersion = normalizeVersion(installedPackage?.version);
|
|
27620
27721
|
return {
|
|
27621
|
-
cacheDir,
|
|
27722
|
+
cacheDir: selectedDir,
|
|
27622
27723
|
cachePackagePath,
|
|
27623
27724
|
installedPackagePath,
|
|
27624
27725
|
expectedVersion,
|
|
@@ -27638,7 +27739,7 @@ init_shared();
|
|
|
27638
27739
|
function isConfigValid(configPath) {
|
|
27639
27740
|
if (!configPath)
|
|
27640
27741
|
return true;
|
|
27641
|
-
if (!
|
|
27742
|
+
if (!existsSync24(configPath))
|
|
27642
27743
|
return false;
|
|
27643
27744
|
try {
|
|
27644
27745
|
parseJsonc(readFileSync21(configPath, "utf-8"));
|
|
@@ -27665,7 +27766,7 @@ async function gatherSystemInfo() {
|
|
|
27665
27766
|
const [binaryInfo, pluginInfo] = await Promise.all([findOpenCodeBinary(), Promise.resolve(getPluginInfo())]);
|
|
27666
27767
|
const loadedInfo = getLoadedPluginVersion();
|
|
27667
27768
|
const opencodeVersion = binaryInfo ? await getOpenCodeVersion2(binaryInfo.path) : null;
|
|
27668
|
-
const pluginVersion = pluginInfo.pinnedVersion ?? loadedInfo.expectedVersion;
|
|
27769
|
+
const pluginVersion = pluginInfo.pinnedVersion ?? loadedInfo.expectedVersion ?? loadedInfo.loadedVersion;
|
|
27669
27770
|
return {
|
|
27670
27771
|
opencodeVersion,
|
|
27671
27772
|
opencodePath: binaryInfo?.path ?? null,
|
|
@@ -27745,23 +27846,23 @@ async function checkSystem() {
|
|
|
27745
27846
|
|
|
27746
27847
|
// src/cli/doctor/checks/config.ts
|
|
27747
27848
|
import { readFileSync as readFileSync24 } from "fs";
|
|
27748
|
-
import { join as
|
|
27849
|
+
import { join as join23 } from "path";
|
|
27749
27850
|
init_shared();
|
|
27750
27851
|
|
|
27751
27852
|
// src/cli/doctor/checks/model-resolution-cache.ts
|
|
27752
27853
|
init_shared();
|
|
27753
|
-
import { existsSync as
|
|
27854
|
+
import { existsSync as existsSync25, readFileSync as readFileSync22 } from "fs";
|
|
27754
27855
|
import { homedir as homedir7 } from "os";
|
|
27755
|
-
import { join as
|
|
27856
|
+
import { join as join20 } from "path";
|
|
27756
27857
|
function getOpenCodeCacheDir2() {
|
|
27757
27858
|
const xdgCache = process.env.XDG_CACHE_HOME;
|
|
27758
27859
|
if (xdgCache)
|
|
27759
|
-
return
|
|
27760
|
-
return
|
|
27860
|
+
return join20(xdgCache, "opencode");
|
|
27861
|
+
return join20(homedir7(), ".cache", "opencode");
|
|
27761
27862
|
}
|
|
27762
27863
|
function loadAvailableModelsFromCache() {
|
|
27763
|
-
const cacheFile =
|
|
27764
|
-
if (!
|
|
27864
|
+
const cacheFile = join20(getOpenCodeCacheDir2(), "models.json");
|
|
27865
|
+
if (!existsSync25(cacheFile)) {
|
|
27765
27866
|
return { providers: [], modelCount: 0, cacheExists: false };
|
|
27766
27867
|
}
|
|
27767
27868
|
try {
|
|
@@ -27787,10 +27888,10 @@ init_model_requirements();
|
|
|
27787
27888
|
// src/cli/doctor/checks/model-resolution-config.ts
|
|
27788
27889
|
init_shared();
|
|
27789
27890
|
import { readFileSync as readFileSync23 } from "fs";
|
|
27790
|
-
import { join as
|
|
27791
|
-
var
|
|
27792
|
-
var USER_CONFIG_BASE =
|
|
27793
|
-
var PROJECT_CONFIG_BASE =
|
|
27891
|
+
import { join as join21 } from "path";
|
|
27892
|
+
var PACKAGE_NAME3 = "oh-my-opencode";
|
|
27893
|
+
var USER_CONFIG_BASE = join21(getOpenCodeConfigPaths({ binary: "opencode", version: null }).configDir, PACKAGE_NAME3);
|
|
27894
|
+
var PROJECT_CONFIG_BASE = join21(process.cwd(), ".opencode", PACKAGE_NAME3);
|
|
27794
27895
|
function loadOmoConfig() {
|
|
27795
27896
|
const projectDetected = detectConfigFile(PROJECT_CONFIG_BASE);
|
|
27796
27897
|
if (projectDetected.format !== "none") {
|
|
@@ -27815,7 +27916,7 @@ function loadOmoConfig() {
|
|
|
27815
27916
|
|
|
27816
27917
|
// src/cli/doctor/checks/model-resolution-details.ts
|
|
27817
27918
|
init_shared();
|
|
27818
|
-
import { join as
|
|
27919
|
+
import { join as join22 } from "path";
|
|
27819
27920
|
|
|
27820
27921
|
// src/cli/doctor/checks/model-resolution-variant.ts
|
|
27821
27922
|
function formatModelWithVariant(model, variant) {
|
|
@@ -27854,7 +27955,7 @@ function getCategoryEffectiveVariant(categoryName, requirement, config2) {
|
|
|
27854
27955
|
// src/cli/doctor/checks/model-resolution-details.ts
|
|
27855
27956
|
function buildModelResolutionDetails(options) {
|
|
27856
27957
|
const details = [];
|
|
27857
|
-
const cacheFile =
|
|
27958
|
+
const cacheFile = join22(getOpenCodeCacheDir(), "models.json");
|
|
27858
27959
|
details.push("\u2550\u2550\u2550 Available Models (from cache) \u2550\u2550\u2550");
|
|
27859
27960
|
details.push("");
|
|
27860
27961
|
if (options.available.cacheExists) {
|
|
@@ -27966,8 +28067,8 @@ async function checkModels() {
|
|
|
27966
28067
|
}
|
|
27967
28068
|
|
|
27968
28069
|
// src/cli/doctor/checks/config.ts
|
|
27969
|
-
var USER_CONFIG_BASE2 =
|
|
27970
|
-
var PROJECT_CONFIG_BASE2 =
|
|
28070
|
+
var USER_CONFIG_BASE2 = join23(getOpenCodeConfigDir({ binary: "opencode" }), PACKAGE_NAME2);
|
|
28071
|
+
var PROJECT_CONFIG_BASE2 = join23(process.cwd(), ".opencode", PACKAGE_NAME2);
|
|
27971
28072
|
function findConfigPath() {
|
|
27972
28073
|
const projectConfig = detectConfigFile(PROJECT_CONFIG_BASE2);
|
|
27973
28074
|
if (projectConfig.format !== "none")
|
|
@@ -28087,14 +28188,14 @@ async function checkConfig() {
|
|
|
28087
28188
|
|
|
28088
28189
|
// src/cli/doctor/checks/dependencies.ts
|
|
28089
28190
|
init_spawn_with_windows_hide();
|
|
28090
|
-
import { existsSync as
|
|
28191
|
+
import { existsSync as existsSync26 } from "fs";
|
|
28091
28192
|
import { createRequire } from "module";
|
|
28092
|
-
import { dirname as dirname6, join as
|
|
28193
|
+
import { dirname as dirname6, join as join24 } from "path";
|
|
28093
28194
|
async function checkBinaryExists(binary2) {
|
|
28094
28195
|
try {
|
|
28095
|
-
const
|
|
28096
|
-
if (
|
|
28097
|
-
return { exists: true, path:
|
|
28196
|
+
const path10 = Bun.which(binary2);
|
|
28197
|
+
if (path10) {
|
|
28198
|
+
return { exists: true, path: path10 };
|
|
28098
28199
|
}
|
|
28099
28200
|
} catch {}
|
|
28100
28201
|
return { exists: false, path: null };
|
|
@@ -28145,15 +28246,15 @@ async function checkAstGrepNapi() {
|
|
|
28145
28246
|
path: null
|
|
28146
28247
|
};
|
|
28147
28248
|
} catch {
|
|
28148
|
-
const { existsSync:
|
|
28149
|
-
const { join:
|
|
28249
|
+
const { existsSync: existsSync27 } = await import("fs");
|
|
28250
|
+
const { join: join25 } = await import("path");
|
|
28150
28251
|
const { homedir: homedir8 } = await import("os");
|
|
28151
28252
|
const pathsToCheck = [
|
|
28152
|
-
|
|
28153
|
-
|
|
28253
|
+
join25(homedir8(), ".config", "opencode", "node_modules", "@ast-grep", "napi"),
|
|
28254
|
+
join25(process.cwd(), "node_modules", "@ast-grep", "napi")
|
|
28154
28255
|
];
|
|
28155
28256
|
for (const napiPath of pathsToCheck) {
|
|
28156
|
-
if (
|
|
28257
|
+
if (existsSync27(napiPath)) {
|
|
28157
28258
|
return {
|
|
28158
28259
|
name: "AST-Grep NAPI",
|
|
28159
28260
|
required: false,
|
|
@@ -28178,8 +28279,8 @@ function findCommentCheckerPackageBinary() {
|
|
|
28178
28279
|
try {
|
|
28179
28280
|
const require2 = createRequire(import.meta.url);
|
|
28180
28281
|
const pkgPath = require2.resolve("@code-yeongyu/comment-checker/package.json");
|
|
28181
|
-
const binaryPath =
|
|
28182
|
-
if (
|
|
28282
|
+
const binaryPath = join24(dirname6(pkgPath), "bin", binaryName);
|
|
28283
|
+
if (existsSync26(binaryPath))
|
|
28183
28284
|
return binaryPath;
|
|
28184
28285
|
} catch {}
|
|
28185
28286
|
return null;
|
|
@@ -28292,20 +28393,163 @@ async function getGhCliInfo() {
|
|
|
28292
28393
|
error: authStatus.error
|
|
28293
28394
|
};
|
|
28294
28395
|
}
|
|
28396
|
+
// src/tools/lsp/server-definitions.ts
|
|
28397
|
+
var BUILTIN_SERVERS = {
|
|
28398
|
+
typescript: { command: ["typescript-language-server", "--stdio"], extensions: [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".mts", ".cts"] },
|
|
28399
|
+
deno: { command: ["deno", "lsp"], extensions: [".ts", ".tsx", ".js", ".jsx", ".mjs"] },
|
|
28400
|
+
vue: { command: ["vue-language-server", "--stdio"], extensions: [".vue"] },
|
|
28401
|
+
eslint: { command: ["vscode-eslint-language-server", "--stdio"], extensions: [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".mts", ".cts", ".vue"] },
|
|
28402
|
+
oxlint: { command: ["oxlint", "--lsp"], extensions: [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".mts", ".cts", ".vue", ".astro", ".svelte"] },
|
|
28403
|
+
biome: { command: ["biome", "lsp-proxy", "--stdio"], extensions: [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".mts", ".cts", ".json", ".jsonc", ".vue", ".astro", ".svelte", ".css", ".graphql", ".gql", ".html"] },
|
|
28404
|
+
gopls: { command: ["gopls"], extensions: [".go"] },
|
|
28405
|
+
"ruby-lsp": { command: ["rubocop", "--lsp"], extensions: [".rb", ".rake", ".gemspec", ".ru"] },
|
|
28406
|
+
basedpyright: { command: ["basedpyright-langserver", "--stdio"], extensions: [".py", ".pyi"] },
|
|
28407
|
+
pyright: { command: ["pyright-langserver", "--stdio"], extensions: [".py", ".pyi"] },
|
|
28408
|
+
ty: { command: ["ty", "server"], extensions: [".py", ".pyi"] },
|
|
28409
|
+
ruff: { command: ["ruff", "server"], extensions: [".py", ".pyi"] },
|
|
28410
|
+
"elixir-ls": { command: ["elixir-ls"], extensions: [".ex", ".exs"] },
|
|
28411
|
+
zls: { command: ["zls"], extensions: [".zig", ".zon"] },
|
|
28412
|
+
csharp: { command: ["csharp-ls"], extensions: [".cs"] },
|
|
28413
|
+
fsharp: { command: ["fsautocomplete"], extensions: [".fs", ".fsi", ".fsx", ".fsscript"] },
|
|
28414
|
+
"sourcekit-lsp": { command: ["sourcekit-lsp"], extensions: [".swift", ".objc", ".objcpp"] },
|
|
28415
|
+
rust: { command: ["rust-analyzer"], extensions: [".rs"] },
|
|
28416
|
+
clangd: { command: ["clangd", "--background-index", "--clang-tidy"], extensions: [".c", ".cpp", ".cc", ".cxx", ".c++", ".h", ".hpp", ".hh", ".hxx", ".h++"] },
|
|
28417
|
+
svelte: { command: ["svelteserver", "--stdio"], extensions: [".svelte"] },
|
|
28418
|
+
astro: { command: ["astro-ls", "--stdio"], extensions: [".astro"] },
|
|
28419
|
+
bash: { command: ["bash-language-server", "start"], extensions: [".sh", ".bash", ".zsh", ".ksh"] },
|
|
28420
|
+
"bash-ls": { command: ["bash-language-server", "start"], extensions: [".sh", ".bash", ".zsh", ".ksh"] },
|
|
28421
|
+
jdtls: { command: ["jdtls"], extensions: [".java"] },
|
|
28422
|
+
"yaml-ls": { command: ["yaml-language-server", "--stdio"], extensions: [".yaml", ".yml"] },
|
|
28423
|
+
"lua-ls": { command: ["lua-language-server"], extensions: [".lua"] },
|
|
28424
|
+
php: { command: ["intelephense", "--stdio"], extensions: [".php"] },
|
|
28425
|
+
dart: { command: ["dart", "language-server", "--lsp"], extensions: [".dart"] },
|
|
28426
|
+
terraform: { command: ["terraform-ls", "serve"], extensions: [".tf", ".tfvars"] },
|
|
28427
|
+
"terraform-ls": { command: ["terraform-ls", "serve"], extensions: [".tf", ".tfvars"] },
|
|
28428
|
+
prisma: { command: ["prisma", "language-server"], extensions: [".prisma"] },
|
|
28429
|
+
"ocaml-lsp": { command: ["ocamllsp"], extensions: [".ml", ".mli"] },
|
|
28430
|
+
texlab: { command: ["texlab"], extensions: [".tex", ".bib"] },
|
|
28431
|
+
dockerfile: { command: ["docker-langserver", "--stdio"], extensions: [".dockerfile"] },
|
|
28432
|
+
gleam: { command: ["gleam", "lsp"], extensions: [".gleam"] },
|
|
28433
|
+
"clojure-lsp": { command: ["clojure-lsp", "listen"], extensions: [".clj", ".cljs", ".cljc", ".edn"] },
|
|
28434
|
+
nixd: { command: ["nixd"], extensions: [".nix"] },
|
|
28435
|
+
tinymist: { command: ["tinymist"], extensions: [".typ", ".typc"] },
|
|
28436
|
+
"haskell-language-server": { command: ["haskell-language-server-wrapper", "--lsp"], extensions: [".hs", ".lhs"] },
|
|
28437
|
+
"kotlin-ls": { command: ["kotlin-lsp"], extensions: [".kt", ".kts"] }
|
|
28438
|
+
};
|
|
28295
28439
|
// src/tools/lsp/server-config-loader.ts
|
|
28440
|
+
import { existsSync as existsSync27, readFileSync as readFileSync25 } from "fs";
|
|
28441
|
+
import { join as join25 } from "path";
|
|
28296
28442
|
init_shared();
|
|
28297
28443
|
init_jsonc_parser();
|
|
28444
|
+
function loadJsonFile(path10) {
|
|
28445
|
+
if (!existsSync27(path10))
|
|
28446
|
+
return null;
|
|
28447
|
+
try {
|
|
28448
|
+
return parseJsonc(readFileSync25(path10, "utf-8"));
|
|
28449
|
+
} catch {
|
|
28450
|
+
return null;
|
|
28451
|
+
}
|
|
28452
|
+
}
|
|
28453
|
+
function getConfigPaths2() {
|
|
28454
|
+
const cwd = process.cwd();
|
|
28455
|
+
const configDir = getOpenCodeConfigDir({ binary: "opencode" });
|
|
28456
|
+
return {
|
|
28457
|
+
project: detectConfigFile(join25(cwd, ".opencode", "oh-my-opencode")).path,
|
|
28458
|
+
user: detectConfigFile(join25(configDir, "oh-my-opencode")).path,
|
|
28459
|
+
opencode: detectConfigFile(join25(configDir, "opencode")).path
|
|
28460
|
+
};
|
|
28461
|
+
}
|
|
28462
|
+
function loadAllConfigs() {
|
|
28463
|
+
const paths = getConfigPaths2();
|
|
28464
|
+
const configs = new Map;
|
|
28465
|
+
const project = loadJsonFile(paths.project);
|
|
28466
|
+
if (project)
|
|
28467
|
+
configs.set("project", project);
|
|
28468
|
+
const user = loadJsonFile(paths.user);
|
|
28469
|
+
if (user)
|
|
28470
|
+
configs.set("user", user);
|
|
28471
|
+
const opencode = loadJsonFile(paths.opencode);
|
|
28472
|
+
if (opencode)
|
|
28473
|
+
configs.set("opencode", opencode);
|
|
28474
|
+
return configs;
|
|
28475
|
+
}
|
|
28476
|
+
function getMergedServers() {
|
|
28477
|
+
const configs = loadAllConfigs();
|
|
28478
|
+
const servers = [];
|
|
28479
|
+
const disabled = new Set;
|
|
28480
|
+
const seen = new Set;
|
|
28481
|
+
const sources = ["project", "user", "opencode"];
|
|
28482
|
+
for (const source of sources) {
|
|
28483
|
+
const config2 = configs.get(source);
|
|
28484
|
+
if (!config2?.lsp)
|
|
28485
|
+
continue;
|
|
28486
|
+
for (const [id, entry] of Object.entries(config2.lsp)) {
|
|
28487
|
+
if (entry.disabled) {
|
|
28488
|
+
disabled.add(id);
|
|
28489
|
+
continue;
|
|
28490
|
+
}
|
|
28491
|
+
if (seen.has(id))
|
|
28492
|
+
continue;
|
|
28493
|
+
if (!entry.command || !entry.extensions)
|
|
28494
|
+
continue;
|
|
28495
|
+
servers.push({
|
|
28496
|
+
id,
|
|
28497
|
+
command: entry.command,
|
|
28498
|
+
extensions: entry.extensions,
|
|
28499
|
+
priority: entry.priority ?? 0,
|
|
28500
|
+
env: entry.env,
|
|
28501
|
+
initialization: entry.initialization,
|
|
28502
|
+
source
|
|
28503
|
+
});
|
|
28504
|
+
seen.add(id);
|
|
28505
|
+
}
|
|
28506
|
+
}
|
|
28507
|
+
for (const [id, config2] of Object.entries(BUILTIN_SERVERS)) {
|
|
28508
|
+
if (disabled.has(id) || seen.has(id))
|
|
28509
|
+
continue;
|
|
28510
|
+
servers.push({
|
|
28511
|
+
id,
|
|
28512
|
+
command: config2.command,
|
|
28513
|
+
extensions: config2.extensions,
|
|
28514
|
+
priority: -100,
|
|
28515
|
+
source: "opencode"
|
|
28516
|
+
});
|
|
28517
|
+
}
|
|
28518
|
+
return servers.sort((a, b3) => {
|
|
28519
|
+
if (a.source !== b3.source) {
|
|
28520
|
+
const order = { project: 0, user: 1, opencode: 2 };
|
|
28521
|
+
return order[a.source] - order[b3.source];
|
|
28522
|
+
}
|
|
28523
|
+
return b3.priority - a.priority;
|
|
28524
|
+
});
|
|
28525
|
+
}
|
|
28298
28526
|
|
|
28299
28527
|
// src/tools/lsp/server-installation.ts
|
|
28528
|
+
import { existsSync as existsSync28 } from "fs";
|
|
28529
|
+
import { delimiter as delimiter2, join as join27 } from "path";
|
|
28530
|
+
|
|
28531
|
+
// src/tools/lsp/server-path-bases.ts
|
|
28300
28532
|
init_shared();
|
|
28301
|
-
import {
|
|
28302
|
-
|
|
28533
|
+
import { join as join26 } from "path";
|
|
28534
|
+
function getLspServerAdditionalPathBases(workingDirectory) {
|
|
28535
|
+
const configDir = getOpenCodeConfigDir({ binary: "opencode" });
|
|
28536
|
+
const dataDir = join26(getDataDir(), "opencode");
|
|
28537
|
+
return [
|
|
28538
|
+
join26(workingDirectory, "node_modules", ".bin"),
|
|
28539
|
+
join26(configDir, "bin"),
|
|
28540
|
+
join26(configDir, "node_modules", ".bin"),
|
|
28541
|
+
join26(dataDir, "bin"),
|
|
28542
|
+
join26(dataDir, "bin", "node_modules", ".bin")
|
|
28543
|
+
];
|
|
28544
|
+
}
|
|
28545
|
+
|
|
28546
|
+
// src/tools/lsp/server-installation.ts
|
|
28303
28547
|
function isServerInstalled(command) {
|
|
28304
28548
|
if (command.length === 0)
|
|
28305
28549
|
return false;
|
|
28306
28550
|
const cmd = command[0];
|
|
28307
28551
|
if (cmd.includes("/") || cmd.includes("\\")) {
|
|
28308
|
-
if (
|
|
28552
|
+
if (existsSync28(cmd))
|
|
28309
28553
|
return true;
|
|
28310
28554
|
}
|
|
28311
28555
|
const isWindows = process.platform === "win32";
|
|
@@ -28323,27 +28567,17 @@ function isServerInstalled(command) {
|
|
|
28323
28567
|
if (isWindows && !pathEnv) {
|
|
28324
28568
|
pathEnv = process.env.Path || "";
|
|
28325
28569
|
}
|
|
28326
|
-
const
|
|
28327
|
-
const paths = pathEnv.split(pathSeparator);
|
|
28570
|
+
const paths = pathEnv.split(delimiter2);
|
|
28328
28571
|
for (const p2 of paths) {
|
|
28329
28572
|
for (const suffix of exts) {
|
|
28330
|
-
if (
|
|
28573
|
+
if (existsSync28(join27(p2, cmd + suffix))) {
|
|
28331
28574
|
return true;
|
|
28332
28575
|
}
|
|
28333
28576
|
}
|
|
28334
28577
|
}
|
|
28335
|
-
const
|
|
28336
|
-
const configDir = getOpenCodeConfigDir({ binary: "opencode" });
|
|
28337
|
-
const dataDir = join23(getDataDir(), "opencode");
|
|
28338
|
-
const additionalBases = [
|
|
28339
|
-
join23(cwd, "node_modules", ".bin"),
|
|
28340
|
-
join23(configDir, "bin"),
|
|
28341
|
-
join23(configDir, "node_modules", ".bin"),
|
|
28342
|
-
join23(dataDir, "bin")
|
|
28343
|
-
];
|
|
28344
|
-
for (const base of additionalBases) {
|
|
28578
|
+
for (const base of getLspServerAdditionalPathBases(process.cwd())) {
|
|
28345
28579
|
for (const suffix of exts) {
|
|
28346
|
-
if (
|
|
28580
|
+
if (existsSync28(join27(base, cmd + suffix))) {
|
|
28347
28581
|
return true;
|
|
28348
28582
|
}
|
|
28349
28583
|
}
|
|
@@ -28353,48 +28587,76 @@ function isServerInstalled(command) {
|
|
|
28353
28587
|
}
|
|
28354
28588
|
return false;
|
|
28355
28589
|
}
|
|
28356
|
-
|
|
28357
|
-
|
|
28358
|
-
|
|
28359
|
-
|
|
28360
|
-
|
|
28361
|
-
|
|
28362
|
-
|
|
28363
|
-
|
|
28364
|
-
|
|
28365
|
-
id
|
|
28366
|
-
|
|
28367
|
-
|
|
28368
|
-
|
|
28369
|
-
}
|
|
28590
|
+
|
|
28591
|
+
// src/tools/lsp/server-resolution.ts
|
|
28592
|
+
function getAllServers() {
|
|
28593
|
+
const configs = loadAllConfigs();
|
|
28594
|
+
const servers = getMergedServers();
|
|
28595
|
+
const disabled = new Set;
|
|
28596
|
+
for (const config2 of configs.values()) {
|
|
28597
|
+
if (!config2.lsp)
|
|
28598
|
+
continue;
|
|
28599
|
+
for (const [id, entry] of Object.entries(config2.lsp)) {
|
|
28600
|
+
if (entry.disabled)
|
|
28601
|
+
disabled.add(id);
|
|
28602
|
+
}
|
|
28603
|
+
}
|
|
28604
|
+
const result = [];
|
|
28605
|
+
const seen = new Set;
|
|
28606
|
+
for (const server2 of servers) {
|
|
28607
|
+
if (seen.has(server2.id))
|
|
28608
|
+
continue;
|
|
28609
|
+
result.push({
|
|
28610
|
+
id: server2.id,
|
|
28611
|
+
installed: isServerInstalled(server2.command),
|
|
28612
|
+
extensions: server2.extensions,
|
|
28613
|
+
disabled: false,
|
|
28614
|
+
source: server2.source,
|
|
28615
|
+
priority: server2.priority
|
|
28616
|
+
});
|
|
28617
|
+
seen.add(server2.id);
|
|
28618
|
+
}
|
|
28619
|
+
for (const id of disabled) {
|
|
28620
|
+
if (seen.has(id))
|
|
28621
|
+
continue;
|
|
28622
|
+
const builtin = BUILTIN_SERVERS[id];
|
|
28623
|
+
result.push({
|
|
28624
|
+
id,
|
|
28625
|
+
installed: builtin ? isServerInstalled(builtin.command) : false,
|
|
28626
|
+
extensions: builtin?.extensions || [],
|
|
28627
|
+
disabled: true,
|
|
28628
|
+
source: "disabled",
|
|
28629
|
+
priority: 0
|
|
28630
|
+
});
|
|
28631
|
+
}
|
|
28632
|
+
return result;
|
|
28370
28633
|
}
|
|
28371
|
-
|
|
28372
|
-
|
|
28373
|
-
|
|
28374
|
-
|
|
28375
|
-
};
|
|
28634
|
+
// src/cli/doctor/checks/tools-lsp.ts
|
|
28635
|
+
function getInstalledLspServers() {
|
|
28636
|
+
const servers = getAllServers();
|
|
28637
|
+
return servers.filter((s) => s.installed && !s.disabled).map((s) => ({ id: s.id, extensions: s.extensions }));
|
|
28376
28638
|
}
|
|
28377
28639
|
|
|
28378
28640
|
// src/cli/doctor/checks/tools-mcp.ts
|
|
28379
28641
|
init_shared();
|
|
28380
|
-
import { existsSync as
|
|
28642
|
+
import { existsSync as existsSync29, readFileSync as readFileSync26 } from "fs";
|
|
28381
28643
|
import { homedir as homedir8 } from "os";
|
|
28382
|
-
import { join as
|
|
28644
|
+
import { join as join28 } from "path";
|
|
28383
28645
|
var BUILTIN_MCP_SERVERS = ["context7", "grep_app"];
|
|
28384
28646
|
function getMcpConfigPaths() {
|
|
28385
28647
|
return [
|
|
28386
|
-
|
|
28387
|
-
|
|
28388
|
-
|
|
28648
|
+
join28(homedir8(), ".claude", ".mcp.json"),
|
|
28649
|
+
join28(process.cwd(), ".mcp.json"),
|
|
28650
|
+
join28(process.cwd(), ".claude", ".mcp.json")
|
|
28389
28651
|
];
|
|
28390
28652
|
}
|
|
28391
28653
|
function loadUserMcpConfig() {
|
|
28392
28654
|
const servers = {};
|
|
28393
28655
|
for (const configPath of getMcpConfigPaths()) {
|
|
28394
|
-
if (!
|
|
28656
|
+
if (!existsSync29(configPath))
|
|
28395
28657
|
continue;
|
|
28396
28658
|
try {
|
|
28397
|
-
const content =
|
|
28659
|
+
const content = readFileSync26(configPath, "utf-8");
|
|
28398
28660
|
const config2 = parseJsonc(content);
|
|
28399
28661
|
if (config2.mcpServers) {
|
|
28400
28662
|
Object.assign(servers, config2.mcpServers);
|
|
@@ -28434,13 +28696,11 @@ async function gatherToolsSummary() {
|
|
|
28434
28696
|
checkCommentChecker(),
|
|
28435
28697
|
getGhCliInfo()
|
|
28436
28698
|
]);
|
|
28437
|
-
const lspServers =
|
|
28438
|
-
const lspStats = getLspServerStats(lspServers);
|
|
28699
|
+
const lspServers = getInstalledLspServers();
|
|
28439
28700
|
const builtinMcp = getBuiltinMcpInfo();
|
|
28440
28701
|
const userMcp = getUserMcpInfo();
|
|
28441
28702
|
return {
|
|
28442
|
-
|
|
28443
|
-
lspTotal: lspStats.total,
|
|
28703
|
+
lspServers,
|
|
28444
28704
|
astGrepCli: astGrepCliInfo.installed,
|
|
28445
28705
|
astGrepNapi: astGrepNapiInfo.installed,
|
|
28446
28706
|
commentChecker: commentCheckerInfo.installed,
|
|
@@ -28473,7 +28733,7 @@ function buildToolIssues(summary) {
|
|
|
28473
28733
|
affects: ["comment-checker hook"]
|
|
28474
28734
|
});
|
|
28475
28735
|
}
|
|
28476
|
-
if (summary.
|
|
28736
|
+
if (summary.lspServers.length === 0) {
|
|
28477
28737
|
issues.push({
|
|
28478
28738
|
title: "No LSP servers detected",
|
|
28479
28739
|
description: "LSP-dependent tools will be limited until at least one server is installed.",
|
|
@@ -28520,7 +28780,7 @@ async function checkTools() {
|
|
|
28520
28780
|
details: [
|
|
28521
28781
|
`AST-Grep: cli=${summary.astGrepCli ? "yes" : "no"}, napi=${summary.astGrepNapi ? "yes" : "no"}`,
|
|
28522
28782
|
`Comment checker: ${summary.commentChecker ? "yes" : "no"}`,
|
|
28523
|
-
`LSP: ${summary.
|
|
28783
|
+
`LSP: ${summary.lspServers.length > 0 ? `${summary.lspServers.length} server(s)` : "none"}`,
|
|
28524
28784
|
`GH CLI: ${summary.ghCli.installed ? "installed" : "missing"}${summary.ghCli.authenticated ? " (authenticated)" : ""}`,
|
|
28525
28785
|
`MCP: builtin=${summary.mcpBuiltin.length}, user=${summary.mcpUser.length}`
|
|
28526
28786
|
],
|
|
@@ -28555,10 +28815,10 @@ function getAllCheckDefinitions() {
|
|
|
28555
28815
|
}
|
|
28556
28816
|
|
|
28557
28817
|
// src/cli/doctor/format-default.ts
|
|
28558
|
-
var
|
|
28818
|
+
var import_picocolors18 = __toESM(require_picocolors(), 1);
|
|
28559
28819
|
|
|
28560
28820
|
// src/cli/doctor/format-shared.ts
|
|
28561
|
-
var
|
|
28821
|
+
var import_picocolors17 = __toESM(require_picocolors(), 1);
|
|
28562
28822
|
function formatStatusSymbol(status) {
|
|
28563
28823
|
const colorFn = STATUS_COLORS[status];
|
|
28564
28824
|
switch (status) {
|
|
@@ -28573,23 +28833,23 @@ function formatStatusSymbol(status) {
|
|
|
28573
28833
|
}
|
|
28574
28834
|
}
|
|
28575
28835
|
function formatStatusMark(available) {
|
|
28576
|
-
return available ?
|
|
28836
|
+
return available ? import_picocolors17.default.green(SYMBOLS3.check) : import_picocolors17.default.red(SYMBOLS3.cross);
|
|
28577
28837
|
}
|
|
28578
28838
|
function formatHeader() {
|
|
28579
28839
|
return `
|
|
28580
|
-
${
|
|
28840
|
+
${import_picocolors17.default.bgMagenta(import_picocolors17.default.white(" oMoMoMoMo Doctor "))}
|
|
28581
28841
|
`;
|
|
28582
28842
|
}
|
|
28583
28843
|
function formatIssue(issue2, index) {
|
|
28584
28844
|
const lines = [];
|
|
28585
|
-
const severityColor = issue2.severity === "error" ?
|
|
28845
|
+
const severityColor = issue2.severity === "error" ? import_picocolors17.default.red : import_picocolors17.default.yellow;
|
|
28586
28846
|
lines.push(`${index}. ${severityColor(issue2.title)}`);
|
|
28587
|
-
lines.push(` ${
|
|
28847
|
+
lines.push(` ${import_picocolors17.default.dim(issue2.description)}`);
|
|
28588
28848
|
if (issue2.fix) {
|
|
28589
|
-
lines.push(` ${
|
|
28849
|
+
lines.push(` ${import_picocolors17.default.cyan("Fix:")} ${import_picocolors17.default.dim(issue2.fix)}`);
|
|
28590
28850
|
}
|
|
28591
28851
|
if (issue2.affects && issue2.affects.length > 0) {
|
|
28592
|
-
lines.push(` ${
|
|
28852
|
+
lines.push(` ${import_picocolors17.default.cyan("Affects:")} ${import_picocolors17.default.dim(issue2.affects.join(", "))}`);
|
|
28593
28853
|
}
|
|
28594
28854
|
return lines.join(`
|
|
28595
28855
|
`);
|
|
@@ -28603,12 +28863,12 @@ function formatDefault(result) {
|
|
|
28603
28863
|
if (allIssues.length === 0) {
|
|
28604
28864
|
const opencodeVer = result.systemInfo.opencodeVersion ?? "unknown";
|
|
28605
28865
|
const pluginVer = result.systemInfo.pluginVersion ?? "unknown";
|
|
28606
|
-
lines.push(` ${
|
|
28866
|
+
lines.push(` ${import_picocolors18.default.green(SYMBOLS3.check)} ${import_picocolors18.default.green(`System OK (opencode ${opencodeVer} \xB7 oh-my-opencode ${pluginVer})`)}`);
|
|
28607
28867
|
} else {
|
|
28608
28868
|
const issueCount = allIssues.filter((i2) => i2.severity === "error").length;
|
|
28609
28869
|
const warnCount = allIssues.filter((i2) => i2.severity === "warning").length;
|
|
28610
28870
|
const totalStr = `${issueCount + warnCount} ${issueCount + warnCount === 1 ? "issue" : "issues"}`;
|
|
28611
|
-
lines.push(` ${
|
|
28871
|
+
lines.push(` ${import_picocolors18.default.yellow(SYMBOLS3.warn)} ${totalStr} found:
|
|
28612
28872
|
`);
|
|
28613
28873
|
allIssues.forEach((issue2, index) => {
|
|
28614
28874
|
lines.push(formatIssue(issue2, index + 1));
|
|
@@ -28620,7 +28880,7 @@ function formatDefault(result) {
|
|
|
28620
28880
|
}
|
|
28621
28881
|
|
|
28622
28882
|
// src/cli/doctor/format-status.ts
|
|
28623
|
-
var
|
|
28883
|
+
var import_picocolors19 = __toESM(require_picocolors(), 1);
|
|
28624
28884
|
function formatStatus(result) {
|
|
28625
28885
|
const lines = [];
|
|
28626
28886
|
lines.push(formatHeader());
|
|
@@ -28631,13 +28891,15 @@ function formatStatus(result) {
|
|
|
28631
28891
|
const bunVer = systemInfo.bunVersion ?? "unknown";
|
|
28632
28892
|
lines.push(` ${padding}System ${opencodeVer} \xB7 ${pluginVer} \xB7 Bun ${bunVer}`);
|
|
28633
28893
|
const configPath = systemInfo.configPath ?? "unknown";
|
|
28634
|
-
const configStatus = systemInfo.configValid ?
|
|
28894
|
+
const configStatus = systemInfo.configValid ? import_picocolors19.default.green("(valid)") : import_picocolors19.default.red("(invalid)");
|
|
28635
28895
|
lines.push(` ${padding}Config ${configPath} ${configStatus}`);
|
|
28636
|
-
const
|
|
28896
|
+
const serverCount = tools.lspServers.length;
|
|
28897
|
+
const lspMark = formatStatusMark(serverCount > 0);
|
|
28898
|
+
const lspText = serverCount > 0 ? `${serverCount} server${serverCount === 1 ? "" : "s"}` : "none";
|
|
28637
28899
|
const astGrepMark = formatStatusMark(tools.astGrepCli);
|
|
28638
28900
|
const ghMark = formatStatusMark(tools.ghCli.installed && tools.ghCli.authenticated);
|
|
28639
28901
|
const ghUser = tools.ghCli.username ?? "";
|
|
28640
|
-
lines.push(` ${padding}Tools ${lspText} \xB7 AST-Grep ${astGrepMark} \xB7 gh ${ghMark}${ghUser ? ` (${ghUser})` : ""}`);
|
|
28902
|
+
lines.push(` ${padding}Tools LSP ${lspMark} ${lspText} \xB7 AST-Grep ${astGrepMark} \xB7 gh ${ghMark}${ghUser ? ` (${ghUser})` : ""}`);
|
|
28641
28903
|
const builtinCount = tools.mcpBuiltin.length;
|
|
28642
28904
|
const userCount = tools.mcpUser.length;
|
|
28643
28905
|
const builtinText = builtinCount > 0 ? tools.mcpBuiltin.join(" \xB7 ") : "none";
|
|
@@ -28648,13 +28910,13 @@ function formatStatus(result) {
|
|
|
28648
28910
|
}
|
|
28649
28911
|
|
|
28650
28912
|
// src/cli/doctor/format-verbose.ts
|
|
28651
|
-
var
|
|
28913
|
+
var import_picocolors20 = __toESM(require_picocolors(), 1);
|
|
28652
28914
|
function formatVerbose(result) {
|
|
28653
28915
|
const lines = [];
|
|
28654
28916
|
lines.push(formatHeader());
|
|
28655
28917
|
const { systemInfo, tools, results, summary } = result;
|
|
28656
|
-
lines.push(`${
|
|
28657
|
-
lines.push(`${
|
|
28918
|
+
lines.push(`${import_picocolors20.default.bold("System Information")}`);
|
|
28919
|
+
lines.push(`${import_picocolors20.default.dim("\u2500".repeat(40))}`);
|
|
28658
28920
|
lines.push(` ${formatStatusSymbol("pass")} opencode ${systemInfo.opencodeVersion ?? "unknown"}`);
|
|
28659
28921
|
lines.push(` ${formatStatusSymbol("pass")} oh-my-opencode ${systemInfo.pluginVersion ?? "unknown"}`);
|
|
28660
28922
|
if (systemInfo.loadedVersion) {
|
|
@@ -28665,54 +28927,73 @@ function formatVerbose(result) {
|
|
|
28665
28927
|
}
|
|
28666
28928
|
lines.push(` ${formatStatusSymbol("pass")} path ${systemInfo.opencodePath ?? "unknown"}`);
|
|
28667
28929
|
if (systemInfo.isLocalDev) {
|
|
28668
|
-
lines.push(` ${
|
|
28930
|
+
lines.push(` ${import_picocolors20.default.yellow("*")} ${import_picocolors20.default.dim("(local development mode)")}`);
|
|
28669
28931
|
}
|
|
28670
28932
|
lines.push("");
|
|
28671
|
-
lines.push(`${
|
|
28672
|
-
lines.push(`${
|
|
28673
|
-
const configStatus = systemInfo.configValid ?
|
|
28933
|
+
lines.push(`${import_picocolors20.default.bold("Configuration")}`);
|
|
28934
|
+
lines.push(`${import_picocolors20.default.dim("\u2500".repeat(40))}`);
|
|
28935
|
+
const configStatus = systemInfo.configValid ? import_picocolors20.default.green("valid") : import_picocolors20.default.red("invalid");
|
|
28674
28936
|
lines.push(` ${formatStatusSymbol(systemInfo.configValid ? "pass" : "fail")} ${systemInfo.configPath ?? "unknown"} (${configStatus})`);
|
|
28675
28937
|
lines.push("");
|
|
28676
|
-
lines.push(`${
|
|
28677
|
-
lines.push(`${
|
|
28678
|
-
|
|
28938
|
+
lines.push(`${import_picocolors20.default.bold("Tools")}`);
|
|
28939
|
+
lines.push(`${import_picocolors20.default.dim("\u2500".repeat(40))}`);
|
|
28940
|
+
if (tools.lspServers.length === 0) {
|
|
28941
|
+
lines.push(` ${formatStatusSymbol("warn")} LSP none detected`);
|
|
28942
|
+
} else {
|
|
28943
|
+
const count = tools.lspServers.length;
|
|
28944
|
+
lines.push(` ${formatStatusSymbol("pass")} LSP ${count} server${count === 1 ? "" : "s"}`);
|
|
28945
|
+
for (const server2 of tools.lspServers) {
|
|
28946
|
+
lines.push(`${" ".repeat(20)}${server2.id} (${server2.extensions.join(", ")})`);
|
|
28947
|
+
}
|
|
28948
|
+
}
|
|
28679
28949
|
lines.push(` ${formatStatusSymbol(tools.astGrepCli ? "pass" : "fail")} ast-grep CLI ${tools.astGrepCli ? "installed" : "not found"}`);
|
|
28680
28950
|
lines.push(` ${formatStatusSymbol(tools.astGrepNapi ? "pass" : "fail")} ast-grep napi ${tools.astGrepNapi ? "installed" : "not found"}`);
|
|
28681
28951
|
lines.push(` ${formatStatusSymbol(tools.commentChecker ? "pass" : "fail")} comment-checker ${tools.commentChecker ? "installed" : "not found"}`);
|
|
28682
28952
|
lines.push(` ${formatStatusSymbol(tools.ghCli.installed && tools.ghCli.authenticated ? "pass" : "fail")} gh CLI ${tools.ghCli.installed ? "installed" : "not found"}${tools.ghCli.authenticated && tools.ghCli.username ? ` (${tools.ghCli.username})` : ""}`);
|
|
28683
28953
|
lines.push("");
|
|
28684
|
-
lines.push(`${
|
|
28685
|
-
lines.push(`${
|
|
28954
|
+
lines.push(`${import_picocolors20.default.bold("MCPs")}`);
|
|
28955
|
+
lines.push(`${import_picocolors20.default.dim("\u2500".repeat(40))}`);
|
|
28686
28956
|
if (tools.mcpBuiltin.length === 0) {
|
|
28687
|
-
lines.push(` ${
|
|
28957
|
+
lines.push(` ${import_picocolors20.default.dim("No built-in MCPs")}`);
|
|
28688
28958
|
} else {
|
|
28689
28959
|
for (const mcp of tools.mcpBuiltin) {
|
|
28690
28960
|
lines.push(` ${formatStatusSymbol("pass")} ${mcp}`);
|
|
28691
28961
|
}
|
|
28692
28962
|
}
|
|
28693
28963
|
if (tools.mcpUser.length > 0) {
|
|
28694
|
-
lines.push(` ${
|
|
28964
|
+
lines.push(` ${import_picocolors20.default.cyan("+")} ${tools.mcpUser.length} user MCP(s):`);
|
|
28695
28965
|
for (const mcp of tools.mcpUser) {
|
|
28696
28966
|
lines.push(` ${formatStatusSymbol("pass")} ${mcp}`);
|
|
28697
28967
|
}
|
|
28698
28968
|
}
|
|
28699
28969
|
lines.push("");
|
|
28970
|
+
for (const check2 of results) {
|
|
28971
|
+
if (!check2.details || check2.details.length === 0) {
|
|
28972
|
+
continue;
|
|
28973
|
+
}
|
|
28974
|
+
lines.push(`${import_picocolors20.default.bold(check2.name)}`);
|
|
28975
|
+
lines.push(`${import_picocolors20.default.dim("\u2500".repeat(40))}`);
|
|
28976
|
+
for (const detail of check2.details) {
|
|
28977
|
+
lines.push(detail);
|
|
28978
|
+
}
|
|
28979
|
+
lines.push("");
|
|
28980
|
+
}
|
|
28700
28981
|
const allIssues = results.flatMap((r2) => r2.issues);
|
|
28701
28982
|
if (allIssues.length > 0) {
|
|
28702
|
-
lines.push(`${
|
|
28703
|
-
lines.push(`${
|
|
28983
|
+
lines.push(`${import_picocolors20.default.bold("Issues")}`);
|
|
28984
|
+
lines.push(`${import_picocolors20.default.dim("\u2500".repeat(40))}`);
|
|
28704
28985
|
allIssues.forEach((issue2, index) => {
|
|
28705
28986
|
lines.push(formatIssue(issue2, index + 1));
|
|
28706
28987
|
lines.push("");
|
|
28707
28988
|
});
|
|
28708
28989
|
}
|
|
28709
|
-
lines.push(`${
|
|
28710
|
-
lines.push(`${
|
|
28711
|
-
const passText = summary.passed > 0 ?
|
|
28712
|
-
const failText = summary.failed > 0 ?
|
|
28713
|
-
const warnText = summary.warnings > 0 ?
|
|
28990
|
+
lines.push(`${import_picocolors20.default.bold("Summary")}`);
|
|
28991
|
+
lines.push(`${import_picocolors20.default.dim("\u2500".repeat(40))}`);
|
|
28992
|
+
const passText = summary.passed > 0 ? import_picocolors20.default.green(`${summary.passed} passed`) : `${summary.passed} passed`;
|
|
28993
|
+
const failText = summary.failed > 0 ? import_picocolors20.default.red(`${summary.failed} failed`) : `${summary.failed} failed`;
|
|
28994
|
+
const warnText = summary.warnings > 0 ? import_picocolors20.default.yellow(`${summary.warnings} warnings`) : `${summary.warnings} warnings`;
|
|
28714
28995
|
lines.push(` ${passText}, ${failText}, ${warnText}`);
|
|
28715
|
-
lines.push(` ${
|
|
28996
|
+
lines.push(` ${import_picocolors20.default.dim(`Total: ${summary.total} checks in ${summary.duration}ms`)}`);
|
|
28716
28997
|
return lines.join(`
|
|
28717
28998
|
`);
|
|
28718
28999
|
}
|
|
@@ -28796,11 +29077,11 @@ async function doctor(options = { mode: "default" }) {
|
|
|
28796
29077
|
|
|
28797
29078
|
// src/features/mcp-oauth/storage.ts
|
|
28798
29079
|
init_shared();
|
|
28799
|
-
import { chmodSync, existsSync as
|
|
28800
|
-
import { dirname as dirname7, join as
|
|
29080
|
+
import { chmodSync, existsSync as existsSync30, mkdirSync as mkdirSync6, readFileSync as readFileSync27, unlinkSync as unlinkSync4, writeFileSync as writeFileSync10 } from "fs";
|
|
29081
|
+
import { dirname as dirname7, join as join29 } from "path";
|
|
28801
29082
|
var STORAGE_FILE_NAME = "mcp-oauth.json";
|
|
28802
29083
|
function getMcpOauthStoragePath() {
|
|
28803
|
-
return
|
|
29084
|
+
return join29(getOpenCodeConfigDir({ binary: "opencode" }), STORAGE_FILE_NAME);
|
|
28804
29085
|
}
|
|
28805
29086
|
function normalizeHost(serverHost) {
|
|
28806
29087
|
let host = serverHost.trim();
|
|
@@ -28837,11 +29118,11 @@ function buildKey(serverHost, resource) {
|
|
|
28837
29118
|
}
|
|
28838
29119
|
function readStore() {
|
|
28839
29120
|
const filePath = getMcpOauthStoragePath();
|
|
28840
|
-
if (!
|
|
29121
|
+
if (!existsSync30(filePath)) {
|
|
28841
29122
|
return null;
|
|
28842
29123
|
}
|
|
28843
29124
|
try {
|
|
28844
|
-
const content =
|
|
29125
|
+
const content = readFileSync27(filePath, "utf-8");
|
|
28845
29126
|
return JSON.parse(content);
|
|
28846
29127
|
} catch {
|
|
28847
29128
|
return null;
|
|
@@ -28851,7 +29132,7 @@ function writeStore(store2) {
|
|
|
28851
29132
|
const filePath = getMcpOauthStoragePath();
|
|
28852
29133
|
try {
|
|
28853
29134
|
const dir = dirname7(filePath);
|
|
28854
|
-
if (!
|
|
29135
|
+
if (!existsSync30(dir)) {
|
|
28855
29136
|
mkdirSync6(dir, { recursive: true });
|
|
28856
29137
|
}
|
|
28857
29138
|
writeFileSync10(filePath, JSON.stringify(store2, null, 2), { encoding: "utf-8", mode: 384 });
|
|
@@ -28886,8 +29167,8 @@ function deleteToken(serverHost, resource) {
|
|
|
28886
29167
|
if (Object.keys(store2).length === 0) {
|
|
28887
29168
|
try {
|
|
28888
29169
|
const filePath = getMcpOauthStoragePath();
|
|
28889
|
-
if (
|
|
28890
|
-
|
|
29170
|
+
if (existsSync30(filePath)) {
|
|
29171
|
+
unlinkSync4(filePath);
|
|
28891
29172
|
}
|
|
28892
29173
|
return true;
|
|
28893
29174
|
} catch {
|
|
@@ -29420,7 +29701,7 @@ function createMcpOAuthCommand() {
|
|
|
29420
29701
|
var VERSION2 = package_default.version;
|
|
29421
29702
|
var program2 = new Command;
|
|
29422
29703
|
program2.name("oh-my-opencode").description("The ultimate OpenCode plugin - multi-model orchestration, LSP tools, and more").version(VERSION2, "-v, --version", "Show version number").enablePositionalOptions();
|
|
29423
|
-
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("--kimi-for-coding <value>", "Kimi For Coding subscription: no, yes (default: no)").option("--skip-auth", "Skip authentication setup hints").addHelpText("after", `
|
|
29704
|
+
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("--kimi-for-coding <value>", "Kimi For Coding subscription: no, yes (default: no)").option("--opencode-go <value>", "OpenCode Go subscription: no, yes (default: no)").option("--skip-auth", "Skip authentication setup hints").addHelpText("after", `
|
|
29424
29705
|
Examples:
|
|
29425
29706
|
$ bunx oh-my-opencode install
|
|
29426
29707
|
$ bunx oh-my-opencode install --no-tui --claude=max20 --openai=yes --gemini=yes --copilot=no
|
|
@@ -29444,12 +29725,13 @@ Model Providers (Priority: Native > Copilot > OpenCode Zen > Z.ai > Kimi):
|
|
|
29444
29725
|
opencodeZen: options.opencodeZen,
|
|
29445
29726
|
zaiCodingPlan: options.zaiCodingPlan,
|
|
29446
29727
|
kimiForCoding: options.kimiForCoding,
|
|
29728
|
+
opencodeGo: options.opencodeGo,
|
|
29447
29729
|
skipAuth: options.skipAuth ?? false
|
|
29448
29730
|
};
|
|
29449
29731
|
const exitCode = await install(args);
|
|
29450
29732
|
process.exit(exitCode);
|
|
29451
29733
|
});
|
|
29452
|
-
program2.command("run <message>").allowUnknownOption().passThroughOptions().description("Run opencode with todo/background task completion enforcement").option("-a, --agent <name>", "Agent to use (default: from CLI/env/config, fallback: Sisyphus)").option("-d, --directory <path>", "Working directory").option("-p, --port <port>", "Server port (attaches if port already in use)", parseInt).option("--attach <url>", "Attach to existing opencode server URL").option("--on-complete <command>", "Shell command to run after completion").option("--json", "Output structured JSON result to stdout").option("--no-timestamp", "Disable timestamp prefix in run output").option("--verbose", "Show full event stream (default: messages/tools only)").option("--session-id <id>", "Resume existing session instead of creating new one").addHelpText("after", `
|
|
29734
|
+
program2.command("run <message>").allowUnknownOption().passThroughOptions().description("Run opencode with todo/background task completion enforcement").option("-a, --agent <name>", "Agent to use (default: from CLI/env/config, fallback: Sisyphus)").option("-m, --model <provider/model>", "Model override (e.g., anthropic/claude-sonnet-4)").option("-d, --directory <path>", "Working directory").option("-p, --port <port>", "Server port (attaches if port already in use)", parseInt).option("--attach <url>", "Attach to existing opencode server URL").option("--on-complete <command>", "Shell command to run after completion").option("--json", "Output structured JSON result to stdout").option("--no-timestamp", "Disable timestamp prefix in run output").option("--verbose", "Show full event stream (default: messages/tools only)").option("--session-id <id>", "Resume existing session instead of creating new one").addHelpText("after", `
|
|
29453
29735
|
Examples:
|
|
29454
29736
|
$ bunx oh-my-opencode run "Fix the bug in index.ts"
|
|
29455
29737
|
$ bunx oh-my-opencode run --agent Sisyphus "Implement feature X"
|
|
@@ -29458,6 +29740,8 @@ Examples:
|
|
|
29458
29740
|
$ bunx oh-my-opencode run --json "Fix the bug" | jq .sessionId
|
|
29459
29741
|
$ bunx oh-my-opencode run --on-complete "notify-send Done" "Fix the bug"
|
|
29460
29742
|
$ bunx oh-my-opencode run --session-id ses_abc123 "Continue the work"
|
|
29743
|
+
$ bunx oh-my-opencode run --model anthropic/claude-sonnet-4 "Fix the bug"
|
|
29744
|
+
$ bunx oh-my-opencode run --agent Sisyphus --model openai/gpt-5.4 "Implement feature X"
|
|
29461
29745
|
|
|
29462
29746
|
Agent resolution order:
|
|
29463
29747
|
1) --agent flag
|
|
@@ -29479,6 +29763,7 @@ Unlike 'opencode run', this command waits until:
|
|
|
29479
29763
|
const runOptions = {
|
|
29480
29764
|
message,
|
|
29481
29765
|
agent: options.agent,
|
|
29766
|
+
model: options.model,
|
|
29482
29767
|
directory: options.directory,
|
|
29483
29768
|
port: options.port,
|
|
29484
29769
|
attach: options.attach,
|