oh-my-opencode 3.2.0 → 3.2.2
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/dist/agents/{atlas.d.ts → atlas/default.d.ts} +8 -19
- package/dist/agents/atlas/gpt.d.ts +19 -0
- package/dist/agents/atlas/index.d.ts +39 -0
- package/dist/agents/atlas/utils.d.ts +13 -0
- package/dist/agents/hephaestus.d.ts +1 -1
- package/dist/agents/prometheus/identity-constraints.d.ts +1 -1
- package/dist/agents/prometheus/index.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/sisyphus-junior/default.d.ts +9 -0
- package/dist/agents/sisyphus-junior/gpt.d.ts +18 -0
- package/dist/agents/sisyphus-junior/index.d.ts +31 -0
- package/dist/agents/sisyphus.d.ts +1 -1
- package/dist/cli/index.js +1140 -835
- package/dist/cli/run/runner.d.ts +4 -0
- package/dist/config/index.d.ts +1 -1
- package/dist/config/schema.d.ts +23 -43
- package/dist/features/background-agent/manager.d.ts +6 -0
- package/dist/features/builtin-commands/templates/init-deep.d.ts +1 -1
- package/dist/features/claude-tasks/index.d.ts +2 -0
- package/dist/features/claude-tasks/storage.d.ts +12 -0
- package/dist/features/claude-tasks/types.d.ts +25 -0
- package/dist/hooks/auto-slash-command/detector.d.ts +4 -0
- package/dist/hooks/auto-slash-command/index.d.ts +2 -1
- package/dist/hooks/auto-slash-command/types.d.ts +12 -0
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/keyword-detector/ultrawork/default.d.ts +4 -4
- package/dist/hooks/keyword-detector/ultrawork/gpt5.2.d.ts +5 -6
- package/dist/hooks/keyword-detector/ultrawork/planner.d.ts +1 -1
- package/dist/hooks/preemptive-compaction.d.ts +30 -0
- package/dist/hooks/prometheus-md-only/constants.d.ts +1 -1
- package/dist/hooks/task-reminder/index.d.ts +19 -0
- package/dist/hooks/tasks-todowrite-disabler/constants.d.ts +3 -0
- package/dist/hooks/tasks-todowrite-disabler/index.d.ts +14 -0
- package/dist/index.js +26317 -24694
- package/dist/tools/delegate-task/constants.d.ts +1 -1
- package/dist/tools/delegate-task/types.d.ts +4 -0
- package/dist/tools/index.d.ts +1 -0
- package/dist/tools/task/index.d.ts +7 -0
- package/dist/tools/task/task-create.d.ts +4 -0
- package/dist/tools/task/task-get.d.ts +3 -0
- package/dist/tools/task/task-list.d.ts +3 -0
- package/dist/tools/task/task-update.d.ts +4 -0
- package/dist/tools/task/task.d.ts +3 -0
- package/dist/tools/task/todo-sync.d.ts +16 -0
- package/dist/tools/task/types.d.ts +97 -0
- package/package.json +9 -9
- package/dist/agents/momus.test.d.ts +0 -1
- package/dist/agents/prometheus-prompt.test.d.ts +0 -1
- package/dist/agents/sisyphus-junior.d.ts +0 -10
- package/dist/agents/sisyphus-junior.test.d.ts +0 -1
- package/dist/agents/utils.test.d.ts +0 -1
- package/dist/cli/config-manager.test.d.ts +0 -1
- package/dist/cli/doctor/checks/auth.test.d.ts +0 -1
- package/dist/cli/doctor/checks/config.test.d.ts +0 -1
- package/dist/cli/doctor/checks/dependencies.test.d.ts +0 -1
- package/dist/cli/doctor/checks/gh.test.d.ts +0 -1
- package/dist/cli/doctor/checks/lsp.test.d.ts +0 -1
- package/dist/cli/doctor/checks/mcp-oauth.test.d.ts +0 -1
- package/dist/cli/doctor/checks/mcp.test.d.ts +0 -1
- package/dist/cli/doctor/checks/model-resolution.test.d.ts +0 -1
- package/dist/cli/doctor/checks/opencode.test.d.ts +0 -1
- package/dist/cli/doctor/checks/plugin.test.d.ts +0 -1
- package/dist/cli/doctor/checks/version.test.d.ts +0 -1
- package/dist/cli/doctor/formatter.test.d.ts +0 -1
- package/dist/cli/doctor/runner.test.d.ts +0 -1
- package/dist/cli/index.test.d.ts +0 -1
- package/dist/cli/install.test.d.ts +0 -1
- package/dist/cli/mcp-oauth/index.test.d.ts +0 -1
- package/dist/cli/mcp-oauth/login.test.d.ts +0 -1
- package/dist/cli/mcp-oauth/logout.test.d.ts +0 -1
- package/dist/cli/mcp-oauth/status.test.d.ts +0 -1
- package/dist/cli/model-fallback.test.d.ts +0 -1
- package/dist/cli/run/completion.test.d.ts +0 -1
- package/dist/cli/run/events.test.d.ts +0 -1
- package/dist/config/schema.test.d.ts +0 -1
- package/dist/features/background-agent/concurrency.test.d.ts +0 -1
- package/dist/features/background-agent/manager.test.d.ts +0 -1
- package/dist/features/boulder-state/storage.test.d.ts +0 -1
- package/dist/features/builtin-commands/templates/stop-continuation.test.d.ts +0 -1
- package/dist/features/builtin-skills/skills.test.d.ts +0 -1
- package/dist/features/claude-code-mcp-loader/loader.test.d.ts +0 -1
- package/dist/features/claude-code-session-state/state.test.d.ts +0 -1
- package/dist/features/context-injector/collector.test.d.ts +0 -1
- package/dist/features/context-injector/injector.test.d.ts +0 -1
- package/dist/features/mcp-oauth/callback-server.test.d.ts +0 -1
- package/dist/features/mcp-oauth/dcr.test.d.ts +0 -1
- package/dist/features/mcp-oauth/discovery.test.d.ts +0 -1
- package/dist/features/mcp-oauth/provider.test.d.ts +0 -1
- package/dist/features/mcp-oauth/resource-indicator.test.d.ts +0 -1
- package/dist/features/mcp-oauth/schema.test.d.ts +0 -1
- package/dist/features/mcp-oauth/step-up.test.d.ts +0 -1
- package/dist/features/mcp-oauth/storage.test.d.ts +0 -1
- package/dist/features/opencode-skill-loader/async-loader.test.d.ts +0 -1
- package/dist/features/opencode-skill-loader/blocking.test.d.ts +0 -1
- package/dist/features/opencode-skill-loader/loader.test.d.ts +0 -1
- package/dist/features/opencode-skill-loader/skill-content.test.d.ts +0 -1
- package/dist/features/sisyphus-swarm/mailbox/types.d.ts +0 -191
- package/dist/features/sisyphus-swarm/mailbox/types.test.d.ts +0 -1
- package/dist/features/sisyphus-tasks/storage.d.ts +0 -9
- package/dist/features/sisyphus-tasks/storage.test.d.ts +0 -1
- package/dist/features/sisyphus-tasks/types.d.ts +0 -47
- package/dist/features/sisyphus-tasks/types.test.d.ts +0 -1
- package/dist/features/skill-mcp-manager/env-cleaner.test.d.ts +0 -1
- package/dist/features/skill-mcp-manager/manager.test.d.ts +0 -1
- package/dist/features/task-toast-manager/manager.test.d.ts +0 -1
- package/dist/features/tmux-subagent/decision-engine.test.d.ts +0 -1
- package/dist/features/tmux-subagent/manager.test.d.ts +0 -1
- package/dist/hooks/anthropic-context-window-limit-recovery/executor.test.d.ts +0 -1
- package/dist/hooks/anthropic-context-window-limit-recovery/pruning-deduplication.test.d.ts +0 -1
- package/dist/hooks/anthropic-context-window-limit-recovery/storage.test.d.ts +0 -1
- package/dist/hooks/atlas/index.test.d.ts +0 -1
- package/dist/hooks/auto-slash-command/detector.test.d.ts +0 -1
- package/dist/hooks/auto-slash-command/index.test.d.ts +0 -1
- package/dist/hooks/auto-update-checker/checker.test.d.ts +0 -1
- package/dist/hooks/auto-update-checker/index.test.d.ts +0 -1
- package/dist/hooks/category-skill-reminder/index.test.d.ts +0 -1
- package/dist/hooks/comment-checker/cli.test.d.ts +0 -1
- package/dist/hooks/compaction-context-injector/index.test.d.ts +0 -1
- package/dist/hooks/delegate-task-retry/index.test.d.ts +0 -1
- package/dist/hooks/edit-error-recovery/index.test.d.ts +0 -1
- package/dist/hooks/keyword-detector/index.test.d.ts +0 -1
- package/dist/hooks/non-interactive-env/index.test.d.ts +0 -1
- package/dist/hooks/prometheus-md-only/index.test.d.ts +0 -1
- package/dist/hooks/question-label-truncator/index.test.d.ts +0 -1
- package/dist/hooks/ralph-loop/index.test.d.ts +0 -1
- package/dist/hooks/rules-injector/finder.test.d.ts +0 -1
- package/dist/hooks/rules-injector/output-path.test.d.ts +0 -1
- package/dist/hooks/rules-injector/parser.test.d.ts +0 -1
- package/dist/hooks/session-notification.test.d.ts +0 -1
- package/dist/hooks/session-recovery/index.test.d.ts +0 -1
- package/dist/hooks/start-work/index.test.d.ts +0 -1
- package/dist/hooks/stop-continuation-guard/index.test.d.ts +0 -1
- package/dist/hooks/subagent-question-blocker/index.test.d.ts +0 -1
- package/dist/hooks/think-mode/index.test.d.ts +0 -1
- package/dist/hooks/think-mode/switcher.test.d.ts +0 -1
- package/dist/hooks/todo-continuation-enforcer.test.d.ts +0 -1
- package/dist/hooks/tool-output-truncator.test.d.ts +0 -1
- package/dist/hooks/unstable-agent-babysitter/index.test.d.ts +0 -1
- package/dist/index.test.d.ts +0 -1
- package/dist/mcp/index.test.d.ts +0 -1
- package/dist/plugin-config.test.d.ts +0 -1
- package/dist/plugin-handlers/config-handler.test.d.ts +0 -1
- package/dist/shared/agent-config-integration.test.d.ts +0 -1
- package/dist/shared/agent-display-names.test.d.ts +0 -1
- package/dist/shared/agent-variant.test.d.ts +0 -1
- package/dist/shared/claude-config-dir.test.d.ts +0 -1
- package/dist/shared/deep-merge.test.d.ts +0 -1
- package/dist/shared/external-plugin-detector.test.d.ts +0 -1
- package/dist/shared/first-message-variant.test.d.ts +0 -1
- package/dist/shared/frontmatter.test.d.ts +0 -1
- package/dist/shared/jsonc-parser.test.d.ts +0 -1
- package/dist/shared/migration.test.d.ts +0 -1
- package/dist/shared/model-availability.test.d.ts +0 -1
- package/dist/shared/model-requirements.test.d.ts +0 -1
- package/dist/shared/model-resolver.test.d.ts +0 -1
- package/dist/shared/model-suggestion-retry.test.d.ts +0 -1
- package/dist/shared/opencode-config-dir.test.d.ts +0 -1
- package/dist/shared/opencode-version.test.d.ts +0 -1
- package/dist/shared/permission-compat.test.d.ts +0 -1
- package/dist/shared/session-cursor.test.d.ts +0 -1
- package/dist/shared/shell-env.test.d.ts +0 -1
- package/dist/shared/system-directive.test.d.ts +0 -1
- package/dist/shared/tmux/tmux-utils.test.d.ts +0 -1
- package/dist/tools/background-task/tools.test.d.ts +0 -1
- package/dist/tools/delegate-task/tools.test.d.ts +0 -1
- package/dist/tools/glob/cli.test.d.ts +0 -1
- package/dist/tools/grep/downloader.test.d.ts +0 -1
- package/dist/tools/look-at/tools.test.d.ts +0 -1
- package/dist/tools/lsp/config.test.d.ts +0 -1
- package/dist/tools/session-manager/storage.test.d.ts +0 -1
- package/dist/tools/session-manager/tools.test.d.ts +0 -1
- package/dist/tools/session-manager/utils.test.d.ts +0 -1
- package/dist/tools/skill/tools.test.d.ts +0 -1
- package/dist/tools/skill-mcp/tools.test.d.ts +0 -1
- package/dist/tools/slashcommand/tools.test.d.ts +0 -1
package/dist/cli/index.js
CHANGED
|
@@ -4892,7 +4892,35 @@ var init_logger = __esm(() => {
|
|
|
4892
4892
|
});
|
|
4893
4893
|
|
|
4894
4894
|
// src/shared/deep-merge.ts
|
|
4895
|
-
|
|
4895
|
+
function isPlainObject(value) {
|
|
4896
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) && Object.prototype.toString.call(value) === "[object Object]";
|
|
4897
|
+
}
|
|
4898
|
+
function deepMerge(base, override, depth = 0) {
|
|
4899
|
+
if (!base && !override)
|
|
4900
|
+
return;
|
|
4901
|
+
if (!base)
|
|
4902
|
+
return override;
|
|
4903
|
+
if (!override)
|
|
4904
|
+
return base;
|
|
4905
|
+
if (depth > MAX_DEPTH)
|
|
4906
|
+
return override ?? base;
|
|
4907
|
+
const result = { ...base };
|
|
4908
|
+
for (const key of Object.keys(override)) {
|
|
4909
|
+
if (DANGEROUS_KEYS.has(key))
|
|
4910
|
+
continue;
|
|
4911
|
+
const baseValue = base[key];
|
|
4912
|
+
const overrideValue = override[key];
|
|
4913
|
+
if (overrideValue === undefined)
|
|
4914
|
+
continue;
|
|
4915
|
+
if (isPlainObject(baseValue) && isPlainObject(overrideValue)) {
|
|
4916
|
+
result[key] = deepMerge(baseValue, overrideValue, depth + 1);
|
|
4917
|
+
} else {
|
|
4918
|
+
result[key] = overrideValue;
|
|
4919
|
+
}
|
|
4920
|
+
}
|
|
4921
|
+
return result;
|
|
4922
|
+
}
|
|
4923
|
+
var DANGEROUS_KEYS, MAX_DEPTH = 50;
|
|
4896
4924
|
var init_deep_merge = __esm(() => {
|
|
4897
4925
|
DANGEROUS_KEYS = new Set(["__proto__", "constructor", "prototype"]);
|
|
4898
4926
|
});
|
|
@@ -4940,6 +4968,9 @@ function getConfigLoadErrors() {
|
|
|
4940
4968
|
function clearConfigLoadErrors() {
|
|
4941
4969
|
configLoadErrors = [];
|
|
4942
4970
|
}
|
|
4971
|
+
function addConfigLoadError(error) {
|
|
4972
|
+
configLoadErrors.push(error);
|
|
4973
|
+
}
|
|
4943
4974
|
var configLoadErrors;
|
|
4944
4975
|
var init_config_errors = __esm(() => {
|
|
4945
4976
|
configLoadErrors = [];
|
|
@@ -5842,9 +5873,127 @@ var init_jsonc_parser = __esm(() => {
|
|
|
5842
5873
|
});
|
|
5843
5874
|
|
|
5844
5875
|
// src/shared/migration.ts
|
|
5845
|
-
|
|
5876
|
+
import * as fs2 from "fs";
|
|
5877
|
+
function migrateAgentNames(agents) {
|
|
5878
|
+
const migrated = {};
|
|
5879
|
+
let changed = false;
|
|
5880
|
+
for (const [key, value] of Object.entries(agents)) {
|
|
5881
|
+
const newKey = AGENT_NAME_MAP[key.toLowerCase()] ?? AGENT_NAME_MAP[key] ?? key;
|
|
5882
|
+
if (newKey !== key) {
|
|
5883
|
+
changed = true;
|
|
5884
|
+
}
|
|
5885
|
+
migrated[newKey] = value;
|
|
5886
|
+
}
|
|
5887
|
+
return { migrated, changed };
|
|
5888
|
+
}
|
|
5889
|
+
function migrateHookNames(hooks) {
|
|
5890
|
+
const migrated = [];
|
|
5891
|
+
const removed = [];
|
|
5892
|
+
let changed = false;
|
|
5893
|
+
for (const hook of hooks) {
|
|
5894
|
+
const mapping = HOOK_NAME_MAP[hook];
|
|
5895
|
+
if (mapping === null) {
|
|
5896
|
+
removed.push(hook);
|
|
5897
|
+
changed = true;
|
|
5898
|
+
continue;
|
|
5899
|
+
}
|
|
5900
|
+
const newHook = mapping ?? hook;
|
|
5901
|
+
if (newHook !== hook) {
|
|
5902
|
+
changed = true;
|
|
5903
|
+
}
|
|
5904
|
+
migrated.push(newHook);
|
|
5905
|
+
}
|
|
5906
|
+
return { migrated, changed, removed };
|
|
5907
|
+
}
|
|
5908
|
+
function migrateConfigFile(configPath, rawConfig) {
|
|
5909
|
+
let needsWrite = false;
|
|
5910
|
+
if (rawConfig.agents && typeof rawConfig.agents === "object") {
|
|
5911
|
+
const { migrated, changed } = migrateAgentNames(rawConfig.agents);
|
|
5912
|
+
if (changed) {
|
|
5913
|
+
rawConfig.agents = migrated;
|
|
5914
|
+
needsWrite = true;
|
|
5915
|
+
}
|
|
5916
|
+
}
|
|
5917
|
+
if (rawConfig.omo_agent) {
|
|
5918
|
+
rawConfig.sisyphus_agent = rawConfig.omo_agent;
|
|
5919
|
+
delete rawConfig.omo_agent;
|
|
5920
|
+
needsWrite = true;
|
|
5921
|
+
}
|
|
5922
|
+
if (rawConfig.disabled_agents && Array.isArray(rawConfig.disabled_agents)) {
|
|
5923
|
+
const migrated = [];
|
|
5924
|
+
let changed = false;
|
|
5925
|
+
for (const agent of rawConfig.disabled_agents) {
|
|
5926
|
+
const newAgent = AGENT_NAME_MAP[agent.toLowerCase()] ?? AGENT_NAME_MAP[agent] ?? agent;
|
|
5927
|
+
if (newAgent !== agent) {
|
|
5928
|
+
changed = true;
|
|
5929
|
+
}
|
|
5930
|
+
migrated.push(newAgent);
|
|
5931
|
+
}
|
|
5932
|
+
if (changed) {
|
|
5933
|
+
rawConfig.disabled_agents = migrated;
|
|
5934
|
+
needsWrite = true;
|
|
5935
|
+
}
|
|
5936
|
+
}
|
|
5937
|
+
if (rawConfig.disabled_hooks && Array.isArray(rawConfig.disabled_hooks)) {
|
|
5938
|
+
const { migrated, changed, removed } = migrateHookNames(rawConfig.disabled_hooks);
|
|
5939
|
+
if (changed) {
|
|
5940
|
+
rawConfig.disabled_hooks = migrated;
|
|
5941
|
+
needsWrite = true;
|
|
5942
|
+
}
|
|
5943
|
+
if (removed.length > 0) {
|
|
5944
|
+
log(`Removed obsolete hooks from disabled_hooks: ${removed.join(", ")} (these hooks no longer exist in v3.0.0)`);
|
|
5945
|
+
}
|
|
5946
|
+
}
|
|
5947
|
+
if (rawConfig.experimental && typeof rawConfig.experimental === "object") {
|
|
5948
|
+
const exp = rawConfig.experimental;
|
|
5949
|
+
if ("task_system" in exp && exp.task_system !== undefined) {
|
|
5950
|
+
needsWrite = true;
|
|
5951
|
+
}
|
|
5952
|
+
}
|
|
5953
|
+
if (needsWrite) {
|
|
5954
|
+
try {
|
|
5955
|
+
const timestamp2 = new Date().toISOString().replace(/[:.]/g, "-");
|
|
5956
|
+
const backupPath = `${configPath}.bak.${timestamp2}`;
|
|
5957
|
+
fs2.copyFileSync(configPath, backupPath);
|
|
5958
|
+
fs2.writeFileSync(configPath, JSON.stringify(rawConfig, null, 2) + `
|
|
5959
|
+
`, "utf-8");
|
|
5960
|
+
log(`Migrated config file: ${configPath} (backup: ${backupPath})`);
|
|
5961
|
+
} catch (err) {
|
|
5962
|
+
log(`Failed to write migrated config to ${configPath}:`, err);
|
|
5963
|
+
}
|
|
5964
|
+
}
|
|
5965
|
+
return needsWrite;
|
|
5966
|
+
}
|
|
5967
|
+
var AGENT_NAME_MAP, BUILTIN_AGENT_NAMES, HOOK_NAME_MAP;
|
|
5846
5968
|
var init_migration = __esm(() => {
|
|
5847
5969
|
init_logger();
|
|
5970
|
+
AGENT_NAME_MAP = {
|
|
5971
|
+
omo: "sisyphus",
|
|
5972
|
+
OmO: "sisyphus",
|
|
5973
|
+
Sisyphus: "sisyphus",
|
|
5974
|
+
sisyphus: "sisyphus",
|
|
5975
|
+
"OmO-Plan": "prometheus",
|
|
5976
|
+
"omo-plan": "prometheus",
|
|
5977
|
+
"Planner-Sisyphus": "prometheus",
|
|
5978
|
+
"planner-sisyphus": "prometheus",
|
|
5979
|
+
"Prometheus (Planner)": "prometheus",
|
|
5980
|
+
prometheus: "prometheus",
|
|
5981
|
+
"orchestrator-sisyphus": "atlas",
|
|
5982
|
+
Atlas: "atlas",
|
|
5983
|
+
atlas: "atlas",
|
|
5984
|
+
"plan-consultant": "metis",
|
|
5985
|
+
"Metis (Plan Consultant)": "metis",
|
|
5986
|
+
metis: "metis",
|
|
5987
|
+
"Momus (Plan Reviewer)": "momus",
|
|
5988
|
+
momus: "momus",
|
|
5989
|
+
"Sisyphus-Junior": "sisyphus-junior",
|
|
5990
|
+
"sisyphus-junior": "sisyphus-junior",
|
|
5991
|
+
build: "build",
|
|
5992
|
+
oracle: "oracle",
|
|
5993
|
+
librarian: "librarian",
|
|
5994
|
+
explore: "explore",
|
|
5995
|
+
"multimodal-looker": "multimodal-looker"
|
|
5996
|
+
};
|
|
5848
5997
|
BUILTIN_AGENT_NAMES = new Set([
|
|
5849
5998
|
"sisyphus",
|
|
5850
5999
|
"oracle",
|
|
@@ -5857,6 +6006,11 @@ var init_migration = __esm(() => {
|
|
|
5857
6006
|
"atlas",
|
|
5858
6007
|
"build"
|
|
5859
6008
|
]);
|
|
6009
|
+
HOOK_NAME_MAP = {
|
|
6010
|
+
"anthropic-auto-compact": "anthropic-context-window-limit-recovery",
|
|
6011
|
+
"sisyphus-orchestrator": "atlas",
|
|
6012
|
+
"empty-message-sanitizer": null
|
|
6013
|
+
};
|
|
5860
6014
|
});
|
|
5861
6015
|
|
|
5862
6016
|
// src/shared/opencode-config-dir.ts
|
|
@@ -5991,8 +6145,8 @@ var init_model_requirements = __esm(() => {
|
|
|
5991
6145
|
},
|
|
5992
6146
|
explore: {
|
|
5993
6147
|
fallbackChain: [
|
|
6148
|
+
{ providers: ["github-copilot"], model: "grok-code-fast-1" },
|
|
5994
6149
|
{ providers: ["anthropic", "opencode"], model: "claude-haiku-4-5" },
|
|
5995
|
-
{ providers: ["github-copilot"], model: "gpt-5-mini" },
|
|
5996
6150
|
{ providers: ["opencode"], model: "gpt-5-nano" }
|
|
5997
6151
|
]
|
|
5998
6152
|
},
|
|
@@ -6122,7 +6276,7 @@ var init_system_directive = () => {};
|
|
|
6122
6276
|
var init_agent_tool_restrictions = () => {};
|
|
6123
6277
|
|
|
6124
6278
|
// src/shared/connected-providers-cache.ts
|
|
6125
|
-
import { existsSync as existsSync3, readFileSync as readFileSync2, writeFileSync, mkdirSync } from "fs";
|
|
6279
|
+
import { existsSync as existsSync3, readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync } from "fs";
|
|
6126
6280
|
import { join as join4 } from "path";
|
|
6127
6281
|
function getCacheFilePath(filename) {
|
|
6128
6282
|
return join4(getOmoOpenCodeCacheDir(), filename);
|
|
@@ -6145,7 +6299,7 @@ function writeConnectedProvidersCache(connected) {
|
|
|
6145
6299
|
updatedAt: new Date().toISOString()
|
|
6146
6300
|
};
|
|
6147
6301
|
try {
|
|
6148
|
-
|
|
6302
|
+
writeFileSync2(cacheFile, JSON.stringify(data, null, 2));
|
|
6149
6303
|
log("[connected-providers-cache] Cache written", { count: connected.length });
|
|
6150
6304
|
} catch (err) {
|
|
6151
6305
|
log("[connected-providers-cache] Error writing cache", { error: String(err) });
|
|
@@ -6163,7 +6317,7 @@ function writeProviderModelsCache(data) {
|
|
|
6163
6317
|
updatedAt: new Date().toISOString()
|
|
6164
6318
|
};
|
|
6165
6319
|
try {
|
|
6166
|
-
|
|
6320
|
+
writeFileSync2(cacheFile, JSON.stringify(cacheData, null, 2));
|
|
6167
6321
|
log("[connected-providers-cache] Provider-models cache written", {
|
|
6168
6322
|
providerCount: Object.keys(data.models).length
|
|
6169
6323
|
});
|
|
@@ -6359,7 +6513,7 @@ function isProviderAvailable(provider, avail) {
|
|
|
6359
6513
|
}
|
|
6360
6514
|
function transformModelForProvider(provider, model) {
|
|
6361
6515
|
if (provider === "github-copilot") {
|
|
6362
|
-
return model.replace("claude-opus-4-5", "claude-opus-4.5").replace("claude-sonnet-4-5", "claude-sonnet-4.5").replace("claude-haiku-4-5", "claude-haiku-4.5").replace("claude-sonnet-4", "claude-sonnet-4");
|
|
6516
|
+
return model.replace("claude-opus-4-5", "claude-opus-4.5").replace("claude-sonnet-4-5", "claude-sonnet-4.5").replace("claude-haiku-4-5", "claude-haiku-4.5").replace("claude-sonnet-4", "claude-sonnet-4").replace("gemini-3-pro", "gemini-3-pro-preview").replace("gemini-3-flash", "gemini-3-flash-preview");
|
|
6363
6517
|
}
|
|
6364
6518
|
return model;
|
|
6365
6519
|
}
|
|
@@ -6466,7 +6620,7 @@ var init_model_fallback = __esm(() => {
|
|
|
6466
6620
|
});
|
|
6467
6621
|
|
|
6468
6622
|
// src/cli/config-manager.ts
|
|
6469
|
-
import { existsSync as existsSync5, mkdirSync as mkdirSync2, readFileSync as readFileSync4, writeFileSync as
|
|
6623
|
+
import { existsSync as existsSync5, mkdirSync as mkdirSync2, readFileSync as readFileSync4, writeFileSync as writeFileSync3, statSync } from "fs";
|
|
6470
6624
|
function initConfigContext(binary2, version) {
|
|
6471
6625
|
const paths = getOpenCodeConfigPaths({ binary: binary2, version });
|
|
6472
6626
|
configContext = { binary: binary2, version, paths };
|
|
@@ -6606,7 +6760,7 @@ async function addPluginToOpenCodeConfig(currentVersion) {
|
|
|
6606
6760
|
try {
|
|
6607
6761
|
if (format2 === "none") {
|
|
6608
6762
|
const config2 = { plugin: [pluginEntry] };
|
|
6609
|
-
|
|
6763
|
+
writeFileSync3(path3, JSON.stringify(config2, null, 2) + `
|
|
6610
6764
|
`);
|
|
6611
6765
|
return { success: true, configPath: path3 };
|
|
6612
6766
|
}
|
|
@@ -6636,14 +6790,14 @@ async function addPluginToOpenCodeConfig(currentVersion) {
|
|
|
6636
6790
|
const newContent = content.replace(pluginArrayRegex, `"plugin": [
|
|
6637
6791
|
${formattedPlugins}
|
|
6638
6792
|
]`);
|
|
6639
|
-
|
|
6793
|
+
writeFileSync3(path3, newContent);
|
|
6640
6794
|
} else {
|
|
6641
6795
|
const newContent = content.replace(/^(\s*\{)/, `$1
|
|
6642
6796
|
"plugin": ["${pluginEntry}"],`);
|
|
6643
|
-
|
|
6797
|
+
writeFileSync3(path3, newContent);
|
|
6644
6798
|
}
|
|
6645
6799
|
} else {
|
|
6646
|
-
|
|
6800
|
+
writeFileSync3(path3, JSON.stringify(config, null, 2) + `
|
|
6647
6801
|
`);
|
|
6648
6802
|
}
|
|
6649
6803
|
return { success: true, configPath: path3 };
|
|
@@ -6651,13 +6805,13 @@ async function addPluginToOpenCodeConfig(currentVersion) {
|
|
|
6651
6805
|
return { success: false, configPath: path3, error: formatErrorWithSuggestion(err, "update opencode config") };
|
|
6652
6806
|
}
|
|
6653
6807
|
}
|
|
6654
|
-
function
|
|
6808
|
+
function deepMerge2(target, source) {
|
|
6655
6809
|
const result = { ...target };
|
|
6656
6810
|
for (const key of Object.keys(source)) {
|
|
6657
6811
|
const sourceValue = source[key];
|
|
6658
6812
|
const targetValue = result[key];
|
|
6659
6813
|
if (sourceValue !== null && typeof sourceValue === "object" && !Array.isArray(sourceValue) && targetValue !== null && typeof targetValue === "object" && !Array.isArray(targetValue)) {
|
|
6660
|
-
result[key] =
|
|
6814
|
+
result[key] = deepMerge2(targetValue, sourceValue);
|
|
6661
6815
|
} else if (sourceValue !== undefined) {
|
|
6662
6816
|
result[key] = sourceValue;
|
|
6663
6817
|
}
|
|
@@ -6681,29 +6835,29 @@ function writeOmoConfig(installConfig) {
|
|
|
6681
6835
|
const stat = statSync(omoConfigPath);
|
|
6682
6836
|
const content = readFileSync4(omoConfigPath, "utf-8");
|
|
6683
6837
|
if (stat.size === 0 || isEmptyOrWhitespace(content)) {
|
|
6684
|
-
|
|
6838
|
+
writeFileSync3(omoConfigPath, JSON.stringify(newConfig, null, 2) + `
|
|
6685
6839
|
`);
|
|
6686
6840
|
return { success: true, configPath: omoConfigPath };
|
|
6687
6841
|
}
|
|
6688
6842
|
const existing = parseJsonc(content);
|
|
6689
6843
|
if (!existing || typeof existing !== "object" || Array.isArray(existing)) {
|
|
6690
|
-
|
|
6844
|
+
writeFileSync3(omoConfigPath, JSON.stringify(newConfig, null, 2) + `
|
|
6691
6845
|
`);
|
|
6692
6846
|
return { success: true, configPath: omoConfigPath };
|
|
6693
6847
|
}
|
|
6694
|
-
const merged =
|
|
6695
|
-
|
|
6848
|
+
const merged = deepMerge2(existing, newConfig);
|
|
6849
|
+
writeFileSync3(omoConfigPath, JSON.stringify(merged, null, 2) + `
|
|
6696
6850
|
`);
|
|
6697
6851
|
} catch (parseErr) {
|
|
6698
6852
|
if (parseErr instanceof SyntaxError) {
|
|
6699
|
-
|
|
6853
|
+
writeFileSync3(omoConfigPath, JSON.stringify(newConfig, null, 2) + `
|
|
6700
6854
|
`);
|
|
6701
6855
|
return { success: true, configPath: omoConfigPath };
|
|
6702
6856
|
}
|
|
6703
6857
|
throw parseErr;
|
|
6704
6858
|
}
|
|
6705
6859
|
} else {
|
|
6706
|
-
|
|
6860
|
+
writeFileSync3(omoConfigPath, JSON.stringify(newConfig, null, 2) + `
|
|
6707
6861
|
`);
|
|
6708
6862
|
}
|
|
6709
6863
|
return { success: true, configPath: omoConfigPath };
|
|
@@ -6765,7 +6919,7 @@ async function addAuthPlugins(config) {
|
|
|
6765
6919
|
}
|
|
6766
6920
|
}
|
|
6767
6921
|
const newConfig = { ...existingConfig ?? {}, plugin: plugins };
|
|
6768
|
-
|
|
6922
|
+
writeFileSync3(path3, JSON.stringify(newConfig, null, 2) + `
|
|
6769
6923
|
`);
|
|
6770
6924
|
return { success: true, configPath: path3 };
|
|
6771
6925
|
} catch (err) {
|
|
@@ -6837,7 +6991,7 @@ function addProviderConfig(config) {
|
|
|
6837
6991
|
if (Object.keys(providers).length > 0) {
|
|
6838
6992
|
newConfig.provider = providers;
|
|
6839
6993
|
}
|
|
6840
|
-
|
|
6994
|
+
writeFileSync3(path3, JSON.stringify(newConfig, null, 2) + `
|
|
6841
6995
|
`);
|
|
6842
6996
|
return { success: true, configPath: path3 };
|
|
6843
6997
|
} catch (err) {
|
|
@@ -6959,43 +7113,43 @@ var init_config_manager = __esm(() => {
|
|
|
6959
7113
|
});
|
|
6960
7114
|
|
|
6961
7115
|
// src/hooks/auto-update-checker/constants.ts
|
|
6962
|
-
import * as
|
|
7116
|
+
import * as path4 from "path";
|
|
6963
7117
|
import * as os3 from "os";
|
|
6964
7118
|
function getCacheDir2() {
|
|
6965
7119
|
if (process.platform === "win32") {
|
|
6966
|
-
return
|
|
7120
|
+
return path4.join(process.env.LOCALAPPDATA ?? os3.homedir(), "opencode");
|
|
6967
7121
|
}
|
|
6968
|
-
return
|
|
7122
|
+
return path4.join(os3.homedir(), ".cache", "opencode");
|
|
6969
7123
|
}
|
|
6970
7124
|
function getWindowsAppdataDir() {
|
|
6971
7125
|
if (process.platform !== "win32")
|
|
6972
7126
|
return null;
|
|
6973
|
-
return process.env.APPDATA ??
|
|
7127
|
+
return process.env.APPDATA ?? path4.join(os3.homedir(), "AppData", "Roaming");
|
|
6974
7128
|
}
|
|
6975
7129
|
var PACKAGE_NAME2 = "oh-my-opencode", NPM_REGISTRY_URL, NPM_FETCH_TIMEOUT = 5000, CACHE_DIR, VERSION_FILE, INSTALLED_PACKAGE_JSON, USER_CONFIG_DIR, USER_OPENCODE_CONFIG, USER_OPENCODE_CONFIG_JSONC;
|
|
6976
7130
|
var init_constants3 = __esm(() => {
|
|
6977
7131
|
init_shared();
|
|
6978
7132
|
NPM_REGISTRY_URL = `https://registry.npmjs.org/-/package/${PACKAGE_NAME2}/dist-tags`;
|
|
6979
7133
|
CACHE_DIR = getCacheDir2();
|
|
6980
|
-
VERSION_FILE =
|
|
6981
|
-
INSTALLED_PACKAGE_JSON =
|
|
7134
|
+
VERSION_FILE = path4.join(CACHE_DIR, "version");
|
|
7135
|
+
INSTALLED_PACKAGE_JSON = path4.join(CACHE_DIR, "node_modules", PACKAGE_NAME2, "package.json");
|
|
6982
7136
|
USER_CONFIG_DIR = getOpenCodeConfigDir({ binary: "opencode" });
|
|
6983
|
-
USER_OPENCODE_CONFIG =
|
|
6984
|
-
USER_OPENCODE_CONFIG_JSONC =
|
|
7137
|
+
USER_OPENCODE_CONFIG = path4.join(USER_CONFIG_DIR, "opencode.json");
|
|
7138
|
+
USER_OPENCODE_CONFIG_JSONC = path4.join(USER_CONFIG_DIR, "opencode.jsonc");
|
|
6985
7139
|
});
|
|
6986
7140
|
|
|
6987
7141
|
// src/hooks/auto-update-checker/cache.ts
|
|
6988
|
-
import * as
|
|
6989
|
-
import * as
|
|
6990
|
-
function stripTrailingCommas(
|
|
6991
|
-
return
|
|
7142
|
+
import * as fs4 from "fs";
|
|
7143
|
+
import * as path5 from "path";
|
|
7144
|
+
function stripTrailingCommas(json3) {
|
|
7145
|
+
return json3.replace(/,(\s*[}\]])/g, "$1");
|
|
6992
7146
|
}
|
|
6993
7147
|
function removeFromBunLock(packageName) {
|
|
6994
|
-
const lockPath =
|
|
6995
|
-
if (!
|
|
7148
|
+
const lockPath = path5.join(CACHE_DIR, "bun.lock");
|
|
7149
|
+
if (!fs4.existsSync(lockPath))
|
|
6996
7150
|
return false;
|
|
6997
7151
|
try {
|
|
6998
|
-
const content =
|
|
7152
|
+
const content = fs4.readFileSync(lockPath, "utf-8");
|
|
6999
7153
|
const lock = JSON.parse(stripTrailingCommas(content));
|
|
7000
7154
|
let modified = false;
|
|
7001
7155
|
if (lock.workspaces?.[""]?.dependencies?.[packageName]) {
|
|
@@ -7007,7 +7161,7 @@ function removeFromBunLock(packageName) {
|
|
|
7007
7161
|
modified = true;
|
|
7008
7162
|
}
|
|
7009
7163
|
if (modified) {
|
|
7010
|
-
|
|
7164
|
+
fs4.writeFileSync(lockPath, JSON.stringify(lock, null, 2));
|
|
7011
7165
|
log(`[auto-update-checker] Removed from bun.lock: ${packageName}`);
|
|
7012
7166
|
}
|
|
7013
7167
|
return modified;
|
|
@@ -7017,22 +7171,22 @@ function removeFromBunLock(packageName) {
|
|
|
7017
7171
|
}
|
|
7018
7172
|
function invalidatePackage(packageName = PACKAGE_NAME2) {
|
|
7019
7173
|
try {
|
|
7020
|
-
const pkgDir =
|
|
7021
|
-
const pkgJsonPath =
|
|
7174
|
+
const pkgDir = path5.join(CACHE_DIR, "node_modules", packageName);
|
|
7175
|
+
const pkgJsonPath = path5.join(CACHE_DIR, "package.json");
|
|
7022
7176
|
let packageRemoved = false;
|
|
7023
7177
|
let dependencyRemoved = false;
|
|
7024
7178
|
let lockRemoved = false;
|
|
7025
|
-
if (
|
|
7026
|
-
|
|
7179
|
+
if (fs4.existsSync(pkgDir)) {
|
|
7180
|
+
fs4.rmSync(pkgDir, { recursive: true, force: true });
|
|
7027
7181
|
log(`[auto-update-checker] Package removed: ${pkgDir}`);
|
|
7028
7182
|
packageRemoved = true;
|
|
7029
7183
|
}
|
|
7030
|
-
if (
|
|
7031
|
-
const content =
|
|
7184
|
+
if (fs4.existsSync(pkgJsonPath)) {
|
|
7185
|
+
const content = fs4.readFileSync(pkgJsonPath, "utf-8");
|
|
7032
7186
|
const pkgJson = JSON.parse(content);
|
|
7033
7187
|
if (pkgJson.dependencies?.[packageName]) {
|
|
7034
7188
|
delete pkgJson.dependencies[packageName];
|
|
7035
|
-
|
|
7189
|
+
fs4.writeFileSync(pkgJsonPath, JSON.stringify(pkgJson, null, 2));
|
|
7036
7190
|
log(`[auto-update-checker] Dependency removed from package.json: ${packageName}`);
|
|
7037
7191
|
dependencyRemoved = true;
|
|
7038
7192
|
}
|
|
@@ -7069,11 +7223,11 @@ __export(exports_auto_update_checker, {
|
|
|
7069
7223
|
createAutoUpdateCheckerHook: () => createAutoUpdateCheckerHook,
|
|
7070
7224
|
checkForUpdate: () => checkForUpdate
|
|
7071
7225
|
});
|
|
7072
|
-
function isPrereleaseVersion(
|
|
7073
|
-
return
|
|
7226
|
+
function isPrereleaseVersion(version2) {
|
|
7227
|
+
return version2.includes("-");
|
|
7074
7228
|
}
|
|
7075
|
-
function isDistTag(
|
|
7076
|
-
const startsWithDigit = /^\d/.test(
|
|
7229
|
+
function isDistTag(version2) {
|
|
7230
|
+
const startsWithDigit = /^\d/.test(version2);
|
|
7077
7231
|
return !startsWithDigit;
|
|
7078
7232
|
}
|
|
7079
7233
|
function isPrereleaseOrDistTag(pinnedVersion) {
|
|
@@ -7081,14 +7235,14 @@ function isPrereleaseOrDistTag(pinnedVersion) {
|
|
|
7081
7235
|
return false;
|
|
7082
7236
|
return isPrereleaseVersion(pinnedVersion) || isDistTag(pinnedVersion);
|
|
7083
7237
|
}
|
|
7084
|
-
function extractChannel(
|
|
7085
|
-
if (!
|
|
7238
|
+
function extractChannel(version2) {
|
|
7239
|
+
if (!version2)
|
|
7086
7240
|
return "latest";
|
|
7087
|
-
if (isDistTag(
|
|
7088
|
-
return
|
|
7241
|
+
if (isDistTag(version2)) {
|
|
7242
|
+
return version2;
|
|
7089
7243
|
}
|
|
7090
|
-
if (isPrereleaseVersion(
|
|
7091
|
-
const prereleasePart =
|
|
7244
|
+
if (isPrereleaseVersion(version2)) {
|
|
7245
|
+
const prereleasePart = version2.split("-")[1];
|
|
7092
7246
|
if (prereleasePart) {
|
|
7093
7247
|
const channelMatch = prereleasePart.match(/^(alpha|beta|rc|canary|next)/);
|
|
7094
7248
|
if (channelMatch) {
|
|
@@ -7230,10 +7384,10 @@ async function updateAndShowConnectedProvidersCacheStatus(ctx) {
|
|
|
7230
7384
|
}
|
|
7231
7385
|
}
|
|
7232
7386
|
async function showConfigErrorsIfAny(ctx) {
|
|
7233
|
-
const
|
|
7234
|
-
if (
|
|
7387
|
+
const errors3 = getConfigLoadErrors();
|
|
7388
|
+
if (errors3.length === 0)
|
|
7235
7389
|
return;
|
|
7236
|
-
const errorMessages =
|
|
7390
|
+
const errorMessages = errors3.map((e2) => `${e2.path}: ${e2.error}`).join(`
|
|
7237
7391
|
`);
|
|
7238
7392
|
await ctx.client.tui.showToast({
|
|
7239
7393
|
body: {
|
|
@@ -7244,15 +7398,15 @@ ${errorMessages}`,
|
|
|
7244
7398
|
duration: 1e4
|
|
7245
7399
|
}
|
|
7246
7400
|
}).catch(() => {});
|
|
7247
|
-
log(`[auto-update-checker] Config load errors shown: ${
|
|
7401
|
+
log(`[auto-update-checker] Config load errors shown: ${errors3.length} error(s)`);
|
|
7248
7402
|
clearConfigLoadErrors();
|
|
7249
7403
|
}
|
|
7250
|
-
async function showVersionToast(ctx,
|
|
7251
|
-
const displayVersion =
|
|
7404
|
+
async function showVersionToast(ctx, version2, message) {
|
|
7405
|
+
const displayVersion = version2 ?? "unknown";
|
|
7252
7406
|
await showSpinnerToast(ctx, displayVersion, message);
|
|
7253
7407
|
log(`[auto-update-checker] Startup toast shown: v${displayVersion}`);
|
|
7254
7408
|
}
|
|
7255
|
-
async function showSpinnerToast(ctx,
|
|
7409
|
+
async function showSpinnerToast(ctx, version2, message) {
|
|
7256
7410
|
const totalDuration = 5000;
|
|
7257
7411
|
const frameInterval = 100;
|
|
7258
7412
|
const totalFrames = Math.floor(totalDuration / frameInterval);
|
|
@@ -7260,7 +7414,7 @@ async function showSpinnerToast(ctx, version, message) {
|
|
|
7260
7414
|
const spinner = SISYPHUS_SPINNER[i2 % SISYPHUS_SPINNER.length];
|
|
7261
7415
|
await ctx.client.tui.showToast({
|
|
7262
7416
|
body: {
|
|
7263
|
-
title: `${spinner} OhMyOpenCode ${
|
|
7417
|
+
title: `${spinner} OhMyOpenCode ${version2}`,
|
|
7264
7418
|
message,
|
|
7265
7419
|
variant: "info",
|
|
7266
7420
|
duration: frameInterval + 50
|
|
@@ -7292,8 +7446,8 @@ Restart OpenCode to apply.`,
|
|
|
7292
7446
|
}).catch(() => {});
|
|
7293
7447
|
log(`[auto-update-checker] Auto-updated toast shown: v${oldVersion} \u2192 v${newVersion}`);
|
|
7294
7448
|
}
|
|
7295
|
-
async function showLocalDevToast(ctx,
|
|
7296
|
-
const displayVersion =
|
|
7449
|
+
async function showLocalDevToast(ctx, version2, isSisyphusEnabled) {
|
|
7450
|
+
const displayVersion = version2 ?? "dev";
|
|
7297
7451
|
const message = isSisyphusEnabled ? "Sisyphus running in local development mode." : "Running in local development mode. oMoMoMo...";
|
|
7298
7452
|
await showSpinnerToast(ctx, `${displayVersion} (dev)`, message);
|
|
7299
7453
|
log(`[auto-update-checker] Local dev toast shown: v${displayVersion}`);
|
|
@@ -7314,30 +7468,30 @@ var init_auto_update_checker = __esm(() => {
|
|
|
7314
7468
|
});
|
|
7315
7469
|
|
|
7316
7470
|
// src/hooks/auto-update-checker/checker.ts
|
|
7317
|
-
import * as
|
|
7318
|
-
import * as
|
|
7471
|
+
import * as fs5 from "fs";
|
|
7472
|
+
import * as path6 from "path";
|
|
7319
7473
|
import { fileURLToPath } from "url";
|
|
7320
7474
|
import * as os4 from "os";
|
|
7321
7475
|
function isLocalDevMode(directory) {
|
|
7322
7476
|
return getLocalDevPath(directory) !== null;
|
|
7323
7477
|
}
|
|
7324
|
-
function stripJsonComments(
|
|
7325
|
-
return
|
|
7478
|
+
function stripJsonComments(json3) {
|
|
7479
|
+
return json3.replace(/\\"|"(?:\\"|[^"])*"|(\/\/.*|\/\*[\s\S]*?\*\/)/g, (m2, g2) => g2 ? "" : m2).replace(/,(\s*[}\]])/g, "$1");
|
|
7326
7480
|
}
|
|
7327
7481
|
function getConfigPaths(directory) {
|
|
7328
7482
|
const paths = [
|
|
7329
|
-
|
|
7330
|
-
|
|
7483
|
+
path6.join(directory, ".opencode", "opencode.json"),
|
|
7484
|
+
path6.join(directory, ".opencode", "opencode.jsonc"),
|
|
7331
7485
|
USER_OPENCODE_CONFIG,
|
|
7332
7486
|
USER_OPENCODE_CONFIG_JSONC
|
|
7333
7487
|
];
|
|
7334
7488
|
if (process.platform === "win32") {
|
|
7335
|
-
const crossPlatformDir =
|
|
7489
|
+
const crossPlatformDir = path6.join(os4.homedir(), ".config");
|
|
7336
7490
|
const appdataDir = getWindowsAppdataDir();
|
|
7337
7491
|
if (appdataDir) {
|
|
7338
7492
|
const alternateDir = USER_CONFIG_DIR === crossPlatformDir ? appdataDir : crossPlatformDir;
|
|
7339
|
-
const alternateConfig =
|
|
7340
|
-
const alternateConfigJsonc =
|
|
7493
|
+
const alternateConfig = path6.join(alternateDir, "opencode", "opencode.json");
|
|
7494
|
+
const alternateConfigJsonc = path6.join(alternateDir, "opencode", "opencode.jsonc");
|
|
7341
7495
|
if (!paths.includes(alternateConfig)) {
|
|
7342
7496
|
paths.push(alternateConfig);
|
|
7343
7497
|
}
|
|
@@ -7351,11 +7505,11 @@ function getConfigPaths(directory) {
|
|
|
7351
7505
|
function getLocalDevPath(directory) {
|
|
7352
7506
|
for (const configPath of getConfigPaths(directory)) {
|
|
7353
7507
|
try {
|
|
7354
|
-
if (!
|
|
7508
|
+
if (!fs5.existsSync(configPath))
|
|
7355
7509
|
continue;
|
|
7356
|
-
const content =
|
|
7357
|
-
const
|
|
7358
|
-
const plugins =
|
|
7510
|
+
const content = fs5.readFileSync(configPath, "utf-8");
|
|
7511
|
+
const config2 = JSON.parse(stripJsonComments(content));
|
|
7512
|
+
const plugins = config2.plugin ?? [];
|
|
7359
7513
|
for (const entry of plugins) {
|
|
7360
7514
|
if (entry.startsWith("file://") && entry.includes(PACKAGE_NAME2)) {
|
|
7361
7515
|
try {
|
|
@@ -7373,19 +7527,19 @@ function getLocalDevPath(directory) {
|
|
|
7373
7527
|
}
|
|
7374
7528
|
function findPackageJsonUp(startPath) {
|
|
7375
7529
|
try {
|
|
7376
|
-
const stat =
|
|
7377
|
-
let dir = stat.isDirectory() ? startPath :
|
|
7530
|
+
const stat = fs5.statSync(startPath);
|
|
7531
|
+
let dir = stat.isDirectory() ? startPath : path6.dirname(startPath);
|
|
7378
7532
|
for (let i2 = 0;i2 < 10; i2++) {
|
|
7379
|
-
const pkgPath =
|
|
7380
|
-
if (
|
|
7533
|
+
const pkgPath = path6.join(dir, "package.json");
|
|
7534
|
+
if (fs5.existsSync(pkgPath)) {
|
|
7381
7535
|
try {
|
|
7382
|
-
const content =
|
|
7536
|
+
const content = fs5.readFileSync(pkgPath, "utf-8");
|
|
7383
7537
|
const pkg = JSON.parse(content);
|
|
7384
7538
|
if (pkg.name === PACKAGE_NAME2)
|
|
7385
7539
|
return pkgPath;
|
|
7386
7540
|
} catch {}
|
|
7387
7541
|
}
|
|
7388
|
-
const parent =
|
|
7542
|
+
const parent = path6.dirname(dir);
|
|
7389
7543
|
if (parent === dir)
|
|
7390
7544
|
break;
|
|
7391
7545
|
dir = parent;
|
|
@@ -7401,7 +7555,7 @@ function getLocalDevVersion(directory) {
|
|
|
7401
7555
|
const pkgPath = findPackageJsonUp(localPath);
|
|
7402
7556
|
if (!pkgPath)
|
|
7403
7557
|
return null;
|
|
7404
|
-
const content =
|
|
7558
|
+
const content = fs5.readFileSync(pkgPath, "utf-8");
|
|
7405
7559
|
const pkg = JSON.parse(content);
|
|
7406
7560
|
return pkg.version ?? null;
|
|
7407
7561
|
} catch {
|
|
@@ -7411,11 +7565,11 @@ function getLocalDevVersion(directory) {
|
|
|
7411
7565
|
function findPluginEntry(directory) {
|
|
7412
7566
|
for (const configPath of getConfigPaths(directory)) {
|
|
7413
7567
|
try {
|
|
7414
|
-
if (!
|
|
7568
|
+
if (!fs5.existsSync(configPath))
|
|
7415
7569
|
continue;
|
|
7416
|
-
const content =
|
|
7417
|
-
const
|
|
7418
|
-
const plugins =
|
|
7570
|
+
const content = fs5.readFileSync(configPath, "utf-8");
|
|
7571
|
+
const config2 = JSON.parse(stripJsonComments(content));
|
|
7572
|
+
const plugins = config2.plugin ?? [];
|
|
7419
7573
|
for (const entry of plugins) {
|
|
7420
7574
|
if (entry === PACKAGE_NAME2) {
|
|
7421
7575
|
return { entry, isPinned: false, pinnedVersion: null, configPath };
|
|
@@ -7434,18 +7588,18 @@ function findPluginEntry(directory) {
|
|
|
7434
7588
|
}
|
|
7435
7589
|
function getCachedVersion() {
|
|
7436
7590
|
try {
|
|
7437
|
-
if (
|
|
7438
|
-
const content =
|
|
7591
|
+
if (fs5.existsSync(INSTALLED_PACKAGE_JSON)) {
|
|
7592
|
+
const content = fs5.readFileSync(INSTALLED_PACKAGE_JSON, "utf-8");
|
|
7439
7593
|
const pkg = JSON.parse(content);
|
|
7440
7594
|
if (pkg.version)
|
|
7441
7595
|
return pkg.version;
|
|
7442
7596
|
}
|
|
7443
7597
|
} catch {}
|
|
7444
7598
|
try {
|
|
7445
|
-
const currentDir =
|
|
7599
|
+
const currentDir = path6.dirname(fileURLToPath(import.meta.url));
|
|
7446
7600
|
const pkgPath = findPackageJsonUp(currentDir);
|
|
7447
7601
|
if (pkgPath) {
|
|
7448
|
-
const content =
|
|
7602
|
+
const content = fs5.readFileSync(pkgPath, "utf-8");
|
|
7449
7603
|
const pkg = JSON.parse(content);
|
|
7450
7604
|
if (pkg.version)
|
|
7451
7605
|
return pkg.version;
|
|
@@ -7454,10 +7608,10 @@ function getCachedVersion() {
|
|
|
7454
7608
|
log("[auto-update-checker] Failed to resolve version from current directory:", err);
|
|
7455
7609
|
}
|
|
7456
7610
|
try {
|
|
7457
|
-
const execDir =
|
|
7611
|
+
const execDir = path6.dirname(fs5.realpathSync(process.execPath));
|
|
7458
7612
|
const pkgPath = findPackageJsonUp(execDir);
|
|
7459
7613
|
if (pkgPath) {
|
|
7460
|
-
const content =
|
|
7614
|
+
const content = fs5.readFileSync(pkgPath, "utf-8");
|
|
7461
7615
|
const pkg = JSON.parse(content);
|
|
7462
7616
|
if (pkg.version)
|
|
7463
7617
|
return pkg.version;
|
|
@@ -7469,7 +7623,7 @@ function getCachedVersion() {
|
|
|
7469
7623
|
}
|
|
7470
7624
|
function updatePinnedVersion(configPath, oldEntry, newVersion) {
|
|
7471
7625
|
try {
|
|
7472
|
-
const content =
|
|
7626
|
+
const content = fs5.readFileSync(configPath, "utf-8");
|
|
7473
7627
|
const newEntry = `${PACKAGE_NAME2}@${newVersion}`;
|
|
7474
7628
|
const pluginMatch = content.match(/"plugin"\s*:\s*\[/);
|
|
7475
7629
|
if (!pluginMatch || pluginMatch.index === undefined) {
|
|
@@ -7501,7 +7655,7 @@ function updatePinnedVersion(configPath, oldEntry, newVersion) {
|
|
|
7501
7655
|
log(`[auto-update-checker] No changes made to ${configPath}`);
|
|
7502
7656
|
return false;
|
|
7503
7657
|
}
|
|
7504
|
-
|
|
7658
|
+
fs5.writeFileSync(configPath, updatedContent, "utf-8");
|
|
7505
7659
|
log(`[auto-update-checker] Updated ${configPath}: ${oldEntry} \u2192 ${newEntry}`);
|
|
7506
7660
|
return true;
|
|
7507
7661
|
} catch (err) {
|
|
@@ -8160,7 +8314,7 @@ var import_picocolors2 = __toESM(require_picocolors(), 1);
|
|
|
8160
8314
|
// package.json
|
|
8161
8315
|
var package_default = {
|
|
8162
8316
|
name: "oh-my-opencode",
|
|
8163
|
-
version: "3.2.
|
|
8317
|
+
version: "3.2.2",
|
|
8164
8318
|
description: "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
|
|
8165
8319
|
main: "dist/index.js",
|
|
8166
8320
|
types: "dist/index.d.ts",
|
|
@@ -8230,17 +8384,17 @@ var package_default = {
|
|
|
8230
8384
|
devDependencies: {
|
|
8231
8385
|
"@types/js-yaml": "^4.0.9",
|
|
8232
8386
|
"@types/picomatch": "^3.0.2",
|
|
8233
|
-
"bun-types": "
|
|
8387
|
+
"bun-types": "1.3.6",
|
|
8234
8388
|
typescript: "^5.7.3"
|
|
8235
8389
|
},
|
|
8236
8390
|
optionalDependencies: {
|
|
8237
|
-
"oh-my-opencode-darwin-arm64": "3.2.
|
|
8238
|
-
"oh-my-opencode-darwin-x64": "3.2.
|
|
8239
|
-
"oh-my-opencode-linux-arm64": "3.2.
|
|
8240
|
-
"oh-my-opencode-linux-arm64-musl": "3.2.
|
|
8241
|
-
"oh-my-opencode-linux-x64": "3.2.
|
|
8242
|
-
"oh-my-opencode-linux-x64-musl": "3.2.
|
|
8243
|
-
"oh-my-opencode-windows-x64": "3.2.
|
|
8391
|
+
"oh-my-opencode-darwin-arm64": "3.2.2",
|
|
8392
|
+
"oh-my-opencode-darwin-x64": "3.2.2",
|
|
8393
|
+
"oh-my-opencode-linux-arm64": "3.2.2",
|
|
8394
|
+
"oh-my-opencode-linux-arm64-musl": "3.2.2",
|
|
8395
|
+
"oh-my-opencode-linux-x64": "3.2.2",
|
|
8396
|
+
"oh-my-opencode-linux-x64-musl": "3.2.2",
|
|
8397
|
+
"oh-my-opencode-windows-x64": "3.2.2"
|
|
8244
8398
|
},
|
|
8245
8399
|
trustedDependencies: [
|
|
8246
8400
|
"@ast-grep/cli",
|
|
@@ -10421,649 +10575,9 @@ function handleToolResult(ctx, payload, state) {
|
|
|
10421
10575
|
state.lastPartText = "";
|
|
10422
10576
|
}
|
|
10423
10577
|
|
|
10424
|
-
// src/
|
|
10425
|
-
|
|
10426
|
-
|
|
10427
|
-
var SESSION_CREATE_MAX_RETRIES = 3;
|
|
10428
|
-
var SESSION_CREATE_RETRY_DELAY_MS = 1000;
|
|
10429
|
-
async function run(options) {
|
|
10430
|
-
const {
|
|
10431
|
-
message,
|
|
10432
|
-
agent,
|
|
10433
|
-
directory = process.cwd(),
|
|
10434
|
-
timeout = DEFAULT_TIMEOUT_MS
|
|
10435
|
-
} = options;
|
|
10436
|
-
console.log(import_picocolors5.default.cyan("Starting opencode server..."));
|
|
10437
|
-
const abortController = new AbortController;
|
|
10438
|
-
let timeoutId = null;
|
|
10439
|
-
if (timeout > 0) {
|
|
10440
|
-
timeoutId = setTimeout(() => {
|
|
10441
|
-
console.log(import_picocolors5.default.yellow(`
|
|
10442
|
-
Timeout reached. Aborting...`));
|
|
10443
|
-
abortController.abort();
|
|
10444
|
-
}, timeout);
|
|
10445
|
-
}
|
|
10446
|
-
try {
|
|
10447
|
-
const serverPort = process.env.OPENCODE_SERVER_PORT ? parseInt(process.env.OPENCODE_SERVER_PORT, 10) : undefined;
|
|
10448
|
-
const serverHostname = process.env.OPENCODE_SERVER_HOSTNAME || undefined;
|
|
10449
|
-
const { client: client3, server: server2 } = await createOpencode({
|
|
10450
|
-
signal: abortController.signal,
|
|
10451
|
-
...serverPort && !isNaN(serverPort) ? { port: serverPort } : {},
|
|
10452
|
-
...serverHostname ? { hostname: serverHostname } : {}
|
|
10453
|
-
});
|
|
10454
|
-
const cleanup = () => {
|
|
10455
|
-
if (timeoutId)
|
|
10456
|
-
clearTimeout(timeoutId);
|
|
10457
|
-
server2.close();
|
|
10458
|
-
};
|
|
10459
|
-
process.on("SIGINT", () => {
|
|
10460
|
-
console.log(import_picocolors5.default.yellow(`
|
|
10461
|
-
Interrupted. Shutting down...`));
|
|
10462
|
-
cleanup();
|
|
10463
|
-
process.exit(130);
|
|
10464
|
-
});
|
|
10465
|
-
try {
|
|
10466
|
-
let sessionID;
|
|
10467
|
-
let lastError;
|
|
10468
|
-
for (let attempt = 1;attempt <= SESSION_CREATE_MAX_RETRIES; attempt++) {
|
|
10469
|
-
const sessionRes = await client3.session.create({
|
|
10470
|
-
body: { title: "oh-my-opencode run" }
|
|
10471
|
-
});
|
|
10472
|
-
if (sessionRes.error) {
|
|
10473
|
-
lastError = sessionRes.error;
|
|
10474
|
-
console.error(import_picocolors5.default.yellow(`Session create attempt ${attempt}/${SESSION_CREATE_MAX_RETRIES} failed:`));
|
|
10475
|
-
console.error(import_picocolors5.default.dim(` Error: ${serializeError(sessionRes.error)}`));
|
|
10476
|
-
if (attempt < SESSION_CREATE_MAX_RETRIES) {
|
|
10477
|
-
const delay = SESSION_CREATE_RETRY_DELAY_MS * attempt;
|
|
10478
|
-
console.log(import_picocolors5.default.dim(` Retrying in ${delay}ms...`));
|
|
10479
|
-
await new Promise((resolve2) => setTimeout(resolve2, delay));
|
|
10480
|
-
continue;
|
|
10481
|
-
}
|
|
10482
|
-
}
|
|
10483
|
-
sessionID = sessionRes.data?.id;
|
|
10484
|
-
if (sessionID) {
|
|
10485
|
-
break;
|
|
10486
|
-
}
|
|
10487
|
-
lastError = new Error(`Unexpected response: ${JSON.stringify(sessionRes, null, 2)}`);
|
|
10488
|
-
console.error(import_picocolors5.default.yellow(`Session create attempt ${attempt}/${SESSION_CREATE_MAX_RETRIES}: No session ID returned`));
|
|
10489
|
-
if (attempt < SESSION_CREATE_MAX_RETRIES) {
|
|
10490
|
-
const delay = SESSION_CREATE_RETRY_DELAY_MS * attempt;
|
|
10491
|
-
console.log(import_picocolors5.default.dim(` Retrying in ${delay}ms...`));
|
|
10492
|
-
await new Promise((resolve2) => setTimeout(resolve2, delay));
|
|
10493
|
-
}
|
|
10494
|
-
}
|
|
10495
|
-
if (!sessionID) {
|
|
10496
|
-
console.error(import_picocolors5.default.red("Failed to create session after all retries"));
|
|
10497
|
-
console.error(import_picocolors5.default.dim(`Last error: ${serializeError(lastError)}`));
|
|
10498
|
-
cleanup();
|
|
10499
|
-
return 1;
|
|
10500
|
-
}
|
|
10501
|
-
console.log(import_picocolors5.default.dim(`Session: ${sessionID}`));
|
|
10502
|
-
const ctx = {
|
|
10503
|
-
client: client3,
|
|
10504
|
-
sessionID,
|
|
10505
|
-
directory,
|
|
10506
|
-
abortController
|
|
10507
|
-
};
|
|
10508
|
-
const events = await client3.event.subscribe();
|
|
10509
|
-
const eventState = createEventState();
|
|
10510
|
-
const eventProcessor = processEvents(ctx, events.stream, eventState);
|
|
10511
|
-
console.log(import_picocolors5.default.dim(`
|
|
10512
|
-
Sending prompt...`));
|
|
10513
|
-
await client3.session.promptAsync({
|
|
10514
|
-
path: { id: sessionID },
|
|
10515
|
-
body: {
|
|
10516
|
-
agent,
|
|
10517
|
-
parts: [{ type: "text", text: message }]
|
|
10518
|
-
},
|
|
10519
|
-
query: { directory }
|
|
10520
|
-
});
|
|
10521
|
-
console.log(import_picocolors5.default.dim(`Waiting for completion...
|
|
10522
|
-
`));
|
|
10523
|
-
while (!abortController.signal.aborted) {
|
|
10524
|
-
await new Promise((resolve2) => setTimeout(resolve2, POLL_INTERVAL_MS));
|
|
10525
|
-
if (!eventState.mainSessionIdle) {
|
|
10526
|
-
continue;
|
|
10527
|
-
}
|
|
10528
|
-
if (eventState.mainSessionError) {
|
|
10529
|
-
console.error(import_picocolors5.default.red(`
|
|
10530
|
-
|
|
10531
|
-
Session ended with error: ${eventState.lastError}`));
|
|
10532
|
-
console.error(import_picocolors5.default.yellow("Check if todos were completed before the error."));
|
|
10533
|
-
cleanup();
|
|
10534
|
-
process.exit(1);
|
|
10535
|
-
}
|
|
10536
|
-
if (!eventState.hasReceivedMeaningfulWork) {
|
|
10537
|
-
continue;
|
|
10538
|
-
}
|
|
10539
|
-
const shouldExit = await checkCompletionConditions(ctx);
|
|
10540
|
-
if (shouldExit) {
|
|
10541
|
-
console.log(import_picocolors5.default.green(`
|
|
10542
|
-
|
|
10543
|
-
All tasks completed.`));
|
|
10544
|
-
cleanup();
|
|
10545
|
-
process.exit(0);
|
|
10546
|
-
}
|
|
10547
|
-
}
|
|
10548
|
-
await eventProcessor.catch(() => {});
|
|
10549
|
-
cleanup();
|
|
10550
|
-
return 130;
|
|
10551
|
-
} catch (err) {
|
|
10552
|
-
cleanup();
|
|
10553
|
-
throw err;
|
|
10554
|
-
}
|
|
10555
|
-
} catch (err) {
|
|
10556
|
-
if (timeoutId)
|
|
10557
|
-
clearTimeout(timeoutId);
|
|
10558
|
-
if (err instanceof Error && err.name === "AbortError") {
|
|
10559
|
-
return 130;
|
|
10560
|
-
}
|
|
10561
|
-
console.error(import_picocolors5.default.red(`Error: ${serializeError(err)}`));
|
|
10562
|
-
return 1;
|
|
10563
|
-
}
|
|
10564
|
-
}
|
|
10565
|
-
// src/cli/get-local-version/index.ts
|
|
10566
|
-
init_checker();
|
|
10567
|
-
|
|
10568
|
-
// src/cli/get-local-version/formatter.ts
|
|
10569
|
-
var import_picocolors6 = __toESM(require_picocolors(), 1);
|
|
10570
|
-
var SYMBOLS2 = {
|
|
10571
|
-
check: import_picocolors6.default.green("[OK]"),
|
|
10572
|
-
cross: import_picocolors6.default.red("[X]"),
|
|
10573
|
-
arrow: import_picocolors6.default.cyan("->"),
|
|
10574
|
-
info: import_picocolors6.default.blue("[i]"),
|
|
10575
|
-
warn: import_picocolors6.default.yellow("[!]"),
|
|
10576
|
-
pin: import_picocolors6.default.magenta("[PINNED]"),
|
|
10577
|
-
dev: import_picocolors6.default.cyan("[DEV]")
|
|
10578
|
-
};
|
|
10579
|
-
function formatVersionOutput(info) {
|
|
10580
|
-
const lines = [];
|
|
10581
|
-
lines.push("");
|
|
10582
|
-
lines.push(import_picocolors6.default.bold(import_picocolors6.default.white("oh-my-opencode Version Information")));
|
|
10583
|
-
lines.push(import_picocolors6.default.dim("\u2500".repeat(50)));
|
|
10584
|
-
lines.push("");
|
|
10585
|
-
if (info.currentVersion) {
|
|
10586
|
-
lines.push(` Current Version: ${import_picocolors6.default.cyan(info.currentVersion)}`);
|
|
10587
|
-
} else {
|
|
10588
|
-
lines.push(` Current Version: ${import_picocolors6.default.dim("unknown")}`);
|
|
10589
|
-
}
|
|
10590
|
-
if (!info.isLocalDev && info.latestVersion) {
|
|
10591
|
-
lines.push(` Latest Version: ${import_picocolors6.default.cyan(info.latestVersion)}`);
|
|
10592
|
-
}
|
|
10593
|
-
lines.push("");
|
|
10594
|
-
switch (info.status) {
|
|
10595
|
-
case "up-to-date":
|
|
10596
|
-
lines.push(` ${SYMBOLS2.check} ${import_picocolors6.default.green("You're up to date!")}`);
|
|
10597
|
-
break;
|
|
10598
|
-
case "outdated":
|
|
10599
|
-
lines.push(` ${SYMBOLS2.warn} ${import_picocolors6.default.yellow("Update available")}`);
|
|
10600
|
-
lines.push(` ${import_picocolors6.default.dim("Run:")} ${import_picocolors6.default.cyan("cd ~/.config/opencode && bun update oh-my-opencode")}`);
|
|
10601
|
-
break;
|
|
10602
|
-
case "local-dev":
|
|
10603
|
-
lines.push(` ${SYMBOLS2.dev} ${import_picocolors6.default.cyan("Running in local development mode")}`);
|
|
10604
|
-
lines.push(` ${import_picocolors6.default.dim("Using file:// protocol from config")}`);
|
|
10605
|
-
break;
|
|
10606
|
-
case "pinned":
|
|
10607
|
-
lines.push(` ${SYMBOLS2.pin} ${import_picocolors6.default.magenta(`Version pinned to ${info.pinnedVersion}`)}`);
|
|
10608
|
-
lines.push(` ${import_picocolors6.default.dim("Update check skipped for pinned versions")}`);
|
|
10609
|
-
break;
|
|
10610
|
-
case "error":
|
|
10611
|
-
lines.push(` ${SYMBOLS2.cross} ${import_picocolors6.default.red("Unable to check for updates")}`);
|
|
10612
|
-
lines.push(` ${import_picocolors6.default.dim("Network error or npm registry unavailable")}`);
|
|
10613
|
-
break;
|
|
10614
|
-
case "unknown":
|
|
10615
|
-
lines.push(` ${SYMBOLS2.info} ${import_picocolors6.default.yellow("Version information unavailable")}`);
|
|
10616
|
-
break;
|
|
10617
|
-
}
|
|
10618
|
-
lines.push("");
|
|
10619
|
-
return lines.join(`
|
|
10620
|
-
`);
|
|
10621
|
-
}
|
|
10622
|
-
function formatJsonOutput(info) {
|
|
10623
|
-
return JSON.stringify(info, null, 2);
|
|
10624
|
-
}
|
|
10625
|
-
|
|
10626
|
-
// src/cli/get-local-version/index.ts
|
|
10627
|
-
async function getLocalVersion(options = {}) {
|
|
10628
|
-
const directory = options.directory ?? process.cwd();
|
|
10629
|
-
try {
|
|
10630
|
-
if (isLocalDevMode(directory)) {
|
|
10631
|
-
const currentVersion2 = getCachedVersion();
|
|
10632
|
-
const info2 = {
|
|
10633
|
-
currentVersion: currentVersion2,
|
|
10634
|
-
latestVersion: null,
|
|
10635
|
-
isUpToDate: false,
|
|
10636
|
-
isLocalDev: true,
|
|
10637
|
-
isPinned: false,
|
|
10638
|
-
pinnedVersion: null,
|
|
10639
|
-
status: "local-dev"
|
|
10640
|
-
};
|
|
10641
|
-
console.log(options.json ? formatJsonOutput(info2) : formatVersionOutput(info2));
|
|
10642
|
-
return 0;
|
|
10643
|
-
}
|
|
10644
|
-
const pluginInfo = findPluginEntry(directory);
|
|
10645
|
-
if (pluginInfo?.isPinned) {
|
|
10646
|
-
const info2 = {
|
|
10647
|
-
currentVersion: pluginInfo.pinnedVersion,
|
|
10648
|
-
latestVersion: null,
|
|
10649
|
-
isUpToDate: false,
|
|
10650
|
-
isLocalDev: false,
|
|
10651
|
-
isPinned: true,
|
|
10652
|
-
pinnedVersion: pluginInfo.pinnedVersion,
|
|
10653
|
-
status: "pinned"
|
|
10654
|
-
};
|
|
10655
|
-
console.log(options.json ? formatJsonOutput(info2) : formatVersionOutput(info2));
|
|
10656
|
-
return 0;
|
|
10657
|
-
}
|
|
10658
|
-
const currentVersion = getCachedVersion();
|
|
10659
|
-
if (!currentVersion) {
|
|
10660
|
-
const info2 = {
|
|
10661
|
-
currentVersion: null,
|
|
10662
|
-
latestVersion: null,
|
|
10663
|
-
isUpToDate: false,
|
|
10664
|
-
isLocalDev: false,
|
|
10665
|
-
isPinned: false,
|
|
10666
|
-
pinnedVersion: null,
|
|
10667
|
-
status: "unknown"
|
|
10668
|
-
};
|
|
10669
|
-
console.log(options.json ? formatJsonOutput(info2) : formatVersionOutput(info2));
|
|
10670
|
-
return 1;
|
|
10671
|
-
}
|
|
10672
|
-
const { extractChannel: extractChannel2 } = await Promise.resolve().then(() => (init_auto_update_checker(), exports_auto_update_checker));
|
|
10673
|
-
const channel = extractChannel2(pluginInfo?.pinnedVersion ?? currentVersion);
|
|
10674
|
-
const latestVersion = await getLatestVersion(channel);
|
|
10675
|
-
if (!latestVersion) {
|
|
10676
|
-
const info2 = {
|
|
10677
|
-
currentVersion,
|
|
10678
|
-
latestVersion: null,
|
|
10679
|
-
isUpToDate: false,
|
|
10680
|
-
isLocalDev: false,
|
|
10681
|
-
isPinned: false,
|
|
10682
|
-
pinnedVersion: null,
|
|
10683
|
-
status: "error"
|
|
10684
|
-
};
|
|
10685
|
-
console.log(options.json ? formatJsonOutput(info2) : formatVersionOutput(info2));
|
|
10686
|
-
return 0;
|
|
10687
|
-
}
|
|
10688
|
-
const isUpToDate = currentVersion === latestVersion;
|
|
10689
|
-
const info = {
|
|
10690
|
-
currentVersion,
|
|
10691
|
-
latestVersion,
|
|
10692
|
-
isUpToDate,
|
|
10693
|
-
isLocalDev: false,
|
|
10694
|
-
isPinned: false,
|
|
10695
|
-
pinnedVersion: null,
|
|
10696
|
-
status: isUpToDate ? "up-to-date" : "outdated"
|
|
10697
|
-
};
|
|
10698
|
-
console.log(options.json ? formatJsonOutput(info) : formatVersionOutput(info));
|
|
10699
|
-
return 0;
|
|
10700
|
-
} catch (error) {
|
|
10701
|
-
const info = {
|
|
10702
|
-
currentVersion: null,
|
|
10703
|
-
latestVersion: null,
|
|
10704
|
-
isUpToDate: false,
|
|
10705
|
-
isLocalDev: false,
|
|
10706
|
-
isPinned: false,
|
|
10707
|
-
pinnedVersion: null,
|
|
10708
|
-
status: "error"
|
|
10709
|
-
};
|
|
10710
|
-
console.log(options.json ? formatJsonOutput(info) : formatVersionOutput(info));
|
|
10711
|
-
return 1;
|
|
10712
|
-
}
|
|
10713
|
-
}
|
|
10714
|
-
|
|
10715
|
-
// src/cli/doctor/checks/opencode.ts
|
|
10716
|
-
import { existsSync as existsSync8 } from "fs";
|
|
10717
|
-
import { homedir as homedir5 } from "os";
|
|
10718
|
-
import { join as join10 } from "path";
|
|
10719
|
-
|
|
10720
|
-
// src/cli/doctor/constants.ts
|
|
10721
|
-
var import_picocolors7 = __toESM(require_picocolors(), 1);
|
|
10722
|
-
var SYMBOLS3 = {
|
|
10723
|
-
check: import_picocolors7.default.green("\u2713"),
|
|
10724
|
-
cross: import_picocolors7.default.red("\u2717"),
|
|
10725
|
-
warn: import_picocolors7.default.yellow("\u26A0"),
|
|
10726
|
-
info: import_picocolors7.default.blue("\u2139"),
|
|
10727
|
-
arrow: import_picocolors7.default.cyan("\u2192"),
|
|
10728
|
-
bullet: import_picocolors7.default.dim("\u2022"),
|
|
10729
|
-
skip: import_picocolors7.default.dim("\u25CB")
|
|
10730
|
-
};
|
|
10731
|
-
var STATUS_COLORS = {
|
|
10732
|
-
pass: import_picocolors7.default.green,
|
|
10733
|
-
fail: import_picocolors7.default.red,
|
|
10734
|
-
warn: import_picocolors7.default.yellow,
|
|
10735
|
-
skip: import_picocolors7.default.dim
|
|
10736
|
-
};
|
|
10737
|
-
var CHECK_IDS = {
|
|
10738
|
-
OPENCODE_INSTALLATION: "opencode-installation",
|
|
10739
|
-
PLUGIN_REGISTRATION: "plugin-registration",
|
|
10740
|
-
CONFIG_VALIDATION: "config-validation",
|
|
10741
|
-
MODEL_RESOLUTION: "model-resolution",
|
|
10742
|
-
AUTH_ANTHROPIC: "auth-anthropic",
|
|
10743
|
-
AUTH_OPENAI: "auth-openai",
|
|
10744
|
-
AUTH_GOOGLE: "auth-google",
|
|
10745
|
-
DEP_AST_GREP_CLI: "dep-ast-grep-cli",
|
|
10746
|
-
DEP_AST_GREP_NAPI: "dep-ast-grep-napi",
|
|
10747
|
-
DEP_COMMENT_CHECKER: "dep-comment-checker",
|
|
10748
|
-
GH_CLI: "gh-cli",
|
|
10749
|
-
LSP_SERVERS: "lsp-servers",
|
|
10750
|
-
MCP_BUILTIN: "mcp-builtin",
|
|
10751
|
-
MCP_USER: "mcp-user",
|
|
10752
|
-
MCP_OAUTH_TOKENS: "mcp-oauth-tokens",
|
|
10753
|
-
VERSION_STATUS: "version-status"
|
|
10754
|
-
};
|
|
10755
|
-
var CHECK_NAMES = {
|
|
10756
|
-
[CHECK_IDS.OPENCODE_INSTALLATION]: "OpenCode Installation",
|
|
10757
|
-
[CHECK_IDS.PLUGIN_REGISTRATION]: "Plugin Registration",
|
|
10758
|
-
[CHECK_IDS.CONFIG_VALIDATION]: "Configuration Validity",
|
|
10759
|
-
[CHECK_IDS.MODEL_RESOLUTION]: "Model Resolution",
|
|
10760
|
-
[CHECK_IDS.AUTH_ANTHROPIC]: "Anthropic (Claude) Auth",
|
|
10761
|
-
[CHECK_IDS.AUTH_OPENAI]: "OpenAI (ChatGPT) Auth",
|
|
10762
|
-
[CHECK_IDS.AUTH_GOOGLE]: "Google (Gemini) Auth",
|
|
10763
|
-
[CHECK_IDS.DEP_AST_GREP_CLI]: "AST-Grep CLI",
|
|
10764
|
-
[CHECK_IDS.DEP_AST_GREP_NAPI]: "AST-Grep NAPI",
|
|
10765
|
-
[CHECK_IDS.DEP_COMMENT_CHECKER]: "Comment Checker",
|
|
10766
|
-
[CHECK_IDS.GH_CLI]: "GitHub CLI",
|
|
10767
|
-
[CHECK_IDS.LSP_SERVERS]: "LSP Servers",
|
|
10768
|
-
[CHECK_IDS.MCP_BUILTIN]: "Built-in MCP Servers",
|
|
10769
|
-
[CHECK_IDS.MCP_USER]: "User MCP Configuration",
|
|
10770
|
-
[CHECK_IDS.MCP_OAUTH_TOKENS]: "MCP OAuth Tokens",
|
|
10771
|
-
[CHECK_IDS.VERSION_STATUS]: "Version Status"
|
|
10772
|
-
};
|
|
10773
|
-
var CATEGORY_NAMES = {
|
|
10774
|
-
installation: "Installation",
|
|
10775
|
-
configuration: "Configuration",
|
|
10776
|
-
authentication: "Authentication",
|
|
10777
|
-
dependencies: "Dependencies",
|
|
10778
|
-
tools: "Tools & Servers",
|
|
10779
|
-
updates: "Updates"
|
|
10780
|
-
};
|
|
10781
|
-
var EXIT_CODES = {
|
|
10782
|
-
SUCCESS: 0,
|
|
10783
|
-
FAILURE: 1
|
|
10784
|
-
};
|
|
10785
|
-
var MIN_OPENCODE_VERSION = "1.0.150";
|
|
10786
|
-
var PACKAGE_NAME3 = "oh-my-opencode";
|
|
10787
|
-
var OPENCODE_BINARIES2 = ["opencode", "opencode-desktop"];
|
|
10788
|
-
|
|
10789
|
-
// src/cli/doctor/checks/opencode.ts
|
|
10790
|
-
function getDesktopAppPaths(platform) {
|
|
10791
|
-
const home = homedir5();
|
|
10792
|
-
switch (platform) {
|
|
10793
|
-
case "darwin":
|
|
10794
|
-
return [
|
|
10795
|
-
"/Applications/OpenCode.app/Contents/MacOS/OpenCode",
|
|
10796
|
-
join10(home, "Applications", "OpenCode.app", "Contents", "MacOS", "OpenCode")
|
|
10797
|
-
];
|
|
10798
|
-
case "win32": {
|
|
10799
|
-
const programFiles = process.env.ProgramFiles;
|
|
10800
|
-
const localAppData = process.env.LOCALAPPDATA;
|
|
10801
|
-
const paths = [];
|
|
10802
|
-
if (programFiles) {
|
|
10803
|
-
paths.push(join10(programFiles, "OpenCode", "OpenCode.exe"));
|
|
10804
|
-
}
|
|
10805
|
-
if (localAppData) {
|
|
10806
|
-
paths.push(join10(localAppData, "OpenCode", "OpenCode.exe"));
|
|
10807
|
-
}
|
|
10808
|
-
return paths;
|
|
10809
|
-
}
|
|
10810
|
-
case "linux":
|
|
10811
|
-
return [
|
|
10812
|
-
"/usr/bin/opencode",
|
|
10813
|
-
"/usr/lib/opencode/opencode",
|
|
10814
|
-
join10(home, "Applications", "opencode-desktop-linux-x86_64.AppImage"),
|
|
10815
|
-
join10(home, "Applications", "opencode-desktop-linux-aarch64.AppImage")
|
|
10816
|
-
];
|
|
10817
|
-
default:
|
|
10818
|
-
return [];
|
|
10819
|
-
}
|
|
10820
|
-
}
|
|
10821
|
-
function buildVersionCommand(binaryPath, platform) {
|
|
10822
|
-
if (platform === "win32" && binaryPath.toLowerCase().endsWith(".ps1")) {
|
|
10823
|
-
return [
|
|
10824
|
-
"powershell",
|
|
10825
|
-
"-NoProfile",
|
|
10826
|
-
"-ExecutionPolicy",
|
|
10827
|
-
"Bypass",
|
|
10828
|
-
"-File",
|
|
10829
|
-
binaryPath,
|
|
10830
|
-
"--version"
|
|
10831
|
-
];
|
|
10832
|
-
}
|
|
10833
|
-
return [binaryPath, "--version"];
|
|
10834
|
-
}
|
|
10835
|
-
function findDesktopBinary(platform = process.platform, checkExists = existsSync8) {
|
|
10836
|
-
const desktopPaths = getDesktopAppPaths(platform);
|
|
10837
|
-
for (const desktopPath of desktopPaths) {
|
|
10838
|
-
if (checkExists(desktopPath)) {
|
|
10839
|
-
return { binary: "opencode", path: desktopPath };
|
|
10840
|
-
}
|
|
10841
|
-
}
|
|
10842
|
-
return null;
|
|
10843
|
-
}
|
|
10844
|
-
async function findOpenCodeBinary() {
|
|
10845
|
-
for (const binary2 of OPENCODE_BINARIES2) {
|
|
10846
|
-
try {
|
|
10847
|
-
const path6 = Bun.which(binary2);
|
|
10848
|
-
if (path6) {
|
|
10849
|
-
return { binary: binary2, path: path6 };
|
|
10850
|
-
}
|
|
10851
|
-
} catch {
|
|
10852
|
-
continue;
|
|
10853
|
-
}
|
|
10854
|
-
}
|
|
10855
|
-
const desktopResult = findDesktopBinary();
|
|
10856
|
-
if (desktopResult) {
|
|
10857
|
-
return desktopResult;
|
|
10858
|
-
}
|
|
10859
|
-
return null;
|
|
10860
|
-
}
|
|
10861
|
-
async function getOpenCodeVersion2(binaryPath, platform = process.platform) {
|
|
10862
|
-
try {
|
|
10863
|
-
const command = buildVersionCommand(binaryPath, platform);
|
|
10864
|
-
const proc = Bun.spawn(command, { stdout: "pipe", stderr: "pipe" });
|
|
10865
|
-
const output = await new Response(proc.stdout).text();
|
|
10866
|
-
await proc.exited;
|
|
10867
|
-
if (proc.exitCode === 0) {
|
|
10868
|
-
return output.trim();
|
|
10869
|
-
}
|
|
10870
|
-
} catch {
|
|
10871
|
-
return null;
|
|
10872
|
-
}
|
|
10873
|
-
return null;
|
|
10874
|
-
}
|
|
10875
|
-
function compareVersions(current, minimum) {
|
|
10876
|
-
const parseVersion = (v) => {
|
|
10877
|
-
const cleaned = v.replace(/^v/, "").split("-")[0];
|
|
10878
|
-
return cleaned.split(".").map((n) => parseInt(n, 10) || 0);
|
|
10879
|
-
};
|
|
10880
|
-
const curr = parseVersion(current);
|
|
10881
|
-
const min = parseVersion(minimum);
|
|
10882
|
-
for (let i2 = 0;i2 < Math.max(curr.length, min.length); i2++) {
|
|
10883
|
-
const c = curr[i2] ?? 0;
|
|
10884
|
-
const m2 = min[i2] ?? 0;
|
|
10885
|
-
if (c > m2)
|
|
10886
|
-
return true;
|
|
10887
|
-
if (c < m2)
|
|
10888
|
-
return false;
|
|
10889
|
-
}
|
|
10890
|
-
return true;
|
|
10891
|
-
}
|
|
10892
|
-
async function getOpenCodeInfo() {
|
|
10893
|
-
const binaryInfo = await findOpenCodeBinary();
|
|
10894
|
-
if (!binaryInfo) {
|
|
10895
|
-
return {
|
|
10896
|
-
installed: false,
|
|
10897
|
-
version: null,
|
|
10898
|
-
path: null,
|
|
10899
|
-
binary: null
|
|
10900
|
-
};
|
|
10901
|
-
}
|
|
10902
|
-
const version = await getOpenCodeVersion2(binaryInfo.path ?? binaryInfo.binary);
|
|
10903
|
-
return {
|
|
10904
|
-
installed: true,
|
|
10905
|
-
version,
|
|
10906
|
-
path: binaryInfo.path,
|
|
10907
|
-
binary: binaryInfo.binary
|
|
10908
|
-
};
|
|
10909
|
-
}
|
|
10910
|
-
async function checkOpenCodeInstallation() {
|
|
10911
|
-
const info = await getOpenCodeInfo();
|
|
10912
|
-
if (!info.installed) {
|
|
10913
|
-
return {
|
|
10914
|
-
name: CHECK_NAMES[CHECK_IDS.OPENCODE_INSTALLATION],
|
|
10915
|
-
status: "fail",
|
|
10916
|
-
message: "OpenCode is not installed",
|
|
10917
|
-
details: [
|
|
10918
|
-
"Visit: https://opencode.ai/docs for installation instructions",
|
|
10919
|
-
"Run: npm install -g opencode"
|
|
10920
|
-
]
|
|
10921
|
-
};
|
|
10922
|
-
}
|
|
10923
|
-
if (info.version && !compareVersions(info.version, MIN_OPENCODE_VERSION)) {
|
|
10924
|
-
return {
|
|
10925
|
-
name: CHECK_NAMES[CHECK_IDS.OPENCODE_INSTALLATION],
|
|
10926
|
-
status: "warn",
|
|
10927
|
-
message: `Version ${info.version} is below minimum ${MIN_OPENCODE_VERSION}`,
|
|
10928
|
-
details: [
|
|
10929
|
-
`Current: ${info.version}`,
|
|
10930
|
-
`Required: >= ${MIN_OPENCODE_VERSION}`,
|
|
10931
|
-
"Run: npm update -g opencode"
|
|
10932
|
-
]
|
|
10933
|
-
};
|
|
10934
|
-
}
|
|
10935
|
-
return {
|
|
10936
|
-
name: CHECK_NAMES[CHECK_IDS.OPENCODE_INSTALLATION],
|
|
10937
|
-
status: "pass",
|
|
10938
|
-
message: info.version ?? "installed",
|
|
10939
|
-
details: info.path ? [`Path: ${info.path}`] : undefined
|
|
10940
|
-
};
|
|
10941
|
-
}
|
|
10942
|
-
function getOpenCodeCheckDefinition() {
|
|
10943
|
-
return {
|
|
10944
|
-
id: CHECK_IDS.OPENCODE_INSTALLATION,
|
|
10945
|
-
name: CHECK_NAMES[CHECK_IDS.OPENCODE_INSTALLATION],
|
|
10946
|
-
category: "installation",
|
|
10947
|
-
check: checkOpenCodeInstallation,
|
|
10948
|
-
critical: true
|
|
10949
|
-
};
|
|
10950
|
-
}
|
|
10951
|
-
|
|
10952
|
-
// src/cli/doctor/checks/plugin.ts
|
|
10953
|
-
import { existsSync as existsSync9, readFileSync as readFileSync7 } from "fs";
|
|
10954
|
-
init_shared();
|
|
10955
|
-
function detectConfigPath() {
|
|
10956
|
-
const paths = getOpenCodeConfigPaths({ binary: "opencode", version: null });
|
|
10957
|
-
if (existsSync9(paths.configJsonc)) {
|
|
10958
|
-
return { path: paths.configJsonc, format: "jsonc" };
|
|
10959
|
-
}
|
|
10960
|
-
if (existsSync9(paths.configJson)) {
|
|
10961
|
-
return { path: paths.configJson, format: "json" };
|
|
10962
|
-
}
|
|
10963
|
-
return null;
|
|
10964
|
-
}
|
|
10965
|
-
function findPluginEntry2(plugins) {
|
|
10966
|
-
for (const plugin of plugins) {
|
|
10967
|
-
if (plugin === PACKAGE_NAME3 || plugin.startsWith(`${PACKAGE_NAME3}@`)) {
|
|
10968
|
-
const isPinned = plugin.includes("@");
|
|
10969
|
-
const version = isPinned ? plugin.split("@")[1] : null;
|
|
10970
|
-
return { entry: plugin, isPinned, version };
|
|
10971
|
-
}
|
|
10972
|
-
if (plugin.startsWith("file://") && plugin.includes(PACKAGE_NAME3)) {
|
|
10973
|
-
return { entry: plugin, isPinned: false, version: "local-dev" };
|
|
10974
|
-
}
|
|
10975
|
-
}
|
|
10976
|
-
return null;
|
|
10977
|
-
}
|
|
10978
|
-
function getPluginInfo() {
|
|
10979
|
-
const configInfo = detectConfigPath();
|
|
10980
|
-
if (!configInfo) {
|
|
10981
|
-
return {
|
|
10982
|
-
registered: false,
|
|
10983
|
-
configPath: null,
|
|
10984
|
-
entry: null,
|
|
10985
|
-
isPinned: false,
|
|
10986
|
-
pinnedVersion: null
|
|
10987
|
-
};
|
|
10988
|
-
}
|
|
10989
|
-
try {
|
|
10990
|
-
const content = readFileSync7(configInfo.path, "utf-8");
|
|
10991
|
-
const config = parseJsonc(content);
|
|
10992
|
-
const plugins = config.plugin ?? [];
|
|
10993
|
-
const pluginEntry = findPluginEntry2(plugins);
|
|
10994
|
-
if (!pluginEntry) {
|
|
10995
|
-
return {
|
|
10996
|
-
registered: false,
|
|
10997
|
-
configPath: configInfo.path,
|
|
10998
|
-
entry: null,
|
|
10999
|
-
isPinned: false,
|
|
11000
|
-
pinnedVersion: null
|
|
11001
|
-
};
|
|
11002
|
-
}
|
|
11003
|
-
return {
|
|
11004
|
-
registered: true,
|
|
11005
|
-
configPath: configInfo.path,
|
|
11006
|
-
entry: pluginEntry.entry,
|
|
11007
|
-
isPinned: pluginEntry.isPinned,
|
|
11008
|
-
pinnedVersion: pluginEntry.version
|
|
11009
|
-
};
|
|
11010
|
-
} catch {
|
|
11011
|
-
return {
|
|
11012
|
-
registered: false,
|
|
11013
|
-
configPath: configInfo.path,
|
|
11014
|
-
entry: null,
|
|
11015
|
-
isPinned: false,
|
|
11016
|
-
pinnedVersion: null
|
|
11017
|
-
};
|
|
11018
|
-
}
|
|
11019
|
-
}
|
|
11020
|
-
async function checkPluginRegistration() {
|
|
11021
|
-
const info = getPluginInfo();
|
|
11022
|
-
if (!info.configPath) {
|
|
11023
|
-
const expectedPaths = getOpenCodeConfigPaths({ binary: "opencode", version: null });
|
|
11024
|
-
return {
|
|
11025
|
-
name: CHECK_NAMES[CHECK_IDS.PLUGIN_REGISTRATION],
|
|
11026
|
-
status: "fail",
|
|
11027
|
-
message: "OpenCode config file not found",
|
|
11028
|
-
details: [
|
|
11029
|
-
"Run: bunx oh-my-opencode install",
|
|
11030
|
-
`Expected: ${expectedPaths.configJson} or ${expectedPaths.configJsonc}`
|
|
11031
|
-
]
|
|
11032
|
-
};
|
|
11033
|
-
}
|
|
11034
|
-
if (!info.registered) {
|
|
11035
|
-
return {
|
|
11036
|
-
name: CHECK_NAMES[CHECK_IDS.PLUGIN_REGISTRATION],
|
|
11037
|
-
status: "fail",
|
|
11038
|
-
message: "Plugin not registered in config",
|
|
11039
|
-
details: [
|
|
11040
|
-
"Run: bunx oh-my-opencode install",
|
|
11041
|
-
`Config: ${info.configPath}`
|
|
11042
|
-
]
|
|
11043
|
-
};
|
|
11044
|
-
}
|
|
11045
|
-
const message = info.isPinned ? `Registered (pinned: ${info.pinnedVersion})` : "Registered";
|
|
11046
|
-
return {
|
|
11047
|
-
name: CHECK_NAMES[CHECK_IDS.PLUGIN_REGISTRATION],
|
|
11048
|
-
status: "pass",
|
|
11049
|
-
message,
|
|
11050
|
-
details: [`Config: ${info.configPath}`]
|
|
11051
|
-
};
|
|
11052
|
-
}
|
|
11053
|
-
function getPluginCheckDefinition() {
|
|
11054
|
-
return {
|
|
11055
|
-
id: CHECK_IDS.PLUGIN_REGISTRATION,
|
|
11056
|
-
name: CHECK_NAMES[CHECK_IDS.PLUGIN_REGISTRATION],
|
|
11057
|
-
category: "installation",
|
|
11058
|
-
check: checkPluginRegistration,
|
|
11059
|
-
critical: true
|
|
11060
|
-
};
|
|
11061
|
-
}
|
|
11062
|
-
|
|
11063
|
-
// src/cli/doctor/checks/config.ts
|
|
11064
|
-
import { existsSync as existsSync10, readFileSync as readFileSync8 } from "fs";
|
|
11065
|
-
import { join as join11 } from "path";
|
|
11066
|
-
init_shared();
|
|
10578
|
+
// src/plugin-config.ts
|
|
10579
|
+
import * as fs3 from "fs";
|
|
10580
|
+
import * as path3 from "path";
|
|
11067
10581
|
|
|
11068
10582
|
// node_modules/zod/v4/classic/external.js
|
|
11069
10583
|
var exports_external = {};
|
|
@@ -11830,10 +11344,10 @@ function mergeDefs(...defs) {
|
|
|
11830
11344
|
function cloneDef(schema2) {
|
|
11831
11345
|
return mergeDefs(schema2._zod.def);
|
|
11832
11346
|
}
|
|
11833
|
-
function getElementAtPath(obj,
|
|
11834
|
-
if (!
|
|
11347
|
+
function getElementAtPath(obj, path3) {
|
|
11348
|
+
if (!path3)
|
|
11835
11349
|
return obj;
|
|
11836
|
-
return
|
|
11350
|
+
return path3.reduce((acc, key) => acc?.[key], obj);
|
|
11837
11351
|
}
|
|
11838
11352
|
function promiseAllObject(promisesObj) {
|
|
11839
11353
|
const keys = Object.keys(promisesObj);
|
|
@@ -12214,11 +11728,11 @@ function aborted(x2, startIndex = 0) {
|
|
|
12214
11728
|
}
|
|
12215
11729
|
return false;
|
|
12216
11730
|
}
|
|
12217
|
-
function prefixIssues(
|
|
11731
|
+
function prefixIssues(path3, issues) {
|
|
12218
11732
|
return issues.map((iss) => {
|
|
12219
11733
|
var _a;
|
|
12220
11734
|
(_a = iss).path ?? (_a.path = []);
|
|
12221
|
-
iss.path.unshift(
|
|
11735
|
+
iss.path.unshift(path3);
|
|
12222
11736
|
return iss;
|
|
12223
11737
|
});
|
|
12224
11738
|
}
|
|
@@ -12401,7 +11915,7 @@ function formatError2(error, mapper = (issue2) => issue2.message) {
|
|
|
12401
11915
|
}
|
|
12402
11916
|
function treeifyError(error, mapper = (issue2) => issue2.message) {
|
|
12403
11917
|
const result = { errors: [] };
|
|
12404
|
-
const processError = (error2,
|
|
11918
|
+
const processError = (error2, path3 = []) => {
|
|
12405
11919
|
var _a, _b;
|
|
12406
11920
|
for (const issue2 of error2.issues) {
|
|
12407
11921
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
@@ -12411,7 +11925,7 @@ function treeifyError(error, mapper = (issue2) => issue2.message) {
|
|
|
12411
11925
|
} else if (issue2.code === "invalid_element") {
|
|
12412
11926
|
processError({ issues: issue2.issues }, issue2.path);
|
|
12413
11927
|
} else {
|
|
12414
|
-
const fullpath = [...
|
|
11928
|
+
const fullpath = [...path3, ...issue2.path];
|
|
12415
11929
|
if (fullpath.length === 0) {
|
|
12416
11930
|
result.errors.push(mapper(issue2));
|
|
12417
11931
|
continue;
|
|
@@ -12443,8 +11957,8 @@ function treeifyError(error, mapper = (issue2) => issue2.message) {
|
|
|
12443
11957
|
}
|
|
12444
11958
|
function toDotPath(_path) {
|
|
12445
11959
|
const segs = [];
|
|
12446
|
-
const
|
|
12447
|
-
for (const seg of
|
|
11960
|
+
const path3 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
11961
|
+
for (const seg of path3) {
|
|
12448
11962
|
if (typeof seg === "number")
|
|
12449
11963
|
segs.push(`[${seg}]`);
|
|
12450
11964
|
else if (typeof seg === "symbol")
|
|
@@ -21423,10 +20937,10 @@ function _property(property, schema2, params) {
|
|
|
21423
20937
|
...normalizeParams(params)
|
|
21424
20938
|
});
|
|
21425
20939
|
}
|
|
21426
|
-
function _mime(
|
|
20940
|
+
function _mime(types2, params) {
|
|
21427
20941
|
return new $ZodCheckMimeType({
|
|
21428
20942
|
check: "mime_type",
|
|
21429
|
-
mime:
|
|
20943
|
+
mime: types2,
|
|
21430
20944
|
...normalizeParams(params)
|
|
21431
20945
|
});
|
|
21432
20946
|
}
|
|
@@ -23779,7 +23293,7 @@ var ZodFile = /* @__PURE__ */ $constructor("ZodFile", (inst, def) => {
|
|
|
23779
23293
|
inst._zod.processJSONSchema = (ctx, json2, params) => fileProcessor(inst, ctx, json2, params);
|
|
23780
23294
|
inst.min = (size, params) => inst.check(_minSize(size, params));
|
|
23781
23295
|
inst.max = (size, params) => inst.check(_maxSize(size, params));
|
|
23782
|
-
inst.mime = (
|
|
23296
|
+
inst.mime = (types2, params) => inst.check(_mime(Array.isArray(types2) ? types2 : [types2], params));
|
|
23783
23297
|
});
|
|
23784
23298
|
function file(params) {
|
|
23785
23299
|
return _file(ZodFile, params);
|
|
@@ -24191,13 +23705,13 @@ function resolveRef(ref, ctx) {
|
|
|
24191
23705
|
if (!ref.startsWith("#")) {
|
|
24192
23706
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
24193
23707
|
}
|
|
24194
|
-
const
|
|
24195
|
-
if (
|
|
23708
|
+
const path3 = ref.slice(1).split("/").filter(Boolean);
|
|
23709
|
+
if (path3.length === 0) {
|
|
24196
23710
|
return ctx.rootSchema;
|
|
24197
23711
|
}
|
|
24198
23712
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
24199
|
-
if (
|
|
24200
|
-
const key =
|
|
23713
|
+
if (path3[0] === defsKey) {
|
|
23714
|
+
const key = path3[1];
|
|
24201
23715
|
if (!key || !ctx.defs[key]) {
|
|
24202
23716
|
throw new Error(`Reference not found: ${ref}`);
|
|
24203
23717
|
}
|
|
@@ -24661,6 +24175,7 @@ var HookNameSchema = exports_external.enum([
|
|
|
24661
24175
|
"empty-task-response-detector",
|
|
24662
24176
|
"think-mode",
|
|
24663
24177
|
"anthropic-context-window-limit-recovery",
|
|
24178
|
+
"preemptive-compaction",
|
|
24664
24179
|
"rules-injector",
|
|
24665
24180
|
"background-notification",
|
|
24666
24181
|
"auto-update-checker",
|
|
@@ -24682,7 +24197,8 @@ var HookNameSchema = exports_external.enum([
|
|
|
24682
24197
|
"start-work",
|
|
24683
24198
|
"atlas",
|
|
24684
24199
|
"unstable-agent-babysitter",
|
|
24685
|
-
"stop-continuation-guard"
|
|
24200
|
+
"stop-continuation-guard",
|
|
24201
|
+
"tasks-todowrite-disabler"
|
|
24686
24202
|
]);
|
|
24687
24203
|
var BuiltinCommandNameSchema = exports_external.enum([
|
|
24688
24204
|
"init-deep",
|
|
@@ -24807,8 +24323,10 @@ var DynamicContextPruningConfigSchema = exports_external.object({
|
|
|
24807
24323
|
var ExperimentalConfigSchema = exports_external.object({
|
|
24808
24324
|
aggressive_truncation: exports_external.boolean().optional(),
|
|
24809
24325
|
auto_resume: exports_external.boolean().optional(),
|
|
24326
|
+
preemptive_compaction: exports_external.boolean().optional(),
|
|
24810
24327
|
truncate_all_tool_outputs: exports_external.boolean().optional(),
|
|
24811
|
-
dynamic_context_pruning: DynamicContextPruningConfigSchema.optional()
|
|
24328
|
+
dynamic_context_pruning: DynamicContextPruningConfigSchema.optional(),
|
|
24329
|
+
task_system: exports_external.boolean().optional()
|
|
24812
24330
|
});
|
|
24813
24331
|
var SkillSourceSchema = exports_external.union([
|
|
24814
24332
|
exports_external.string(),
|
|
@@ -24884,26 +24402,22 @@ var TmuxConfigSchema = exports_external.object({
|
|
|
24884
24402
|
agent_pane_min_width: exports_external.number().min(20).default(40)
|
|
24885
24403
|
});
|
|
24886
24404
|
var SisyphusTasksConfigSchema = exports_external.object({
|
|
24887
|
-
enabled: exports_external.boolean().default(false),
|
|
24888
24405
|
storage_path: exports_external.string().default(".sisyphus/tasks"),
|
|
24889
24406
|
claude_code_compat: exports_external.boolean().default(false)
|
|
24890
24407
|
});
|
|
24891
|
-
var SisyphusSwarmConfigSchema = exports_external.object({
|
|
24892
|
-
enabled: exports_external.boolean().default(false),
|
|
24893
|
-
storage_path: exports_external.string().default(".sisyphus/teams"),
|
|
24894
|
-
ui_mode: exports_external.enum(["toast", "tmux", "both"]).default("toast")
|
|
24895
|
-
});
|
|
24896
24408
|
var SisyphusConfigSchema = exports_external.object({
|
|
24897
|
-
tasks: SisyphusTasksConfigSchema.optional()
|
|
24898
|
-
swarm: SisyphusSwarmConfigSchema.optional()
|
|
24409
|
+
tasks: SisyphusTasksConfigSchema.optional()
|
|
24899
24410
|
});
|
|
24900
24411
|
var OhMyOpenCodeConfigSchema = exports_external.object({
|
|
24901
24412
|
$schema: exports_external.string().optional(),
|
|
24413
|
+
new_task_system_enabled: exports_external.boolean().optional(),
|
|
24414
|
+
default_run_agent: exports_external.string().optional(),
|
|
24902
24415
|
disabled_mcps: exports_external.array(AnyMcpNameSchema).optional(),
|
|
24903
24416
|
disabled_agents: exports_external.array(BuiltinAgentNameSchema).optional(),
|
|
24904
24417
|
disabled_skills: exports_external.array(BuiltinSkillNameSchema).optional(),
|
|
24905
24418
|
disabled_hooks: exports_external.array(HookNameSchema).optional(),
|
|
24906
24419
|
disabled_commands: exports_external.array(BuiltinCommandNameSchema).optional(),
|
|
24420
|
+
disabled_tools: exports_external.array(exports_external.string()).optional(),
|
|
24907
24421
|
agents: AgentOverridesSchema.optional(),
|
|
24908
24422
|
categories: CategoriesConfigSchema.optional(),
|
|
24909
24423
|
claude_code: ClaudeCodeConfigSchema.optional(),
|
|
@@ -24921,10 +24435,792 @@ var OhMyOpenCodeConfigSchema = exports_external.object({
|
|
|
24921
24435
|
tmux: TmuxConfigSchema.optional(),
|
|
24922
24436
|
sisyphus: SisyphusConfigSchema.optional()
|
|
24923
24437
|
});
|
|
24438
|
+
// src/plugin-config.ts
|
|
24439
|
+
init_shared();
|
|
24440
|
+
function loadConfigFromPath(configPath, ctx) {
|
|
24441
|
+
try {
|
|
24442
|
+
if (fs3.existsSync(configPath)) {
|
|
24443
|
+
const content = fs3.readFileSync(configPath, "utf-8");
|
|
24444
|
+
const rawConfig = parseJsonc(content);
|
|
24445
|
+
migrateConfigFile(configPath, rawConfig);
|
|
24446
|
+
const result = OhMyOpenCodeConfigSchema.safeParse(rawConfig);
|
|
24447
|
+
if (!result.success) {
|
|
24448
|
+
const errorMsg = result.error.issues.map((i2) => `${i2.path.join(".")}: ${i2.message}`).join(", ");
|
|
24449
|
+
log(`Config validation error in ${configPath}:`, result.error.issues);
|
|
24450
|
+
addConfigLoadError({
|
|
24451
|
+
path: configPath,
|
|
24452
|
+
error: `Validation error: ${errorMsg}`
|
|
24453
|
+
});
|
|
24454
|
+
return null;
|
|
24455
|
+
}
|
|
24456
|
+
log(`Config loaded from ${configPath}`, { agents: result.data.agents });
|
|
24457
|
+
return result.data;
|
|
24458
|
+
}
|
|
24459
|
+
} catch (err) {
|
|
24460
|
+
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
24461
|
+
log(`Error loading config from ${configPath}:`, err);
|
|
24462
|
+
addConfigLoadError({ path: configPath, error: errorMsg });
|
|
24463
|
+
}
|
|
24464
|
+
return null;
|
|
24465
|
+
}
|
|
24466
|
+
function mergeConfigs2(base, override) {
|
|
24467
|
+
return {
|
|
24468
|
+
...base,
|
|
24469
|
+
...override,
|
|
24470
|
+
agents: deepMerge(base.agents, override.agents),
|
|
24471
|
+
categories: deepMerge(base.categories, override.categories),
|
|
24472
|
+
disabled_agents: [
|
|
24473
|
+
...new Set([
|
|
24474
|
+
...base.disabled_agents ?? [],
|
|
24475
|
+
...override.disabled_agents ?? []
|
|
24476
|
+
])
|
|
24477
|
+
],
|
|
24478
|
+
disabled_mcps: [
|
|
24479
|
+
...new Set([
|
|
24480
|
+
...base.disabled_mcps ?? [],
|
|
24481
|
+
...override.disabled_mcps ?? []
|
|
24482
|
+
])
|
|
24483
|
+
],
|
|
24484
|
+
disabled_hooks: [
|
|
24485
|
+
...new Set([
|
|
24486
|
+
...base.disabled_hooks ?? [],
|
|
24487
|
+
...override.disabled_hooks ?? []
|
|
24488
|
+
])
|
|
24489
|
+
],
|
|
24490
|
+
disabled_commands: [
|
|
24491
|
+
...new Set([
|
|
24492
|
+
...base.disabled_commands ?? [],
|
|
24493
|
+
...override.disabled_commands ?? []
|
|
24494
|
+
])
|
|
24495
|
+
],
|
|
24496
|
+
disabled_skills: [
|
|
24497
|
+
...new Set([
|
|
24498
|
+
...base.disabled_skills ?? [],
|
|
24499
|
+
...override.disabled_skills ?? []
|
|
24500
|
+
])
|
|
24501
|
+
],
|
|
24502
|
+
claude_code: deepMerge(base.claude_code, override.claude_code)
|
|
24503
|
+
};
|
|
24504
|
+
}
|
|
24505
|
+
function loadPluginConfig(directory, ctx) {
|
|
24506
|
+
const configDir = getOpenCodeConfigDir({ binary: "opencode" });
|
|
24507
|
+
const userBasePath = path3.join(configDir, "oh-my-opencode");
|
|
24508
|
+
const userDetected = detectConfigFile(userBasePath);
|
|
24509
|
+
const userConfigPath = userDetected.format !== "none" ? userDetected.path : userBasePath + ".json";
|
|
24510
|
+
const projectBasePath = path3.join(directory, ".opencode", "oh-my-opencode");
|
|
24511
|
+
const projectDetected = detectConfigFile(projectBasePath);
|
|
24512
|
+
const projectConfigPath = projectDetected.format !== "none" ? projectDetected.path : projectBasePath + ".json";
|
|
24513
|
+
let config2 = loadConfigFromPath(userConfigPath, ctx) ?? {};
|
|
24514
|
+
const projectConfig = loadConfigFromPath(projectConfigPath, ctx);
|
|
24515
|
+
if (projectConfig) {
|
|
24516
|
+
config2 = mergeConfigs2(config2, projectConfig);
|
|
24517
|
+
}
|
|
24518
|
+
config2 = {
|
|
24519
|
+
...config2
|
|
24520
|
+
};
|
|
24521
|
+
log("Final merged config", {
|
|
24522
|
+
agents: config2.agents,
|
|
24523
|
+
disabled_agents: config2.disabled_agents,
|
|
24524
|
+
disabled_mcps: config2.disabled_mcps,
|
|
24525
|
+
disabled_hooks: config2.disabled_hooks,
|
|
24526
|
+
claude_code: config2.claude_code
|
|
24527
|
+
});
|
|
24528
|
+
return config2;
|
|
24529
|
+
}
|
|
24530
|
+
|
|
24531
|
+
// src/cli/run/runner.ts
|
|
24532
|
+
var POLL_INTERVAL_MS = 500;
|
|
24533
|
+
var DEFAULT_TIMEOUT_MS = 0;
|
|
24534
|
+
var SESSION_CREATE_MAX_RETRIES = 3;
|
|
24535
|
+
var SESSION_CREATE_RETRY_DELAY_MS = 1000;
|
|
24536
|
+
var CORE_AGENT_ORDER = ["sisyphus", "hephaestus", "prometheus", "atlas"];
|
|
24537
|
+
var DEFAULT_AGENT = "sisyphus";
|
|
24538
|
+
var normalizeAgentName = (agent) => {
|
|
24539
|
+
if (!agent)
|
|
24540
|
+
return;
|
|
24541
|
+
const trimmed = agent.trim();
|
|
24542
|
+
if (!trimmed)
|
|
24543
|
+
return;
|
|
24544
|
+
const lowered = trimmed.toLowerCase();
|
|
24545
|
+
const coreMatch = CORE_AGENT_ORDER.find((name) => name.toLowerCase() === lowered);
|
|
24546
|
+
return coreMatch ?? trimmed;
|
|
24547
|
+
};
|
|
24548
|
+
var isAgentDisabled = (agent, config2) => {
|
|
24549
|
+
const lowered = agent.toLowerCase();
|
|
24550
|
+
if (lowered === "sisyphus" && config2.sisyphus_agent?.disabled === true) {
|
|
24551
|
+
return true;
|
|
24552
|
+
}
|
|
24553
|
+
return (config2.disabled_agents ?? []).some((disabled) => disabled.toLowerCase() === lowered);
|
|
24554
|
+
};
|
|
24555
|
+
var pickFallbackAgent = (config2) => {
|
|
24556
|
+
for (const agent of CORE_AGENT_ORDER) {
|
|
24557
|
+
if (!isAgentDisabled(agent, config2)) {
|
|
24558
|
+
return agent;
|
|
24559
|
+
}
|
|
24560
|
+
}
|
|
24561
|
+
return DEFAULT_AGENT;
|
|
24562
|
+
};
|
|
24563
|
+
var resolveRunAgent = (options, pluginConfig, env = process.env) => {
|
|
24564
|
+
const cliAgent = normalizeAgentName(options.agent);
|
|
24565
|
+
const envAgent = normalizeAgentName(env.OPENCODE_DEFAULT_AGENT);
|
|
24566
|
+
const configAgent = normalizeAgentName(pluginConfig.default_run_agent);
|
|
24567
|
+
const resolved = cliAgent ?? envAgent ?? configAgent ?? DEFAULT_AGENT;
|
|
24568
|
+
const normalized = normalizeAgentName(resolved) ?? DEFAULT_AGENT;
|
|
24569
|
+
if (isAgentDisabled(normalized, pluginConfig)) {
|
|
24570
|
+
const fallback = pickFallbackAgent(pluginConfig);
|
|
24571
|
+
const fallbackDisabled = isAgentDisabled(fallback, pluginConfig);
|
|
24572
|
+
if (fallbackDisabled) {
|
|
24573
|
+
console.log(import_picocolors5.default.yellow(`Requested agent "${normalized}" is disabled and no enabled core agent was found. Proceeding with "${fallback}".`));
|
|
24574
|
+
return fallback;
|
|
24575
|
+
}
|
|
24576
|
+
console.log(import_picocolors5.default.yellow(`Requested agent "${normalized}" is disabled. Falling back to "${fallback}".`));
|
|
24577
|
+
return fallback;
|
|
24578
|
+
}
|
|
24579
|
+
return normalized;
|
|
24580
|
+
};
|
|
24581
|
+
async function run(options) {
|
|
24582
|
+
process.env.OPENCODE_CLI_RUN_MODE = "true";
|
|
24583
|
+
const {
|
|
24584
|
+
message,
|
|
24585
|
+
directory = process.cwd(),
|
|
24586
|
+
timeout = DEFAULT_TIMEOUT_MS
|
|
24587
|
+
} = options;
|
|
24588
|
+
const pluginConfig = loadPluginConfig(directory, { command: "run" });
|
|
24589
|
+
const resolvedAgent = resolveRunAgent(options, pluginConfig);
|
|
24590
|
+
console.log(import_picocolors5.default.cyan("Starting opencode server..."));
|
|
24591
|
+
const abortController = new AbortController;
|
|
24592
|
+
let timeoutId = null;
|
|
24593
|
+
if (timeout > 0) {
|
|
24594
|
+
timeoutId = setTimeout(() => {
|
|
24595
|
+
console.log(import_picocolors5.default.yellow(`
|
|
24596
|
+
Timeout reached. Aborting...`));
|
|
24597
|
+
abortController.abort();
|
|
24598
|
+
}, timeout);
|
|
24599
|
+
}
|
|
24600
|
+
try {
|
|
24601
|
+
const serverPort = process.env.OPENCODE_SERVER_PORT ? parseInt(process.env.OPENCODE_SERVER_PORT, 10) : undefined;
|
|
24602
|
+
const serverHostname = process.env.OPENCODE_SERVER_HOSTNAME || undefined;
|
|
24603
|
+
const { client: client3, server: server2 } = await createOpencode({
|
|
24604
|
+
signal: abortController.signal,
|
|
24605
|
+
...serverPort && !isNaN(serverPort) ? { port: serverPort } : {},
|
|
24606
|
+
...serverHostname ? { hostname: serverHostname } : {}
|
|
24607
|
+
});
|
|
24608
|
+
const cleanup = () => {
|
|
24609
|
+
if (timeoutId)
|
|
24610
|
+
clearTimeout(timeoutId);
|
|
24611
|
+
server2.close();
|
|
24612
|
+
};
|
|
24613
|
+
process.on("SIGINT", () => {
|
|
24614
|
+
console.log(import_picocolors5.default.yellow(`
|
|
24615
|
+
Interrupted. Shutting down...`));
|
|
24616
|
+
cleanup();
|
|
24617
|
+
process.exit(130);
|
|
24618
|
+
});
|
|
24619
|
+
try {
|
|
24620
|
+
let sessionID;
|
|
24621
|
+
let lastError;
|
|
24622
|
+
for (let attempt = 1;attempt <= SESSION_CREATE_MAX_RETRIES; attempt++) {
|
|
24623
|
+
const sessionRes = await client3.session.create({
|
|
24624
|
+
body: { title: "oh-my-opencode run" }
|
|
24625
|
+
});
|
|
24626
|
+
if (sessionRes.error) {
|
|
24627
|
+
lastError = sessionRes.error;
|
|
24628
|
+
console.error(import_picocolors5.default.yellow(`Session create attempt ${attempt}/${SESSION_CREATE_MAX_RETRIES} failed:`));
|
|
24629
|
+
console.error(import_picocolors5.default.dim(` Error: ${serializeError(sessionRes.error)}`));
|
|
24630
|
+
if (attempt < SESSION_CREATE_MAX_RETRIES) {
|
|
24631
|
+
const delay = SESSION_CREATE_RETRY_DELAY_MS * attempt;
|
|
24632
|
+
console.log(import_picocolors5.default.dim(` Retrying in ${delay}ms...`));
|
|
24633
|
+
await new Promise((resolve2) => setTimeout(resolve2, delay));
|
|
24634
|
+
continue;
|
|
24635
|
+
}
|
|
24636
|
+
}
|
|
24637
|
+
sessionID = sessionRes.data?.id;
|
|
24638
|
+
if (sessionID) {
|
|
24639
|
+
break;
|
|
24640
|
+
}
|
|
24641
|
+
lastError = new Error(`Unexpected response: ${JSON.stringify(sessionRes, null, 2)}`);
|
|
24642
|
+
console.error(import_picocolors5.default.yellow(`Session create attempt ${attempt}/${SESSION_CREATE_MAX_RETRIES}: No session ID returned`));
|
|
24643
|
+
if (attempt < SESSION_CREATE_MAX_RETRIES) {
|
|
24644
|
+
const delay = SESSION_CREATE_RETRY_DELAY_MS * attempt;
|
|
24645
|
+
console.log(import_picocolors5.default.dim(` Retrying in ${delay}ms...`));
|
|
24646
|
+
await new Promise((resolve2) => setTimeout(resolve2, delay));
|
|
24647
|
+
}
|
|
24648
|
+
}
|
|
24649
|
+
if (!sessionID) {
|
|
24650
|
+
console.error(import_picocolors5.default.red("Failed to create session after all retries"));
|
|
24651
|
+
console.error(import_picocolors5.default.dim(`Last error: ${serializeError(lastError)}`));
|
|
24652
|
+
cleanup();
|
|
24653
|
+
return 1;
|
|
24654
|
+
}
|
|
24655
|
+
console.log(import_picocolors5.default.dim(`Session: ${sessionID}`));
|
|
24656
|
+
const ctx = {
|
|
24657
|
+
client: client3,
|
|
24658
|
+
sessionID,
|
|
24659
|
+
directory,
|
|
24660
|
+
abortController
|
|
24661
|
+
};
|
|
24662
|
+
const events = await client3.event.subscribe();
|
|
24663
|
+
const eventState = createEventState();
|
|
24664
|
+
const eventProcessor = processEvents(ctx, events.stream, eventState);
|
|
24665
|
+
console.log(import_picocolors5.default.dim(`
|
|
24666
|
+
Sending prompt...`));
|
|
24667
|
+
await client3.session.promptAsync({
|
|
24668
|
+
path: { id: sessionID },
|
|
24669
|
+
body: {
|
|
24670
|
+
agent: resolvedAgent,
|
|
24671
|
+
parts: [{ type: "text", text: message }]
|
|
24672
|
+
},
|
|
24673
|
+
query: { directory }
|
|
24674
|
+
});
|
|
24675
|
+
console.log(import_picocolors5.default.dim(`Waiting for completion...
|
|
24676
|
+
`));
|
|
24677
|
+
while (!abortController.signal.aborted) {
|
|
24678
|
+
await new Promise((resolve2) => setTimeout(resolve2, POLL_INTERVAL_MS));
|
|
24679
|
+
if (!eventState.mainSessionIdle) {
|
|
24680
|
+
continue;
|
|
24681
|
+
}
|
|
24682
|
+
if (eventState.mainSessionError) {
|
|
24683
|
+
console.error(import_picocolors5.default.red(`
|
|
24684
|
+
|
|
24685
|
+
Session ended with error: ${eventState.lastError}`));
|
|
24686
|
+
console.error(import_picocolors5.default.yellow("Check if todos were completed before the error."));
|
|
24687
|
+
cleanup();
|
|
24688
|
+
process.exit(1);
|
|
24689
|
+
}
|
|
24690
|
+
if (!eventState.hasReceivedMeaningfulWork) {
|
|
24691
|
+
continue;
|
|
24692
|
+
}
|
|
24693
|
+
const shouldExit = await checkCompletionConditions(ctx);
|
|
24694
|
+
if (shouldExit) {
|
|
24695
|
+
console.log(import_picocolors5.default.green(`
|
|
24696
|
+
|
|
24697
|
+
All tasks completed.`));
|
|
24698
|
+
cleanup();
|
|
24699
|
+
process.exit(0);
|
|
24700
|
+
}
|
|
24701
|
+
}
|
|
24702
|
+
await eventProcessor.catch(() => {});
|
|
24703
|
+
cleanup();
|
|
24704
|
+
return 130;
|
|
24705
|
+
} catch (err) {
|
|
24706
|
+
cleanup();
|
|
24707
|
+
throw err;
|
|
24708
|
+
}
|
|
24709
|
+
} catch (err) {
|
|
24710
|
+
if (timeoutId)
|
|
24711
|
+
clearTimeout(timeoutId);
|
|
24712
|
+
if (err instanceof Error && err.name === "AbortError") {
|
|
24713
|
+
return 130;
|
|
24714
|
+
}
|
|
24715
|
+
console.error(import_picocolors5.default.red(`Error: ${serializeError(err)}`));
|
|
24716
|
+
return 1;
|
|
24717
|
+
}
|
|
24718
|
+
}
|
|
24719
|
+
// src/cli/get-local-version/index.ts
|
|
24720
|
+
init_checker();
|
|
24721
|
+
|
|
24722
|
+
// src/cli/get-local-version/formatter.ts
|
|
24723
|
+
var import_picocolors6 = __toESM(require_picocolors(), 1);
|
|
24724
|
+
var SYMBOLS2 = {
|
|
24725
|
+
check: import_picocolors6.default.green("[OK]"),
|
|
24726
|
+
cross: import_picocolors6.default.red("[X]"),
|
|
24727
|
+
arrow: import_picocolors6.default.cyan("->"),
|
|
24728
|
+
info: import_picocolors6.default.blue("[i]"),
|
|
24729
|
+
warn: import_picocolors6.default.yellow("[!]"),
|
|
24730
|
+
pin: import_picocolors6.default.magenta("[PINNED]"),
|
|
24731
|
+
dev: import_picocolors6.default.cyan("[DEV]")
|
|
24732
|
+
};
|
|
24733
|
+
function formatVersionOutput(info) {
|
|
24734
|
+
const lines = [];
|
|
24735
|
+
lines.push("");
|
|
24736
|
+
lines.push(import_picocolors6.default.bold(import_picocolors6.default.white("oh-my-opencode Version Information")));
|
|
24737
|
+
lines.push(import_picocolors6.default.dim("\u2500".repeat(50)));
|
|
24738
|
+
lines.push("");
|
|
24739
|
+
if (info.currentVersion) {
|
|
24740
|
+
lines.push(` Current Version: ${import_picocolors6.default.cyan(info.currentVersion)}`);
|
|
24741
|
+
} else {
|
|
24742
|
+
lines.push(` Current Version: ${import_picocolors6.default.dim("unknown")}`);
|
|
24743
|
+
}
|
|
24744
|
+
if (!info.isLocalDev && info.latestVersion) {
|
|
24745
|
+
lines.push(` Latest Version: ${import_picocolors6.default.cyan(info.latestVersion)}`);
|
|
24746
|
+
}
|
|
24747
|
+
lines.push("");
|
|
24748
|
+
switch (info.status) {
|
|
24749
|
+
case "up-to-date":
|
|
24750
|
+
lines.push(` ${SYMBOLS2.check} ${import_picocolors6.default.green("You're up to date!")}`);
|
|
24751
|
+
break;
|
|
24752
|
+
case "outdated":
|
|
24753
|
+
lines.push(` ${SYMBOLS2.warn} ${import_picocolors6.default.yellow("Update available")}`);
|
|
24754
|
+
lines.push(` ${import_picocolors6.default.dim("Run:")} ${import_picocolors6.default.cyan("cd ~/.config/opencode && bun update oh-my-opencode")}`);
|
|
24755
|
+
break;
|
|
24756
|
+
case "local-dev":
|
|
24757
|
+
lines.push(` ${SYMBOLS2.dev} ${import_picocolors6.default.cyan("Running in local development mode")}`);
|
|
24758
|
+
lines.push(` ${import_picocolors6.default.dim("Using file:// protocol from config")}`);
|
|
24759
|
+
break;
|
|
24760
|
+
case "pinned":
|
|
24761
|
+
lines.push(` ${SYMBOLS2.pin} ${import_picocolors6.default.magenta(`Version pinned to ${info.pinnedVersion}`)}`);
|
|
24762
|
+
lines.push(` ${import_picocolors6.default.dim("Update check skipped for pinned versions")}`);
|
|
24763
|
+
break;
|
|
24764
|
+
case "error":
|
|
24765
|
+
lines.push(` ${SYMBOLS2.cross} ${import_picocolors6.default.red("Unable to check for updates")}`);
|
|
24766
|
+
lines.push(` ${import_picocolors6.default.dim("Network error or npm registry unavailable")}`);
|
|
24767
|
+
break;
|
|
24768
|
+
case "unknown":
|
|
24769
|
+
lines.push(` ${SYMBOLS2.info} ${import_picocolors6.default.yellow("Version information unavailable")}`);
|
|
24770
|
+
break;
|
|
24771
|
+
}
|
|
24772
|
+
lines.push("");
|
|
24773
|
+
return lines.join(`
|
|
24774
|
+
`);
|
|
24775
|
+
}
|
|
24776
|
+
function formatJsonOutput(info) {
|
|
24777
|
+
return JSON.stringify(info, null, 2);
|
|
24778
|
+
}
|
|
24779
|
+
|
|
24780
|
+
// src/cli/get-local-version/index.ts
|
|
24781
|
+
async function getLocalVersion(options = {}) {
|
|
24782
|
+
const directory = options.directory ?? process.cwd();
|
|
24783
|
+
try {
|
|
24784
|
+
if (isLocalDevMode(directory)) {
|
|
24785
|
+
const currentVersion2 = getCachedVersion();
|
|
24786
|
+
const info2 = {
|
|
24787
|
+
currentVersion: currentVersion2,
|
|
24788
|
+
latestVersion: null,
|
|
24789
|
+
isUpToDate: false,
|
|
24790
|
+
isLocalDev: true,
|
|
24791
|
+
isPinned: false,
|
|
24792
|
+
pinnedVersion: null,
|
|
24793
|
+
status: "local-dev"
|
|
24794
|
+
};
|
|
24795
|
+
console.log(options.json ? formatJsonOutput(info2) : formatVersionOutput(info2));
|
|
24796
|
+
return 0;
|
|
24797
|
+
}
|
|
24798
|
+
const pluginInfo = findPluginEntry(directory);
|
|
24799
|
+
if (pluginInfo?.isPinned) {
|
|
24800
|
+
const info2 = {
|
|
24801
|
+
currentVersion: pluginInfo.pinnedVersion,
|
|
24802
|
+
latestVersion: null,
|
|
24803
|
+
isUpToDate: false,
|
|
24804
|
+
isLocalDev: false,
|
|
24805
|
+
isPinned: true,
|
|
24806
|
+
pinnedVersion: pluginInfo.pinnedVersion,
|
|
24807
|
+
status: "pinned"
|
|
24808
|
+
};
|
|
24809
|
+
console.log(options.json ? formatJsonOutput(info2) : formatVersionOutput(info2));
|
|
24810
|
+
return 0;
|
|
24811
|
+
}
|
|
24812
|
+
const currentVersion = getCachedVersion();
|
|
24813
|
+
if (!currentVersion) {
|
|
24814
|
+
const info2 = {
|
|
24815
|
+
currentVersion: null,
|
|
24816
|
+
latestVersion: null,
|
|
24817
|
+
isUpToDate: false,
|
|
24818
|
+
isLocalDev: false,
|
|
24819
|
+
isPinned: false,
|
|
24820
|
+
pinnedVersion: null,
|
|
24821
|
+
status: "unknown"
|
|
24822
|
+
};
|
|
24823
|
+
console.log(options.json ? formatJsonOutput(info2) : formatVersionOutput(info2));
|
|
24824
|
+
return 1;
|
|
24825
|
+
}
|
|
24826
|
+
const { extractChannel: extractChannel2 } = await Promise.resolve().then(() => (init_auto_update_checker(), exports_auto_update_checker));
|
|
24827
|
+
const channel = extractChannel2(pluginInfo?.pinnedVersion ?? currentVersion);
|
|
24828
|
+
const latestVersion = await getLatestVersion(channel);
|
|
24829
|
+
if (!latestVersion) {
|
|
24830
|
+
const info2 = {
|
|
24831
|
+
currentVersion,
|
|
24832
|
+
latestVersion: null,
|
|
24833
|
+
isUpToDate: false,
|
|
24834
|
+
isLocalDev: false,
|
|
24835
|
+
isPinned: false,
|
|
24836
|
+
pinnedVersion: null,
|
|
24837
|
+
status: "error"
|
|
24838
|
+
};
|
|
24839
|
+
console.log(options.json ? formatJsonOutput(info2) : formatVersionOutput(info2));
|
|
24840
|
+
return 0;
|
|
24841
|
+
}
|
|
24842
|
+
const isUpToDate = currentVersion === latestVersion;
|
|
24843
|
+
const info = {
|
|
24844
|
+
currentVersion,
|
|
24845
|
+
latestVersion,
|
|
24846
|
+
isUpToDate,
|
|
24847
|
+
isLocalDev: false,
|
|
24848
|
+
isPinned: false,
|
|
24849
|
+
pinnedVersion: null,
|
|
24850
|
+
status: isUpToDate ? "up-to-date" : "outdated"
|
|
24851
|
+
};
|
|
24852
|
+
console.log(options.json ? formatJsonOutput(info) : formatVersionOutput(info));
|
|
24853
|
+
return 0;
|
|
24854
|
+
} catch (error48) {
|
|
24855
|
+
const info = {
|
|
24856
|
+
currentVersion: null,
|
|
24857
|
+
latestVersion: null,
|
|
24858
|
+
isUpToDate: false,
|
|
24859
|
+
isLocalDev: false,
|
|
24860
|
+
isPinned: false,
|
|
24861
|
+
pinnedVersion: null,
|
|
24862
|
+
status: "error"
|
|
24863
|
+
};
|
|
24864
|
+
console.log(options.json ? formatJsonOutput(info) : formatVersionOutput(info));
|
|
24865
|
+
return 1;
|
|
24866
|
+
}
|
|
24867
|
+
}
|
|
24868
|
+
|
|
24869
|
+
// src/cli/doctor/checks/opencode.ts
|
|
24870
|
+
import { existsSync as existsSync9 } from "fs";
|
|
24871
|
+
import { homedir as homedir5 } from "os";
|
|
24872
|
+
import { join as join11 } from "path";
|
|
24873
|
+
|
|
24874
|
+
// src/cli/doctor/constants.ts
|
|
24875
|
+
var import_picocolors7 = __toESM(require_picocolors(), 1);
|
|
24876
|
+
var SYMBOLS3 = {
|
|
24877
|
+
check: import_picocolors7.default.green("\u2713"),
|
|
24878
|
+
cross: import_picocolors7.default.red("\u2717"),
|
|
24879
|
+
warn: import_picocolors7.default.yellow("\u26A0"),
|
|
24880
|
+
info: import_picocolors7.default.blue("\u2139"),
|
|
24881
|
+
arrow: import_picocolors7.default.cyan("\u2192"),
|
|
24882
|
+
bullet: import_picocolors7.default.dim("\u2022"),
|
|
24883
|
+
skip: import_picocolors7.default.dim("\u25CB")
|
|
24884
|
+
};
|
|
24885
|
+
var STATUS_COLORS = {
|
|
24886
|
+
pass: import_picocolors7.default.green,
|
|
24887
|
+
fail: import_picocolors7.default.red,
|
|
24888
|
+
warn: import_picocolors7.default.yellow,
|
|
24889
|
+
skip: import_picocolors7.default.dim
|
|
24890
|
+
};
|
|
24891
|
+
var CHECK_IDS = {
|
|
24892
|
+
OPENCODE_INSTALLATION: "opencode-installation",
|
|
24893
|
+
PLUGIN_REGISTRATION: "plugin-registration",
|
|
24894
|
+
CONFIG_VALIDATION: "config-validation",
|
|
24895
|
+
MODEL_RESOLUTION: "model-resolution",
|
|
24896
|
+
AUTH_ANTHROPIC: "auth-anthropic",
|
|
24897
|
+
AUTH_OPENAI: "auth-openai",
|
|
24898
|
+
AUTH_GOOGLE: "auth-google",
|
|
24899
|
+
DEP_AST_GREP_CLI: "dep-ast-grep-cli",
|
|
24900
|
+
DEP_AST_GREP_NAPI: "dep-ast-grep-napi",
|
|
24901
|
+
DEP_COMMENT_CHECKER: "dep-comment-checker",
|
|
24902
|
+
GH_CLI: "gh-cli",
|
|
24903
|
+
LSP_SERVERS: "lsp-servers",
|
|
24904
|
+
MCP_BUILTIN: "mcp-builtin",
|
|
24905
|
+
MCP_USER: "mcp-user",
|
|
24906
|
+
MCP_OAUTH_TOKENS: "mcp-oauth-tokens",
|
|
24907
|
+
VERSION_STATUS: "version-status"
|
|
24908
|
+
};
|
|
24909
|
+
var CHECK_NAMES = {
|
|
24910
|
+
[CHECK_IDS.OPENCODE_INSTALLATION]: "OpenCode Installation",
|
|
24911
|
+
[CHECK_IDS.PLUGIN_REGISTRATION]: "Plugin Registration",
|
|
24912
|
+
[CHECK_IDS.CONFIG_VALIDATION]: "Configuration Validity",
|
|
24913
|
+
[CHECK_IDS.MODEL_RESOLUTION]: "Model Resolution",
|
|
24914
|
+
[CHECK_IDS.AUTH_ANTHROPIC]: "Anthropic (Claude) Auth",
|
|
24915
|
+
[CHECK_IDS.AUTH_OPENAI]: "OpenAI (ChatGPT) Auth",
|
|
24916
|
+
[CHECK_IDS.AUTH_GOOGLE]: "Google (Gemini) Auth",
|
|
24917
|
+
[CHECK_IDS.DEP_AST_GREP_CLI]: "AST-Grep CLI",
|
|
24918
|
+
[CHECK_IDS.DEP_AST_GREP_NAPI]: "AST-Grep NAPI",
|
|
24919
|
+
[CHECK_IDS.DEP_COMMENT_CHECKER]: "Comment Checker",
|
|
24920
|
+
[CHECK_IDS.GH_CLI]: "GitHub CLI",
|
|
24921
|
+
[CHECK_IDS.LSP_SERVERS]: "LSP Servers",
|
|
24922
|
+
[CHECK_IDS.MCP_BUILTIN]: "Built-in MCP Servers",
|
|
24923
|
+
[CHECK_IDS.MCP_USER]: "User MCP Configuration",
|
|
24924
|
+
[CHECK_IDS.MCP_OAUTH_TOKENS]: "MCP OAuth Tokens",
|
|
24925
|
+
[CHECK_IDS.VERSION_STATUS]: "Version Status"
|
|
24926
|
+
};
|
|
24927
|
+
var CATEGORY_NAMES = {
|
|
24928
|
+
installation: "Installation",
|
|
24929
|
+
configuration: "Configuration",
|
|
24930
|
+
authentication: "Authentication",
|
|
24931
|
+
dependencies: "Dependencies",
|
|
24932
|
+
tools: "Tools & Servers",
|
|
24933
|
+
updates: "Updates"
|
|
24934
|
+
};
|
|
24935
|
+
var EXIT_CODES = {
|
|
24936
|
+
SUCCESS: 0,
|
|
24937
|
+
FAILURE: 1
|
|
24938
|
+
};
|
|
24939
|
+
var MIN_OPENCODE_VERSION = "1.0.150";
|
|
24940
|
+
var PACKAGE_NAME3 = "oh-my-opencode";
|
|
24941
|
+
var OPENCODE_BINARIES2 = ["opencode", "opencode-desktop"];
|
|
24942
|
+
|
|
24943
|
+
// src/cli/doctor/checks/opencode.ts
|
|
24944
|
+
function getDesktopAppPaths(platform) {
|
|
24945
|
+
const home = homedir5();
|
|
24946
|
+
switch (platform) {
|
|
24947
|
+
case "darwin":
|
|
24948
|
+
return [
|
|
24949
|
+
"/Applications/OpenCode.app/Contents/MacOS/OpenCode",
|
|
24950
|
+
join11(home, "Applications", "OpenCode.app", "Contents", "MacOS", "OpenCode")
|
|
24951
|
+
];
|
|
24952
|
+
case "win32": {
|
|
24953
|
+
const programFiles = process.env.ProgramFiles;
|
|
24954
|
+
const localAppData = process.env.LOCALAPPDATA;
|
|
24955
|
+
const paths = [];
|
|
24956
|
+
if (programFiles) {
|
|
24957
|
+
paths.push(join11(programFiles, "OpenCode", "OpenCode.exe"));
|
|
24958
|
+
}
|
|
24959
|
+
if (localAppData) {
|
|
24960
|
+
paths.push(join11(localAppData, "OpenCode", "OpenCode.exe"));
|
|
24961
|
+
}
|
|
24962
|
+
return paths;
|
|
24963
|
+
}
|
|
24964
|
+
case "linux":
|
|
24965
|
+
return [
|
|
24966
|
+
"/usr/bin/opencode",
|
|
24967
|
+
"/usr/lib/opencode/opencode",
|
|
24968
|
+
join11(home, "Applications", "opencode-desktop-linux-x86_64.AppImage"),
|
|
24969
|
+
join11(home, "Applications", "opencode-desktop-linux-aarch64.AppImage")
|
|
24970
|
+
];
|
|
24971
|
+
default:
|
|
24972
|
+
return [];
|
|
24973
|
+
}
|
|
24974
|
+
}
|
|
24975
|
+
function buildVersionCommand(binaryPath, platform) {
|
|
24976
|
+
if (platform === "win32" && binaryPath.toLowerCase().endsWith(".ps1")) {
|
|
24977
|
+
return [
|
|
24978
|
+
"powershell",
|
|
24979
|
+
"-NoProfile",
|
|
24980
|
+
"-ExecutionPolicy",
|
|
24981
|
+
"Bypass",
|
|
24982
|
+
"-File",
|
|
24983
|
+
binaryPath,
|
|
24984
|
+
"--version"
|
|
24985
|
+
];
|
|
24986
|
+
}
|
|
24987
|
+
return [binaryPath, "--version"];
|
|
24988
|
+
}
|
|
24989
|
+
function findDesktopBinary(platform = process.platform, checkExists = existsSync9) {
|
|
24990
|
+
const desktopPaths = getDesktopAppPaths(platform);
|
|
24991
|
+
for (const desktopPath of desktopPaths) {
|
|
24992
|
+
if (checkExists(desktopPath)) {
|
|
24993
|
+
return { binary: "opencode", path: desktopPath };
|
|
24994
|
+
}
|
|
24995
|
+
}
|
|
24996
|
+
return null;
|
|
24997
|
+
}
|
|
24998
|
+
async function findOpenCodeBinary() {
|
|
24999
|
+
for (const binary2 of OPENCODE_BINARIES2) {
|
|
25000
|
+
try {
|
|
25001
|
+
const path7 = Bun.which(binary2);
|
|
25002
|
+
if (path7) {
|
|
25003
|
+
return { binary: binary2, path: path7 };
|
|
25004
|
+
}
|
|
25005
|
+
} catch {
|
|
25006
|
+
continue;
|
|
25007
|
+
}
|
|
25008
|
+
}
|
|
25009
|
+
const desktopResult = findDesktopBinary();
|
|
25010
|
+
if (desktopResult) {
|
|
25011
|
+
return desktopResult;
|
|
25012
|
+
}
|
|
25013
|
+
return null;
|
|
25014
|
+
}
|
|
25015
|
+
async function getOpenCodeVersion2(binaryPath, platform = process.platform) {
|
|
25016
|
+
try {
|
|
25017
|
+
const command = buildVersionCommand(binaryPath, platform);
|
|
25018
|
+
const proc = Bun.spawn(command, { stdout: "pipe", stderr: "pipe" });
|
|
25019
|
+
const output = await new Response(proc.stdout).text();
|
|
25020
|
+
await proc.exited;
|
|
25021
|
+
if (proc.exitCode === 0) {
|
|
25022
|
+
return output.trim();
|
|
25023
|
+
}
|
|
25024
|
+
} catch {
|
|
25025
|
+
return null;
|
|
25026
|
+
}
|
|
25027
|
+
return null;
|
|
25028
|
+
}
|
|
25029
|
+
function compareVersions(current, minimum) {
|
|
25030
|
+
const parseVersion = (v) => {
|
|
25031
|
+
const cleaned = v.replace(/^v/, "").split("-")[0];
|
|
25032
|
+
return cleaned.split(".").map((n) => parseInt(n, 10) || 0);
|
|
25033
|
+
};
|
|
25034
|
+
const curr = parseVersion(current);
|
|
25035
|
+
const min = parseVersion(minimum);
|
|
25036
|
+
for (let i2 = 0;i2 < Math.max(curr.length, min.length); i2++) {
|
|
25037
|
+
const c = curr[i2] ?? 0;
|
|
25038
|
+
const m2 = min[i2] ?? 0;
|
|
25039
|
+
if (c > m2)
|
|
25040
|
+
return true;
|
|
25041
|
+
if (c < m2)
|
|
25042
|
+
return false;
|
|
25043
|
+
}
|
|
25044
|
+
return true;
|
|
25045
|
+
}
|
|
25046
|
+
async function getOpenCodeInfo() {
|
|
25047
|
+
const binaryInfo = await findOpenCodeBinary();
|
|
25048
|
+
if (!binaryInfo) {
|
|
25049
|
+
return {
|
|
25050
|
+
installed: false,
|
|
25051
|
+
version: null,
|
|
25052
|
+
path: null,
|
|
25053
|
+
binary: null
|
|
25054
|
+
};
|
|
25055
|
+
}
|
|
25056
|
+
const version2 = await getOpenCodeVersion2(binaryInfo.path ?? binaryInfo.binary);
|
|
25057
|
+
return {
|
|
25058
|
+
installed: true,
|
|
25059
|
+
version: version2,
|
|
25060
|
+
path: binaryInfo.path,
|
|
25061
|
+
binary: binaryInfo.binary
|
|
25062
|
+
};
|
|
25063
|
+
}
|
|
25064
|
+
async function checkOpenCodeInstallation() {
|
|
25065
|
+
const info = await getOpenCodeInfo();
|
|
25066
|
+
if (!info.installed) {
|
|
25067
|
+
return {
|
|
25068
|
+
name: CHECK_NAMES[CHECK_IDS.OPENCODE_INSTALLATION],
|
|
25069
|
+
status: "fail",
|
|
25070
|
+
message: "OpenCode is not installed",
|
|
25071
|
+
details: [
|
|
25072
|
+
"Visit: https://opencode.ai/docs for installation instructions",
|
|
25073
|
+
"Run: npm install -g opencode"
|
|
25074
|
+
]
|
|
25075
|
+
};
|
|
25076
|
+
}
|
|
25077
|
+
if (info.version && !compareVersions(info.version, MIN_OPENCODE_VERSION)) {
|
|
25078
|
+
return {
|
|
25079
|
+
name: CHECK_NAMES[CHECK_IDS.OPENCODE_INSTALLATION],
|
|
25080
|
+
status: "warn",
|
|
25081
|
+
message: `Version ${info.version} is below minimum ${MIN_OPENCODE_VERSION}`,
|
|
25082
|
+
details: [
|
|
25083
|
+
`Current: ${info.version}`,
|
|
25084
|
+
`Required: >= ${MIN_OPENCODE_VERSION}`,
|
|
25085
|
+
"Run: npm update -g opencode"
|
|
25086
|
+
]
|
|
25087
|
+
};
|
|
25088
|
+
}
|
|
25089
|
+
return {
|
|
25090
|
+
name: CHECK_NAMES[CHECK_IDS.OPENCODE_INSTALLATION],
|
|
25091
|
+
status: "pass",
|
|
25092
|
+
message: info.version ?? "installed",
|
|
25093
|
+
details: info.path ? [`Path: ${info.path}`] : undefined
|
|
25094
|
+
};
|
|
25095
|
+
}
|
|
25096
|
+
function getOpenCodeCheckDefinition() {
|
|
25097
|
+
return {
|
|
25098
|
+
id: CHECK_IDS.OPENCODE_INSTALLATION,
|
|
25099
|
+
name: CHECK_NAMES[CHECK_IDS.OPENCODE_INSTALLATION],
|
|
25100
|
+
category: "installation",
|
|
25101
|
+
check: checkOpenCodeInstallation,
|
|
25102
|
+
critical: true
|
|
25103
|
+
};
|
|
25104
|
+
}
|
|
25105
|
+
|
|
25106
|
+
// src/cli/doctor/checks/plugin.ts
|
|
25107
|
+
import { existsSync as existsSync10, readFileSync as readFileSync8 } from "fs";
|
|
25108
|
+
init_shared();
|
|
25109
|
+
function detectConfigPath() {
|
|
25110
|
+
const paths = getOpenCodeConfigPaths({ binary: "opencode", version: null });
|
|
25111
|
+
if (existsSync10(paths.configJsonc)) {
|
|
25112
|
+
return { path: paths.configJsonc, format: "jsonc" };
|
|
25113
|
+
}
|
|
25114
|
+
if (existsSync10(paths.configJson)) {
|
|
25115
|
+
return { path: paths.configJson, format: "json" };
|
|
25116
|
+
}
|
|
25117
|
+
return null;
|
|
25118
|
+
}
|
|
25119
|
+
function findPluginEntry2(plugins) {
|
|
25120
|
+
for (const plugin of plugins) {
|
|
25121
|
+
if (plugin === PACKAGE_NAME3 || plugin.startsWith(`${PACKAGE_NAME3}@`)) {
|
|
25122
|
+
const isPinned = plugin.includes("@");
|
|
25123
|
+
const version2 = isPinned ? plugin.split("@")[1] : null;
|
|
25124
|
+
return { entry: plugin, isPinned, version: version2 };
|
|
25125
|
+
}
|
|
25126
|
+
if (plugin.startsWith("file://") && plugin.includes(PACKAGE_NAME3)) {
|
|
25127
|
+
return { entry: plugin, isPinned: false, version: "local-dev" };
|
|
25128
|
+
}
|
|
25129
|
+
}
|
|
25130
|
+
return null;
|
|
25131
|
+
}
|
|
25132
|
+
function getPluginInfo() {
|
|
25133
|
+
const configInfo = detectConfigPath();
|
|
25134
|
+
if (!configInfo) {
|
|
25135
|
+
return {
|
|
25136
|
+
registered: false,
|
|
25137
|
+
configPath: null,
|
|
25138
|
+
entry: null,
|
|
25139
|
+
isPinned: false,
|
|
25140
|
+
pinnedVersion: null
|
|
25141
|
+
};
|
|
25142
|
+
}
|
|
25143
|
+
try {
|
|
25144
|
+
const content = readFileSync8(configInfo.path, "utf-8");
|
|
25145
|
+
const config2 = parseJsonc(content);
|
|
25146
|
+
const plugins = config2.plugin ?? [];
|
|
25147
|
+
const pluginEntry = findPluginEntry2(plugins);
|
|
25148
|
+
if (!pluginEntry) {
|
|
25149
|
+
return {
|
|
25150
|
+
registered: false,
|
|
25151
|
+
configPath: configInfo.path,
|
|
25152
|
+
entry: null,
|
|
25153
|
+
isPinned: false,
|
|
25154
|
+
pinnedVersion: null
|
|
25155
|
+
};
|
|
25156
|
+
}
|
|
25157
|
+
return {
|
|
25158
|
+
registered: true,
|
|
25159
|
+
configPath: configInfo.path,
|
|
25160
|
+
entry: pluginEntry.entry,
|
|
25161
|
+
isPinned: pluginEntry.isPinned,
|
|
25162
|
+
pinnedVersion: pluginEntry.version
|
|
25163
|
+
};
|
|
25164
|
+
} catch {
|
|
25165
|
+
return {
|
|
25166
|
+
registered: false,
|
|
25167
|
+
configPath: configInfo.path,
|
|
25168
|
+
entry: null,
|
|
25169
|
+
isPinned: false,
|
|
25170
|
+
pinnedVersion: null
|
|
25171
|
+
};
|
|
25172
|
+
}
|
|
25173
|
+
}
|
|
25174
|
+
async function checkPluginRegistration() {
|
|
25175
|
+
const info = getPluginInfo();
|
|
25176
|
+
if (!info.configPath) {
|
|
25177
|
+
const expectedPaths = getOpenCodeConfigPaths({ binary: "opencode", version: null });
|
|
25178
|
+
return {
|
|
25179
|
+
name: CHECK_NAMES[CHECK_IDS.PLUGIN_REGISTRATION],
|
|
25180
|
+
status: "fail",
|
|
25181
|
+
message: "OpenCode config file not found",
|
|
25182
|
+
details: [
|
|
25183
|
+
"Run: bunx oh-my-opencode install",
|
|
25184
|
+
`Expected: ${expectedPaths.configJson} or ${expectedPaths.configJsonc}`
|
|
25185
|
+
]
|
|
25186
|
+
};
|
|
25187
|
+
}
|
|
25188
|
+
if (!info.registered) {
|
|
25189
|
+
return {
|
|
25190
|
+
name: CHECK_NAMES[CHECK_IDS.PLUGIN_REGISTRATION],
|
|
25191
|
+
status: "fail",
|
|
25192
|
+
message: "Plugin not registered in config",
|
|
25193
|
+
details: [
|
|
25194
|
+
"Run: bunx oh-my-opencode install",
|
|
25195
|
+
`Config: ${info.configPath}`
|
|
25196
|
+
]
|
|
25197
|
+
};
|
|
25198
|
+
}
|
|
25199
|
+
const message = info.isPinned ? `Registered (pinned: ${info.pinnedVersion})` : "Registered";
|
|
25200
|
+
return {
|
|
25201
|
+
name: CHECK_NAMES[CHECK_IDS.PLUGIN_REGISTRATION],
|
|
25202
|
+
status: "pass",
|
|
25203
|
+
message,
|
|
25204
|
+
details: [`Config: ${info.configPath}`]
|
|
25205
|
+
};
|
|
25206
|
+
}
|
|
25207
|
+
function getPluginCheckDefinition() {
|
|
25208
|
+
return {
|
|
25209
|
+
id: CHECK_IDS.PLUGIN_REGISTRATION,
|
|
25210
|
+
name: CHECK_NAMES[CHECK_IDS.PLUGIN_REGISTRATION],
|
|
25211
|
+
category: "installation",
|
|
25212
|
+
check: checkPluginRegistration,
|
|
25213
|
+
critical: true
|
|
25214
|
+
};
|
|
25215
|
+
}
|
|
25216
|
+
|
|
24924
25217
|
// src/cli/doctor/checks/config.ts
|
|
25218
|
+
import { existsSync as existsSync11, readFileSync as readFileSync9 } from "fs";
|
|
25219
|
+
import { join as join12 } from "path";
|
|
25220
|
+
init_shared();
|
|
24925
25221
|
var USER_CONFIG_DIR2 = getOpenCodeConfigDir({ binary: "opencode" });
|
|
24926
|
-
var USER_CONFIG_BASE =
|
|
24927
|
-
var PROJECT_CONFIG_BASE =
|
|
25222
|
+
var USER_CONFIG_BASE = join12(USER_CONFIG_DIR2, `${PACKAGE_NAME3}`);
|
|
25223
|
+
var PROJECT_CONFIG_BASE = join12(process.cwd(), ".opencode", PACKAGE_NAME3);
|
|
24928
25224
|
function findConfigPath() {
|
|
24929
25225
|
const projectDetected = detectConfigFile(PROJECT_CONFIG_BASE);
|
|
24930
25226
|
if (projectDetected.format !== "none") {
|
|
@@ -24938,7 +25234,7 @@ function findConfigPath() {
|
|
|
24938
25234
|
}
|
|
24939
25235
|
function validateConfig(configPath) {
|
|
24940
25236
|
try {
|
|
24941
|
-
const content =
|
|
25237
|
+
const content = readFileSync9(configPath, "utf-8");
|
|
24942
25238
|
const rawConfig = parseJsonc(content);
|
|
24943
25239
|
const result = OhMyOpenCodeConfigSchema.safeParse(rawConfig);
|
|
24944
25240
|
if (!result.success) {
|
|
@@ -24964,7 +25260,7 @@ function getConfigInfo() {
|
|
|
24964
25260
|
errors: []
|
|
24965
25261
|
};
|
|
24966
25262
|
}
|
|
24967
|
-
if (!
|
|
25263
|
+
if (!existsSync11(configPath.path)) {
|
|
24968
25264
|
return {
|
|
24969
25265
|
exists: false,
|
|
24970
25266
|
path: configPath.path,
|
|
@@ -25021,24 +25317,24 @@ function getConfigCheckDefinition() {
|
|
|
25021
25317
|
}
|
|
25022
25318
|
|
|
25023
25319
|
// src/cli/doctor/checks/model-resolution.ts
|
|
25024
|
-
import { readFileSync as
|
|
25320
|
+
import { readFileSync as readFileSync10, existsSync as existsSync12 } from "fs";
|
|
25025
25321
|
init_shared();
|
|
25026
25322
|
init_model_requirements();
|
|
25027
25323
|
import { homedir as homedir6 } from "os";
|
|
25028
|
-
import { join as
|
|
25324
|
+
import { join as join13 } from "path";
|
|
25029
25325
|
function getOpenCodeCacheDir2() {
|
|
25030
25326
|
const xdgCache = process.env.XDG_CACHE_HOME;
|
|
25031
25327
|
if (xdgCache)
|
|
25032
|
-
return
|
|
25033
|
-
return
|
|
25328
|
+
return join13(xdgCache, "opencode");
|
|
25329
|
+
return join13(homedir6(), ".cache", "opencode");
|
|
25034
25330
|
}
|
|
25035
25331
|
function loadAvailableModels() {
|
|
25036
|
-
const cacheFile =
|
|
25037
|
-
if (!
|
|
25332
|
+
const cacheFile = join13(getOpenCodeCacheDir2(), "models.json");
|
|
25333
|
+
if (!existsSync12(cacheFile)) {
|
|
25038
25334
|
return { providers: [], modelCount: 0, cacheExists: false };
|
|
25039
25335
|
}
|
|
25040
25336
|
try {
|
|
25041
|
-
const content =
|
|
25337
|
+
const content = readFileSync10(cacheFile, "utf-8");
|
|
25042
25338
|
const data = JSON.parse(content);
|
|
25043
25339
|
const providers = Object.keys(data);
|
|
25044
25340
|
let modelCount = 0;
|
|
@@ -25054,14 +25350,14 @@ function loadAvailableModels() {
|
|
|
25054
25350
|
}
|
|
25055
25351
|
}
|
|
25056
25352
|
var PACKAGE_NAME4 = "oh-my-opencode";
|
|
25057
|
-
var USER_CONFIG_DIR3 =
|
|
25058
|
-
var USER_CONFIG_BASE2 =
|
|
25059
|
-
var PROJECT_CONFIG_BASE2 =
|
|
25353
|
+
var USER_CONFIG_DIR3 = join13(homedir6(), ".config", "opencode");
|
|
25354
|
+
var USER_CONFIG_BASE2 = join13(USER_CONFIG_DIR3, PACKAGE_NAME4);
|
|
25355
|
+
var PROJECT_CONFIG_BASE2 = join13(process.cwd(), ".opencode", PACKAGE_NAME4);
|
|
25060
25356
|
function loadConfig() {
|
|
25061
25357
|
const projectDetected = detectConfigFile(PROJECT_CONFIG_BASE2);
|
|
25062
25358
|
if (projectDetected.format !== "none") {
|
|
25063
25359
|
try {
|
|
25064
|
-
const content =
|
|
25360
|
+
const content = readFileSync10(projectDetected.path, "utf-8");
|
|
25065
25361
|
return parseJsonc(content);
|
|
25066
25362
|
} catch {
|
|
25067
25363
|
return null;
|
|
@@ -25070,7 +25366,7 @@ function loadConfig() {
|
|
|
25070
25366
|
const userDetected = detectConfigFile(USER_CONFIG_BASE2);
|
|
25071
25367
|
if (userDetected.format !== "none") {
|
|
25072
25368
|
try {
|
|
25073
|
-
const content =
|
|
25369
|
+
const content = readFileSync10(userDetected.path, "utf-8");
|
|
25074
25370
|
return parseJsonc(content);
|
|
25075
25371
|
} catch {
|
|
25076
25372
|
return null;
|
|
@@ -25194,23 +25490,23 @@ function getModelResolutionCheckDefinition() {
|
|
|
25194
25490
|
}
|
|
25195
25491
|
|
|
25196
25492
|
// src/cli/doctor/checks/auth.ts
|
|
25197
|
-
import { existsSync as
|
|
25198
|
-
import { join as
|
|
25493
|
+
import { existsSync as existsSync13, readFileSync as readFileSync11 } from "fs";
|
|
25494
|
+
import { join as join14 } from "path";
|
|
25199
25495
|
init_shared();
|
|
25200
25496
|
var OPENCODE_CONFIG_DIR = getOpenCodeConfigDir({ binary: "opencode" });
|
|
25201
|
-
var OPENCODE_JSON =
|
|
25202
|
-
var OPENCODE_JSONC =
|
|
25497
|
+
var OPENCODE_JSON = join14(OPENCODE_CONFIG_DIR, "opencode.json");
|
|
25498
|
+
var OPENCODE_JSONC = join14(OPENCODE_CONFIG_DIR, "opencode.jsonc");
|
|
25203
25499
|
var AUTH_PLUGINS = {
|
|
25204
25500
|
anthropic: { plugin: "builtin", name: "Anthropic (Claude)" },
|
|
25205
25501
|
openai: { plugin: "opencode-openai-codex-auth", name: "OpenAI (ChatGPT)" },
|
|
25206
25502
|
google: { plugin: "opencode-antigravity-auth", name: "Google (Gemini)" }
|
|
25207
25503
|
};
|
|
25208
25504
|
function getOpenCodeConfig() {
|
|
25209
|
-
const configPath =
|
|
25210
|
-
if (!
|
|
25505
|
+
const configPath = existsSync13(OPENCODE_JSONC) ? OPENCODE_JSONC : OPENCODE_JSON;
|
|
25506
|
+
if (!existsSync13(configPath))
|
|
25211
25507
|
return null;
|
|
25212
25508
|
try {
|
|
25213
|
-
const content =
|
|
25509
|
+
const content = readFileSync11(configPath, "utf-8");
|
|
25214
25510
|
return parseJsonc(content);
|
|
25215
25511
|
} catch {
|
|
25216
25512
|
return null;
|
|
@@ -25295,9 +25591,9 @@ function getAuthCheckDefinitions() {
|
|
|
25295
25591
|
// src/cli/doctor/checks/dependencies.ts
|
|
25296
25592
|
async function checkBinaryExists(binary2) {
|
|
25297
25593
|
try {
|
|
25298
|
-
const
|
|
25299
|
-
if (
|
|
25300
|
-
return { exists: true, path:
|
|
25594
|
+
const path7 = Bun.which(binary2);
|
|
25595
|
+
if (path7) {
|
|
25596
|
+
return { exists: true, path: path7 };
|
|
25301
25597
|
}
|
|
25302
25598
|
} catch {}
|
|
25303
25599
|
return { exists: false, path: null };
|
|
@@ -25348,15 +25644,15 @@ async function checkAstGrepNapi() {
|
|
|
25348
25644
|
path: null
|
|
25349
25645
|
};
|
|
25350
25646
|
} catch {
|
|
25351
|
-
const { existsSync:
|
|
25352
|
-
const { join:
|
|
25647
|
+
const { existsSync: existsSync14 } = await import("fs");
|
|
25648
|
+
const { join: join15 } = await import("path");
|
|
25353
25649
|
const { homedir: homedir7 } = await import("os");
|
|
25354
25650
|
const pathsToCheck = [
|
|
25355
|
-
|
|
25356
|
-
|
|
25651
|
+
join15(homedir7(), ".config", "opencode", "node_modules", "@ast-grep", "napi"),
|
|
25652
|
+
join15(process.cwd(), "node_modules", "@ast-grep", "napi")
|
|
25357
25653
|
];
|
|
25358
25654
|
for (const napiPath of pathsToCheck) {
|
|
25359
|
-
if (
|
|
25655
|
+
if (existsSync14(napiPath)) {
|
|
25360
25656
|
return {
|
|
25361
25657
|
name: "AST-Grep NAPI",
|
|
25362
25658
|
required: false,
|
|
@@ -25585,15 +25881,15 @@ function getGhCliCheckDefinition() {
|
|
|
25585
25881
|
}
|
|
25586
25882
|
|
|
25587
25883
|
// src/tools/lsp/config.ts
|
|
25588
|
-
import { existsSync as
|
|
25589
|
-
import { join as
|
|
25884
|
+
import { existsSync as existsSync14, readFileSync as readFileSync12 } from "fs";
|
|
25885
|
+
import { join as join15 } from "path";
|
|
25590
25886
|
init_shared();
|
|
25591
25887
|
function isServerInstalled(command) {
|
|
25592
25888
|
if (command.length === 0)
|
|
25593
25889
|
return false;
|
|
25594
25890
|
const cmd = command[0];
|
|
25595
25891
|
if (cmd.includes("/") || cmd.includes("\\")) {
|
|
25596
|
-
if (
|
|
25892
|
+
if (existsSync14(cmd))
|
|
25597
25893
|
return true;
|
|
25598
25894
|
}
|
|
25599
25895
|
const isWindows = process.platform === "win32";
|
|
@@ -25615,23 +25911,23 @@ function isServerInstalled(command) {
|
|
|
25615
25911
|
const paths = pathEnv.split(pathSeparator);
|
|
25616
25912
|
for (const p2 of paths) {
|
|
25617
25913
|
for (const suffix of exts) {
|
|
25618
|
-
if (
|
|
25914
|
+
if (existsSync14(join15(p2, cmd + suffix))) {
|
|
25619
25915
|
return true;
|
|
25620
25916
|
}
|
|
25621
25917
|
}
|
|
25622
25918
|
}
|
|
25623
25919
|
const cwd = process.cwd();
|
|
25624
25920
|
const configDir = getOpenCodeConfigDir({ binary: "opencode" });
|
|
25625
|
-
const dataDir =
|
|
25921
|
+
const dataDir = join15(getDataDir(), "opencode");
|
|
25626
25922
|
const additionalBases = [
|
|
25627
|
-
|
|
25628
|
-
|
|
25629
|
-
|
|
25630
|
-
|
|
25923
|
+
join15(cwd, "node_modules", ".bin"),
|
|
25924
|
+
join15(configDir, "bin"),
|
|
25925
|
+
join15(configDir, "node_modules", ".bin"),
|
|
25926
|
+
join15(dataDir, "bin")
|
|
25631
25927
|
];
|
|
25632
25928
|
for (const base of additionalBases) {
|
|
25633
25929
|
for (const suffix of exts) {
|
|
25634
|
-
if (
|
|
25930
|
+
if (existsSync14(join15(base, cmd + suffix))) {
|
|
25635
25931
|
return true;
|
|
25636
25932
|
}
|
|
25637
25933
|
}
|
|
@@ -25704,23 +26000,23 @@ function getLspCheckDefinition() {
|
|
|
25704
26000
|
}
|
|
25705
26001
|
|
|
25706
26002
|
// src/cli/doctor/checks/mcp.ts
|
|
25707
|
-
import { existsSync as
|
|
26003
|
+
import { existsSync as existsSync15, readFileSync as readFileSync13 } from "fs";
|
|
25708
26004
|
import { homedir as homedir7 } from "os";
|
|
25709
|
-
import { join as
|
|
26005
|
+
import { join as join16 } from "path";
|
|
25710
26006
|
init_shared();
|
|
25711
26007
|
var BUILTIN_MCP_SERVERS = ["context7", "grep_app"];
|
|
25712
26008
|
var MCP_CONFIG_PATHS = [
|
|
25713
|
-
|
|
25714
|
-
|
|
25715
|
-
|
|
26009
|
+
join16(homedir7(), ".claude", ".mcp.json"),
|
|
26010
|
+
join16(process.cwd(), ".mcp.json"),
|
|
26011
|
+
join16(process.cwd(), ".claude", ".mcp.json")
|
|
25716
26012
|
];
|
|
25717
26013
|
function loadUserMcpConfig() {
|
|
25718
26014
|
const servers = {};
|
|
25719
26015
|
for (const configPath of MCP_CONFIG_PATHS) {
|
|
25720
|
-
if (!
|
|
26016
|
+
if (!existsSync15(configPath))
|
|
25721
26017
|
continue;
|
|
25722
26018
|
try {
|
|
25723
|
-
const content =
|
|
26019
|
+
const content = readFileSync13(configPath, "utf-8");
|
|
25724
26020
|
const config2 = parseJsonc(content);
|
|
25725
26021
|
if (config2.mcpServers) {
|
|
25726
26022
|
Object.assign(servers, config2.mcpServers);
|
|
@@ -25811,11 +26107,11 @@ function getMcpCheckDefinitions() {
|
|
|
25811
26107
|
|
|
25812
26108
|
// src/features/mcp-oauth/storage.ts
|
|
25813
26109
|
init_shared();
|
|
25814
|
-
import { chmodSync, existsSync as
|
|
25815
|
-
import { dirname as dirname2, join as
|
|
26110
|
+
import { chmodSync, existsSync as existsSync16, mkdirSync as mkdirSync3, readFileSync as readFileSync14, unlinkSync, writeFileSync as writeFileSync6 } from "fs";
|
|
26111
|
+
import { dirname as dirname2, join as join17 } from "path";
|
|
25816
26112
|
var STORAGE_FILE_NAME = "mcp-oauth.json";
|
|
25817
26113
|
function getMcpOauthStoragePath() {
|
|
25818
|
-
return
|
|
26114
|
+
return join17(getOpenCodeConfigDir({ binary: "opencode" }), STORAGE_FILE_NAME);
|
|
25819
26115
|
}
|
|
25820
26116
|
function normalizeHost(serverHost) {
|
|
25821
26117
|
let host = serverHost.trim();
|
|
@@ -25852,11 +26148,11 @@ function buildKey(serverHost, resource) {
|
|
|
25852
26148
|
}
|
|
25853
26149
|
function readStore() {
|
|
25854
26150
|
const filePath = getMcpOauthStoragePath();
|
|
25855
|
-
if (!
|
|
26151
|
+
if (!existsSync16(filePath)) {
|
|
25856
26152
|
return null;
|
|
25857
26153
|
}
|
|
25858
26154
|
try {
|
|
25859
|
-
const content =
|
|
26155
|
+
const content = readFileSync14(filePath, "utf-8");
|
|
25860
26156
|
return JSON.parse(content);
|
|
25861
26157
|
} catch {
|
|
25862
26158
|
return null;
|
|
@@ -25866,10 +26162,10 @@ function writeStore(store) {
|
|
|
25866
26162
|
const filePath = getMcpOauthStoragePath();
|
|
25867
26163
|
try {
|
|
25868
26164
|
const dir = dirname2(filePath);
|
|
25869
|
-
if (!
|
|
26165
|
+
if (!existsSync16(dir)) {
|
|
25870
26166
|
mkdirSync3(dir, { recursive: true });
|
|
25871
26167
|
}
|
|
25872
|
-
|
|
26168
|
+
writeFileSync6(filePath, JSON.stringify(store, null, 2), { encoding: "utf-8", mode: 384 });
|
|
25873
26169
|
chmodSync(filePath, 384);
|
|
25874
26170
|
return true;
|
|
25875
26171
|
} catch {
|
|
@@ -25901,7 +26197,7 @@ function deleteToken(serverHost, resource) {
|
|
|
25901
26197
|
if (Object.keys(store).length === 0) {
|
|
25902
26198
|
try {
|
|
25903
26199
|
const filePath = getMcpOauthStoragePath();
|
|
25904
|
-
if (
|
|
26200
|
+
if (existsSync16(filePath)) {
|
|
25905
26201
|
unlinkSync(filePath);
|
|
25906
26202
|
}
|
|
25907
26203
|
return true;
|
|
@@ -25930,14 +26226,14 @@ function listAllTokens() {
|
|
|
25930
26226
|
}
|
|
25931
26227
|
|
|
25932
26228
|
// src/cli/doctor/checks/mcp-oauth.ts
|
|
25933
|
-
import { existsSync as
|
|
26229
|
+
import { existsSync as existsSync17, readFileSync as readFileSync15 } from "fs";
|
|
25934
26230
|
function readTokenStore() {
|
|
25935
26231
|
const filePath = getMcpOauthStoragePath();
|
|
25936
|
-
if (!
|
|
26232
|
+
if (!existsSync17(filePath)) {
|
|
25937
26233
|
return null;
|
|
25938
26234
|
}
|
|
25939
26235
|
try {
|
|
25940
|
-
const content =
|
|
26236
|
+
const content = readFileSync15(filePath, "utf-8");
|
|
25941
26237
|
return JSON.parse(content);
|
|
25942
26238
|
} catch {
|
|
25943
26239
|
return null;
|
|
@@ -26835,12 +27131,21 @@ Model Providers (Priority: Native > Copilot > OpenCode Zen > Z.ai > Kimi):
|
|
|
26835
27131
|
const exitCode = await install(args);
|
|
26836
27132
|
process.exit(exitCode);
|
|
26837
27133
|
});
|
|
26838
|
-
program2.command("run <message>").description("Run opencode with todo/background task completion enforcement").option("-a, --agent <name>", "Agent to use (default: Sisyphus)").option("-d, --directory <path>", "Working directory").option("-t, --timeout <ms>", "Timeout in milliseconds (default: 30 minutes)", parseInt).addHelpText("after", `
|
|
27134
|
+
program2.command("run <message>").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("-t, --timeout <ms>", "Timeout in milliseconds (default: 30 minutes)", parseInt).addHelpText("after", `
|
|
26839
27135
|
Examples:
|
|
26840
27136
|
$ bunx oh-my-opencode run "Fix the bug in index.ts"
|
|
26841
27137
|
$ bunx oh-my-opencode run --agent Sisyphus "Implement feature X"
|
|
26842
27138
|
$ bunx oh-my-opencode run --timeout 3600000 "Large refactoring task"
|
|
26843
27139
|
|
|
27140
|
+
Agent resolution order:
|
|
27141
|
+
1) --agent flag
|
|
27142
|
+
2) OPENCODE_DEFAULT_AGENT
|
|
27143
|
+
3) oh-my-opencode.json "default_run_agent"
|
|
27144
|
+
4) Sisyphus (fallback)
|
|
27145
|
+
|
|
27146
|
+
Available core agents:
|
|
27147
|
+
Sisyphus, Hephaestus, Prometheus, Atlas
|
|
27148
|
+
|
|
26844
27149
|
Unlike 'opencode run', this command waits until:
|
|
26845
27150
|
- All todos are completed or cancelled
|
|
26846
27151
|
- All child sessions (background tasks) are idle
|