oh-my-opencode 4.1.2 → 4.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ja.md +1 -0
- package/README.ko.md +1 -0
- package/README.md +1 -0
- package/README.ru.md +1 -0
- package/README.zh-cn.md +1 -0
- package/dist/agents/atlas/default-prompt-sections.d.ts +3 -3
- package/dist/agents/atlas/gemini-prompt-sections.d.ts +2 -2
- package/dist/agents/atlas/gpt-prompt-sections.d.ts +2 -2
- package/dist/agents/atlas/kimi-prompt-sections.d.ts +3 -3
- package/dist/agents/atlas/opus-4-7-prompt-sections.d.ts +3 -3
- package/dist/agents/momus.d.ts +1 -1
- package/dist/agents/prometheus/behavioral-summary.d.ts +1 -1
- package/dist/agents/prometheus/high-accuracy-mode.d.ts +1 -1
- package/dist/agents/prometheus/identity-constraints.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/cli/index.js +720 -430
- package/dist/cli/run/server-connection.d.ts +32 -2
- package/dist/config/schema/team-mode.d.ts +1 -1
- package/dist/features/background-agent/error-classifier.d.ts +1 -0
- package/dist/features/background-agent/fallback-retry-handler.d.ts +15 -0
- package/dist/features/background-agent/manager.d.ts +11 -8
- package/dist/features/background-agent/parent-wake-notifier.d.ts +74 -0
- package/dist/features/background-agent/process-cleanup.d.ts +2 -0
- package/dist/features/background-agent/session-route.d.ts +12 -0
- package/dist/features/background-agent/spawner.d.ts +2 -2
- package/dist/features/background-agent/task-registry.d.ts +6 -0
- package/dist/features/background-agent/types.d.ts +2 -0
- package/dist/features/boulder-state/constants.d.ts +4 -4
- package/dist/features/boulder-state/storage.d.ts +1 -1
- package/dist/features/builtin-commands/templates/init-deep.d.ts +1 -1
- package/dist/features/builtin-commands/templates/start-work.d.ts +1 -1
- package/dist/features/context-injector/injector.d.ts +1 -1
- package/dist/features/opencode-skill-loader/git-master-template-injection.d.ts +18 -0
- package/dist/features/run-continuation-state/constants.d.ts +1 -1
- package/dist/features/team-mode/team-layout-tmux/resolve-caller-tmux-session.d.ts +3 -1
- package/dist/features/team-mode/tools/lifecycle-test-fixture.d.ts +3 -3
- package/dist/features/team-mode/tools/messaging.d.ts +1 -0
- package/dist/features/team-mode/types.d.ts +2 -2
- package/dist/features/tmux-subagent/attachable-session-status.d.ts +1 -1
- package/dist/features/tmux-subagent/manager.d.ts +6 -0
- package/dist/features/tmux-subagent/pane-state-parser.d.ts +2 -0
- package/dist/features/tmux-subagent/polling-manager.d.ts +6 -2
- package/dist/features/tmux-subagent/types.d.ts +4 -0
- package/dist/hooks/atlas/boulder-continuation-injector.d.ts +1 -0
- package/dist/hooks/atlas/omo-path.d.ts +6 -0
- package/dist/hooks/atlas/tool-execute-after.d.ts +3 -0
- package/dist/hooks/atlas/tool-progress.d.ts +14 -0
- package/dist/hooks/atlas/types.d.ts +7 -0
- package/dist/hooks/auto-slash-command/detector.d.ts +2 -0
- package/dist/hooks/auto-update-checker/cache.d.ts +8 -1
- package/dist/hooks/auto-update-checker/checker/cached-version.d.ts +8 -1
- package/dist/hooks/background-notification/hook.d.ts +0 -6
- package/dist/hooks/compaction-context-injector/types.d.ts +1 -0
- package/dist/hooks/interactive-bash-session/state-manager.d.ts +1 -1
- package/dist/hooks/json-error-recovery/hook.d.ts +1 -1
- package/dist/hooks/keyword-detector/detector.d.ts +1 -0
- package/dist/hooks/keyword-detector/ultrawork/default.d.ts +1 -1
- package/dist/hooks/keyword-detector/ultrawork/gemini.d.ts +1 -1
- package/dist/hooks/keyword-detector/ultrawork/planner.d.ts +1 -1
- package/dist/hooks/prometheus-md-only/constants.d.ts +1 -1
- package/dist/hooks/prometheus-md-only/path-policy.d.ts +3 -3
- package/dist/hooks/ralph-loop/completion-promise-detector-test-input.d.ts +11 -0
- package/dist/hooks/ralph-loop/constants.d.ts +1 -1
- package/dist/hooks/ralph-loop/continuation-prompt-injector.d.ts +4 -0
- package/dist/hooks/ralph-loop/iteration-continuation.d.ts +4 -0
- package/dist/hooks/rules-injector/injector.d.ts +9 -2
- package/dist/hooks/rules-injector/matcher.d.ts +5 -0
- package/dist/hooks/rules-injector/project-root-finder.d.ts +4 -0
- package/dist/hooks/rules-injector/rule-scan-cache.d.ts +9 -2
- package/dist/hooks/runtime-fallback/constants.d.ts +10 -0
- package/dist/hooks/runtime-fallback/first-prompt-watchdog.d.ts +25 -0
- package/dist/hooks/runtime-fallback/hook.d.ts +14 -1
- package/dist/hooks/runtime-fallback/last-user-retry-parts.d.ts +10 -2
- package/dist/hooks/runtime-fallback/types.d.ts +10 -0
- package/dist/hooks/session-recovery/detect-error-type.d.ts +1 -1
- package/dist/hooks/session-recovery/hook.d.ts +1 -0
- package/dist/hooks/session-recovery/interrupted-idle-message-fetch-timeout.d.ts +7 -0
- package/dist/hooks/session-recovery/recover-tool-result-missing.d.ts +6 -1
- package/dist/hooks/session-recovery/types.d.ts +12 -0
- package/dist/hooks/shared/prompt-async-gate.d.ts +1 -0
- package/dist/hooks/shared/session-idle-settle.d.ts +1 -11
- package/dist/hooks/sisyphus-junior-notepad/constants.d.ts +1 -1
- package/dist/hooks/team-mode-status-injector/hook.d.ts +2 -1
- package/dist/hooks/todo-continuation-enforcer/pending-question-detection.d.ts +2 -0
- package/dist/hooks/todo-continuation-enforcer/session-state.d.ts +3 -4
- package/dist/hooks/todo-continuation-enforcer/types.d.ts +2 -3
- package/dist/hooks/tool-pair-validator/hook.d.ts +7 -2
- package/dist/hooks/unstable-agent-babysitter/task-message-analyzer.d.ts +1 -0
- package/dist/hooks/write-existing-file-guard/tool-execute-before-handler.d.ts +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +8055 -9850
- package/dist/mcp/index.d.ts +3 -1
- package/dist/mcp/lsp.d.ts +13 -0
- package/dist/mcp/types.d.ts +1 -0
- package/dist/plugin/build-team-idle-wake-hint-client.d.ts +12 -0
- package/dist/plugin/chat-message.d.ts +1 -1
- package/dist/plugin/tool-registry.d.ts +1 -2
- package/dist/plugin-dispose.d.ts +0 -3
- package/dist/shared/agent-sort-shim.d.ts +1 -0
- package/dist/shared/delegated-child-session-bootstrap.d.ts +25 -0
- package/dist/shared/dynamic-truncator.d.ts +2 -0
- package/dist/shared/host-skill-config.d.ts +2 -0
- package/dist/shared/index.d.ts +2 -0
- package/dist/shared/internal-initiator-marker.d.ts +25 -0
- package/dist/shared/legacy-workspace-migration.d.ts +5 -0
- package/dist/shared/logger.d.ts +12 -0
- package/dist/shared/model-error-classifier.d.ts +2 -0
- package/dist/shared/model-resolution-pipeline.d.ts +4 -0
- package/dist/shared/opencode-http-api.d.ts +9 -0
- package/dist/shared/prompt-async-gate.d.ts +82 -0
- package/dist/shared/replace-tool-args.d.ts +13 -0
- package/dist/shared/session-idle-settle.d.ts +11 -0
- package/dist/shared/tmux/tmux-utils/pane-activate.d.ts +1 -0
- package/dist/shared/tmux/tmux-utils/pane-close.d.ts +10 -0
- package/dist/shared/tmux/tmux-utils/pane-command.d.ts +2 -0
- package/dist/shared/tmux/tmux-utils/pane-replace.d.ts +11 -1
- package/dist/shared/tmux/tmux-utils/pane-spawn.d.ts +1 -1
- package/dist/shared/tmux/tmux-utils/server-health.d.ts +12 -1
- package/dist/shared/tmux/tmux-utils/session-spawn.d.ts +2 -2
- package/dist/shared/tmux/tmux-utils/window-spawn.d.ts +1 -1
- package/dist/shared/tmux/tmux-utils.d.ts +2 -0
- package/dist/testing/create-plugin-module.d.ts +41 -0
- package/dist/tools/background-task/constants.d.ts +1 -1
- package/dist/tools/background-task/with-sdk-call-timeout.d.ts +7 -0
- package/dist/tools/call-omo-agent/session-creator.d.ts +2 -1
- package/dist/tools/call-omo-agent/sync-executor.d.ts +2 -2
- package/dist/tools/delegate-task/subagent-discovery.d.ts +1 -0
- package/dist/tools/delegate-task/sync-prompt-sender.d.ts +2 -1
- package/dist/tools/delegate-task/sync-session-creator.d.ts +2 -0
- package/dist/tools/delegate-task/sync-task.d.ts +1 -1
- package/dist/tools/index.d.ts +0 -3
- package/dist/tools/interactive-bash/tools.d.ts +5 -0
- package/package.json +18 -16
- package/packages/lsp-tools-mcp/dist/cli.d.ts +3 -0
- package/packages/lsp-tools-mcp/dist/cli.d.ts.map +1 -0
- package/packages/lsp-tools-mcp/dist/cli.js +24 -0
- package/packages/lsp-tools-mcp/dist/cli.js.map +1 -0
- package/packages/lsp-tools-mcp/dist/lsp/cleanup-errors.d.ts +2 -0
- package/packages/lsp-tools-mcp/dist/lsp/cleanup-errors.d.ts.map +1 -0
- package/packages/lsp-tools-mcp/dist/lsp/cleanup-errors.js +7 -0
- package/packages/lsp-tools-mcp/dist/lsp/cleanup-errors.js.map +1 -0
- package/packages/lsp-tools-mcp/dist/lsp/client-wrapper.d.ts +14 -0
- package/packages/lsp-tools-mcp/dist/lsp/client-wrapper.d.ts.map +1 -0
- package/packages/lsp-tools-mcp/dist/lsp/client-wrapper.js +110 -0
- package/packages/lsp-tools-mcp/dist/lsp/client-wrapper.js.map +1 -0
- package/packages/lsp-tools-mcp/dist/lsp/client.d.ts +21 -0
- package/packages/lsp-tools-mcp/dist/lsp/client.d.ts.map +1 -0
- package/packages/lsp-tools-mcp/dist/lsp/client.js +130 -0
- package/packages/lsp-tools-mcp/dist/lsp/client.js.map +1 -0
- package/{dist/tools/lsp/server-config-loader.d.ts → packages/lsp-tools-mcp/dist/lsp/config-loader.d.ts} +6 -6
- package/packages/lsp-tools-mcp/dist/lsp/config-loader.d.ts.map +1 -0
- package/packages/lsp-tools-mcp/dist/lsp/config-loader.js +110 -0
- package/packages/lsp-tools-mcp/dist/lsp/config-loader.js.map +1 -0
- package/packages/lsp-tools-mcp/dist/lsp/connection.d.ts +5 -0
- package/packages/lsp-tools-mcp/dist/lsp/connection.d.ts.map +1 -0
- package/packages/lsp-tools-mcp/dist/lsp/connection.js +67 -0
- package/packages/lsp-tools-mcp/dist/lsp/connection.js.map +1 -0
- package/packages/lsp-tools-mcp/dist/lsp/constants.d.ts +11 -0
- package/packages/lsp-tools-mcp/dist/lsp/constants.d.ts.map +1 -0
- package/packages/lsp-tools-mcp/dist/lsp/constants.js +11 -0
- package/packages/lsp-tools-mcp/dist/lsp/constants.js.map +1 -0
- package/packages/lsp-tools-mcp/dist/lsp/directory-diagnostics.d.ts +4 -0
- package/packages/lsp-tools-mcp/dist/lsp/directory-diagnostics.d.ts.map +1 -0
- package/packages/lsp-tools-mcp/dist/lsp/directory-diagnostics.js +124 -0
- package/packages/lsp-tools-mcp/dist/lsp/directory-diagnostics.js.map +1 -0
- package/packages/lsp-tools-mcp/dist/lsp/errors.d.ts +36 -0
- package/packages/lsp-tools-mcp/dist/lsp/errors.d.ts.map +1 -0
- package/packages/lsp-tools-mcp/dist/lsp/errors.js +57 -0
- package/packages/lsp-tools-mcp/dist/lsp/errors.js.map +1 -0
- package/{dist/tools/lsp/lsp-formatters.d.ts → packages/lsp-tools-mcp/dist/lsp/formatters.d.ts} +5 -5
- package/packages/lsp-tools-mcp/dist/lsp/formatters.d.ts.map +1 -0
- package/packages/lsp-tools-mcp/dist/lsp/formatters.js +109 -0
- package/packages/lsp-tools-mcp/dist/lsp/formatters.js.map +1 -0
- package/{dist/tools → packages/lsp-tools-mcp/dist}/lsp/infer-extension.d.ts +1 -0
- package/packages/lsp-tools-mcp/dist/lsp/infer-extension.d.ts.map +1 -0
- package/packages/lsp-tools-mcp/dist/lsp/infer-extension.js +59 -0
- package/packages/lsp-tools-mcp/dist/lsp/infer-extension.js.map +1 -0
- package/packages/lsp-tools-mcp/dist/lsp/json-rpc-connection.d.ts +37 -0
- package/packages/lsp-tools-mcp/dist/lsp/json-rpc-connection.d.ts.map +1 -0
- package/packages/lsp-tools-mcp/dist/lsp/json-rpc-connection.js +248 -0
- package/packages/lsp-tools-mcp/dist/lsp/json-rpc-connection.js.map +1 -0
- package/{dist/tools → packages/lsp-tools-mcp/dist}/lsp/language-mappings.d.ts +2 -0
- package/packages/lsp-tools-mcp/dist/lsp/language-mappings.d.ts.map +1 -0
- package/packages/lsp-tools-mcp/dist/lsp/language-mappings.js +170 -0
- package/packages/lsp-tools-mcp/dist/lsp/language-mappings.js.map +1 -0
- package/packages/lsp-tools-mcp/dist/lsp/manager.d.ts +48 -0
- package/packages/lsp-tools-mcp/dist/lsp/manager.d.ts.map +1 -0
- package/packages/lsp-tools-mcp/dist/lsp/manager.js +308 -0
- package/packages/lsp-tools-mcp/dist/lsp/manager.js.map +1 -0
- package/packages/lsp-tools-mcp/dist/lsp/process.d.ts +26 -0
- package/packages/lsp-tools-mcp/dist/lsp/process.d.ts.map +1 -0
- package/packages/lsp-tools-mcp/dist/lsp/process.js +124 -0
- package/packages/lsp-tools-mcp/dist/lsp/process.js.map +1 -0
- package/packages/lsp-tools-mcp/dist/lsp/server-definitions.d.ts +5 -0
- package/packages/lsp-tools-mcp/dist/lsp/server-definitions.d.ts.map +1 -0
- package/packages/lsp-tools-mcp/dist/lsp/server-definitions.js +159 -0
- package/packages/lsp-tools-mcp/dist/lsp/server-definitions.js.map +1 -0
- package/packages/lsp-tools-mcp/dist/lsp/server-installation.d.ts +3 -0
- package/packages/lsp-tools-mcp/dist/lsp/server-installation.d.ts.map +1 -0
- package/packages/lsp-tools-mcp/dist/lsp/server-installation.js +51 -0
- package/packages/lsp-tools-mcp/dist/lsp/server-installation.js.map +1 -0
- package/packages/lsp-tools-mcp/dist/lsp/server-resolution.d.ts +12 -0
- package/packages/lsp-tools-mcp/dist/lsp/server-resolution.d.ts.map +1 -0
- package/packages/lsp-tools-mcp/dist/lsp/server-resolution.js +75 -0
- package/packages/lsp-tools-mcp/dist/lsp/server-resolution.js.map +1 -0
- package/packages/lsp-tools-mcp/dist/lsp/transport.d.ts +26 -0
- package/packages/lsp-tools-mcp/dist/lsp/transport.d.ts.map +1 -0
- package/packages/lsp-tools-mcp/dist/lsp/transport.js +234 -0
- package/packages/lsp-tools-mcp/dist/lsp/transport.js.map +1 -0
- package/{dist/tools → packages/lsp-tools-mcp/dist}/lsp/types.d.ts +28 -26
- package/packages/lsp-tools-mcp/dist/lsp/types.d.ts.map +1 -0
- package/packages/lsp-tools-mcp/dist/lsp/types.js +2 -0
- package/packages/lsp-tools-mcp/dist/lsp/types.js.map +1 -0
- package/packages/lsp-tools-mcp/dist/lsp/utils.d.ts +5 -0
- package/packages/lsp-tools-mcp/dist/lsp/utils.d.ts.map +1 -0
- package/packages/lsp-tools-mcp/dist/lsp/utils.js +43 -0
- package/packages/lsp-tools-mcp/dist/lsp/utils.js.map +1 -0
- package/{dist/tools → packages/lsp-tools-mcp/dist}/lsp/workspace-edit.d.ts +2 -1
- package/packages/lsp-tools-mcp/dist/lsp/workspace-edit.d.ts.map +1 -0
- package/packages/lsp-tools-mcp/dist/lsp/workspace-edit.js +114 -0
- package/packages/lsp-tools-mcp/dist/lsp/workspace-edit.js.map +1 -0
- package/packages/lsp-tools-mcp/dist/mcp.d.ts +31 -0
- package/packages/lsp-tools-mcp/dist/mcp.d.ts.map +1 -0
- package/packages/lsp-tools-mcp/dist/mcp.js +95 -0
- package/packages/lsp-tools-mcp/dist/mcp.js.map +1 -0
- package/packages/lsp-tools-mcp/dist/tools.d.ts +91 -0
- package/packages/lsp-tools-mcp/dist/tools.d.ts.map +1 -0
- package/packages/lsp-tools-mcp/dist/tools.js +453 -0
- package/packages/lsp-tools-mcp/dist/tools.js.map +1 -0
- package/dist/hooks/atlas/sisyphus-path.d.ts +0 -6
- package/dist/tools/lsp/client.d.ts +0 -3
- package/dist/tools/lsp/config.d.ts +0 -3
- package/dist/tools/lsp/constants.d.ts +0 -6
- package/dist/tools/lsp/diagnostics-tool.d.ts +0 -2
- package/dist/tools/lsp/directory-diagnostics.d.ts +0 -1
- package/dist/tools/lsp/find-references-tool.d.ts +0 -2
- package/dist/tools/lsp/goto-definition-tool.d.ts +0 -2
- package/dist/tools/lsp/index.d.ts +0 -8
- package/dist/tools/lsp/language-config.d.ts +0 -1
- package/dist/tools/lsp/lsp-client-connection.d.ts +0 -4
- package/dist/tools/lsp/lsp-client-transport.d.ts +0 -22
- package/dist/tools/lsp/lsp-client-wrapper.d.ts +0 -9
- package/dist/tools/lsp/lsp-client.d.ts +0 -17
- package/dist/tools/lsp/lsp-manager-process-cleanup.d.ts +0 -15
- package/dist/tools/lsp/lsp-manager-temp-directory-cleanup.d.ts +0 -8
- package/dist/tools/lsp/lsp-process.d.ts +0 -29
- package/dist/tools/lsp/lsp-server.d.ts +0 -24
- package/dist/tools/lsp/rename-tools.d.ts +0 -3
- package/dist/tools/lsp/server-definitions.d.ts +0 -3
- package/dist/tools/lsp/server-installation.d.ts +0 -1
- package/dist/tools/lsp/server-path-bases.d.ts +0 -1
- package/dist/tools/lsp/server-resolution.d.ts +0 -15
- package/dist/tools/lsp/symbols-tool.d.ts +0 -2
- package/dist/tools/lsp/tools.d.ts +0 -5
package/dist/cli/index.js
CHANGED
|
@@ -4964,6 +4964,27 @@ var init_plugin_identity = __esm(() => {
|
|
|
4964
4964
|
import * as fs from "fs";
|
|
4965
4965
|
import * as os from "os";
|
|
4966
4966
|
import * as path from "path";
|
|
4967
|
+
function rotateLogFileIfNeeded() {
|
|
4968
|
+
try {
|
|
4969
|
+
if (!fs.existsSync(logFile))
|
|
4970
|
+
return;
|
|
4971
|
+
const stats = fs.statSync(logFile);
|
|
4972
|
+
if (stats.size <= maxLogFileSizeBytes)
|
|
4973
|
+
return;
|
|
4974
|
+
const oldest = `${logFile}.${maxLogFileBackups}`;
|
|
4975
|
+
if (fs.existsSync(oldest)) {
|
|
4976
|
+
fs.unlinkSync(oldest);
|
|
4977
|
+
}
|
|
4978
|
+
for (let i2 = maxLogFileBackups - 1;i2 >= 1; i2 -= 1) {
|
|
4979
|
+
const src = `${logFile}.${i2}`;
|
|
4980
|
+
const dst = `${logFile}.${i2 + 1}`;
|
|
4981
|
+
if (fs.existsSync(src)) {
|
|
4982
|
+
fs.renameSync(src, dst);
|
|
4983
|
+
}
|
|
4984
|
+
}
|
|
4985
|
+
fs.renameSync(logFile, `${logFile}.1`);
|
|
4986
|
+
} catch {}
|
|
4987
|
+
}
|
|
4967
4988
|
function flush() {
|
|
4968
4989
|
if (buffer.length === 0)
|
|
4969
4990
|
return;
|
|
@@ -4971,6 +4992,7 @@ function flush() {
|
|
|
4971
4992
|
buffer = [];
|
|
4972
4993
|
try {
|
|
4973
4994
|
fs.appendFileSync(logFile, data);
|
|
4995
|
+
rotateLogFileIfNeeded();
|
|
4974
4996
|
} catch {}
|
|
4975
4997
|
}
|
|
4976
4998
|
function scheduleFlush() {
|
|
@@ -4994,10 +5016,13 @@ function log(message, data) {
|
|
|
4994
5016
|
}
|
|
4995
5017
|
} catch {}
|
|
4996
5018
|
}
|
|
4997
|
-
var logFile, buffer, flushTimer = null, FLUSH_INTERVAL_MS = 500, BUFFER_SIZE_LIMIT = 50;
|
|
5019
|
+
var DEFAULT_MAX_LOG_FILE_SIZE_BYTES, DEFAULT_MAX_LOG_FILE_BACKUPS = 2, logFile, maxLogFileSizeBytes, maxLogFileBackups, buffer, flushTimer = null, FLUSH_INTERVAL_MS = 500, BUFFER_SIZE_LIMIT = 50;
|
|
4998
5020
|
var init_logger = __esm(() => {
|
|
4999
5021
|
init_plugin_identity();
|
|
5022
|
+
DEFAULT_MAX_LOG_FILE_SIZE_BYTES = 50 * 1024 * 1024;
|
|
5000
5023
|
logFile = path.join(os.tmpdir(), LOG_FILENAME);
|
|
5024
|
+
maxLogFileSizeBytes = DEFAULT_MAX_LOG_FILE_SIZE_BYTES;
|
|
5025
|
+
maxLogFileBackups = DEFAULT_MAX_LOG_FILE_BACKUPS;
|
|
5001
5026
|
buffer = [];
|
|
5002
5027
|
});
|
|
5003
5028
|
|
|
@@ -5098,6 +5123,7 @@ function normalizeSDKResponse(response, fallback, options) {
|
|
|
5098
5123
|
var usageCacheByClient;
|
|
5099
5124
|
var init_dynamic_truncator = __esm(() => {
|
|
5100
5125
|
init_context_limit_resolver();
|
|
5126
|
+
init_logger();
|
|
5101
5127
|
usageCacheByClient = new WeakMap;
|
|
5102
5128
|
});
|
|
5103
5129
|
|
|
@@ -6020,7 +6046,7 @@ var init_main = __esm(() => {
|
|
|
6020
6046
|
});
|
|
6021
6047
|
|
|
6022
6048
|
// src/shared/jsonc-parser.ts
|
|
6023
|
-
import { existsSync as
|
|
6049
|
+
import { existsSync as existsSync3, readFileSync } from "fs";
|
|
6024
6050
|
import { join as join4 } from "path";
|
|
6025
6051
|
function stripBom(content) {
|
|
6026
6052
|
return content.charCodeAt(0) === 65279 ? content.slice(1) : content;
|
|
@@ -6041,10 +6067,10 @@ function parseJsonc(content) {
|
|
|
6041
6067
|
function detectConfigFile(basePath) {
|
|
6042
6068
|
const jsoncPath = `${basePath}.jsonc`;
|
|
6043
6069
|
const jsonPath = `${basePath}.json`;
|
|
6044
|
-
if (
|
|
6070
|
+
if (existsSync3(jsoncPath)) {
|
|
6045
6071
|
return { format: "jsonc", path: jsoncPath };
|
|
6046
6072
|
}
|
|
6047
|
-
if (
|
|
6073
|
+
if (existsSync3(jsonPath)) {
|
|
6048
6074
|
return { format: "json", path: jsonPath };
|
|
6049
6075
|
}
|
|
6050
6076
|
return { format: "none", path: jsonPath };
|
|
@@ -6317,8 +6343,8 @@ var init_tolerant_fsync = __esm(() => {
|
|
|
6317
6343
|
import {
|
|
6318
6344
|
closeSync,
|
|
6319
6345
|
openSync,
|
|
6320
|
-
renameSync,
|
|
6321
|
-
unlinkSync,
|
|
6346
|
+
renameSync as renameSync2,
|
|
6347
|
+
unlinkSync as unlinkSync2,
|
|
6322
6348
|
writeFileSync
|
|
6323
6349
|
} from "fs";
|
|
6324
6350
|
function writeFileAtomically(filePath, content, deps = {}) {
|
|
@@ -6331,13 +6357,13 @@ function writeFileAtomically(filePath, content, deps = {}) {
|
|
|
6331
6357
|
closeSync(tempFileDescriptor);
|
|
6332
6358
|
}
|
|
6333
6359
|
try {
|
|
6334
|
-
|
|
6360
|
+
renameSync2(tempPath, filePath);
|
|
6335
6361
|
} catch (error) {
|
|
6336
6362
|
const isWindows = process.platform === "win32";
|
|
6337
6363
|
const isPermissionError = error instanceof Error && (error.message.includes("EPERM") || error.message.includes("EACCES"));
|
|
6338
6364
|
if (isWindows && isPermissionError) {
|
|
6339
|
-
|
|
6340
|
-
|
|
6365
|
+
unlinkSync2(filePath);
|
|
6366
|
+
renameSync2(tempPath, filePath);
|
|
6341
6367
|
} else {
|
|
6342
6368
|
throw error;
|
|
6343
6369
|
}
|
|
@@ -6573,7 +6599,7 @@ var init_migration = __esm(() => {
|
|
|
6573
6599
|
});
|
|
6574
6600
|
|
|
6575
6601
|
// src/shared/opencode-config-dir.ts
|
|
6576
|
-
import { existsSync as
|
|
6602
|
+
import { existsSync as existsSync5, realpathSync as realpathSync3 } from "fs";
|
|
6577
6603
|
import { homedir as homedir3 } from "os";
|
|
6578
6604
|
import { join as join5, resolve as resolve2, win32 } from "path";
|
|
6579
6605
|
function isDevBuild(version) {
|
|
@@ -6599,7 +6625,7 @@ function getTauriConfigDir(identifier) {
|
|
|
6599
6625
|
}
|
|
6600
6626
|
function resolveConfigPath(pathValue) {
|
|
6601
6627
|
const resolvedPath = resolve2(pathValue);
|
|
6602
|
-
if (!
|
|
6628
|
+
if (!existsSync5(resolvedPath))
|
|
6603
6629
|
return resolvedPath;
|
|
6604
6630
|
try {
|
|
6605
6631
|
return realpathSync3(resolvedPath);
|
|
@@ -6627,7 +6653,7 @@ function getOpenCodeConfigDir(options) {
|
|
|
6627
6653
|
const legacyDir = getCliConfigDir();
|
|
6628
6654
|
const legacyConfig = join5(legacyDir, "opencode.json");
|
|
6629
6655
|
const legacyConfigC = join5(legacyDir, "opencode.jsonc");
|
|
6630
|
-
if (
|
|
6656
|
+
if (existsSync5(legacyConfig) || existsSync5(legacyConfigC)) {
|
|
6631
6657
|
return legacyDir;
|
|
6632
6658
|
}
|
|
6633
6659
|
}
|
|
@@ -6669,7 +6695,7 @@ var init_resolve_agent_definition_paths = __esm(() => {
|
|
|
6669
6695
|
|
|
6670
6696
|
// src/shared/opencode-version.ts
|
|
6671
6697
|
import { execSync } from "child_process";
|
|
6672
|
-
import { existsSync as
|
|
6698
|
+
import { existsSync as existsSync6, readFileSync as readFileSync4, realpathSync as realpathSync4 } from "fs";
|
|
6673
6699
|
import { dirname as dirname3, join as join6 } from "path";
|
|
6674
6700
|
function parseVersion(version) {
|
|
6675
6701
|
const cleaned = version.replace(/^v/, "").split("-")[0];
|
|
@@ -6764,14 +6790,14 @@ var init_opencode_version = __esm(() => {
|
|
|
6764
6790
|
return envPath;
|
|
6765
6791
|
return globalThis.Bun?.which("opencode") ?? null;
|
|
6766
6792
|
},
|
|
6767
|
-
exists:
|
|
6793
|
+
exists: existsSync6,
|
|
6768
6794
|
realpath: realpathSync4,
|
|
6769
6795
|
readText: (filePath) => readFileSync4(filePath, "utf-8")
|
|
6770
6796
|
};
|
|
6771
6797
|
});
|
|
6772
6798
|
|
|
6773
6799
|
// src/shared/opencode-storage-detection.ts
|
|
6774
|
-
import { existsSync as
|
|
6800
|
+
import { existsSync as existsSync7 } from "fs";
|
|
6775
6801
|
import { join as join7 } from "path";
|
|
6776
6802
|
function isSqliteBackend() {
|
|
6777
6803
|
if (cachedResult === true)
|
|
@@ -6781,7 +6807,7 @@ function isSqliteBackend() {
|
|
|
6781
6807
|
const check = () => {
|
|
6782
6808
|
const versionOk = isOpenCodeVersionAtLeast(OPENCODE_SQLITE_VERSION);
|
|
6783
6809
|
const dbPath = join7(getDataDir(), "opencode", "opencode.db");
|
|
6784
|
-
return versionOk &&
|
|
6810
|
+
return versionOk && existsSync7(dbPath);
|
|
6785
6811
|
};
|
|
6786
6812
|
if (cachedResult === FALSE_PENDING_RETRY) {
|
|
6787
6813
|
const result2 = check();
|
|
@@ -6967,11 +6993,11 @@ var init_bun_file_shim = __esm(() => {
|
|
|
6967
6993
|
});
|
|
6968
6994
|
|
|
6969
6995
|
// src/shared/binary-downloader.ts
|
|
6970
|
-
import { chmodSync, existsSync as
|
|
6996
|
+
import { chmodSync, existsSync as existsSync8, mkdirSync as mkdirSync3, unlinkSync as unlinkSync3 } from "fs";
|
|
6971
6997
|
import * as path5 from "path";
|
|
6972
6998
|
function getCachedBinaryPath(cacheDir, binaryName) {
|
|
6973
6999
|
const binaryPath = path5.join(cacheDir, binaryName);
|
|
6974
|
-
return
|
|
7000
|
+
return existsSync8(binaryPath) ? binaryPath : null;
|
|
6975
7001
|
}
|
|
6976
7002
|
var init_binary_downloader = __esm(() => {
|
|
6977
7003
|
init_bun_spawn_shim();
|
|
@@ -7426,7 +7452,7 @@ function normalizeModelID(modelID) {
|
|
|
7426
7452
|
}
|
|
7427
7453
|
|
|
7428
7454
|
// src/shared/json-file-cache-store.ts
|
|
7429
|
-
import { existsSync as
|
|
7455
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync4, readFileSync as readFileSync5, writeFileSync as writeFileSync2 } from "fs";
|
|
7430
7456
|
import { join as join9 } from "path";
|
|
7431
7457
|
function toLogLabel(cacheLabel) {
|
|
7432
7458
|
return cacheLabel.toLowerCase();
|
|
@@ -7439,7 +7465,7 @@ function createJsonFileCacheStore(options) {
|
|
|
7439
7465
|
}
|
|
7440
7466
|
function ensureCacheDir() {
|
|
7441
7467
|
const cacheDir = options.getCacheDir();
|
|
7442
|
-
if (!
|
|
7468
|
+
if (!existsSync9(cacheDir)) {
|
|
7443
7469
|
mkdirSync4(cacheDir, { recursive: true });
|
|
7444
7470
|
}
|
|
7445
7471
|
}
|
|
@@ -7448,7 +7474,7 @@ function createJsonFileCacheStore(options) {
|
|
|
7448
7474
|
return memoryValue;
|
|
7449
7475
|
}
|
|
7450
7476
|
const cacheFile = getCacheFilePath();
|
|
7451
|
-
if (!
|
|
7477
|
+
if (!existsSync9(cacheFile)) {
|
|
7452
7478
|
memoryValue = null;
|
|
7453
7479
|
log(`[${options.logPrefix}] ${options.cacheLabel} file not found`, { cacheFile });
|
|
7454
7480
|
return null;
|
|
@@ -7474,7 +7500,7 @@ function createJsonFileCacheStore(options) {
|
|
|
7474
7500
|
if (writtenInCurrentProcess) {
|
|
7475
7501
|
return true;
|
|
7476
7502
|
}
|
|
7477
|
-
return
|
|
7503
|
+
return existsSync9(getCacheFilePath());
|
|
7478
7504
|
}
|
|
7479
7505
|
function write(value) {
|
|
7480
7506
|
ensureCacheDir();
|
|
@@ -7650,14 +7676,14 @@ var init_connected_providers_cache = __esm(() => {
|
|
|
7650
7676
|
});
|
|
7651
7677
|
|
|
7652
7678
|
// src/shared/model-availability.ts
|
|
7653
|
-
import { existsSync as
|
|
7679
|
+
import { existsSync as existsSync10, readFileSync as readFileSync6 } from "fs";
|
|
7654
7680
|
import { join as join10 } from "path";
|
|
7655
7681
|
function isModelCacheAvailable() {
|
|
7656
7682
|
if (hasProviderModelsCache()) {
|
|
7657
7683
|
return true;
|
|
7658
7684
|
}
|
|
7659
7685
|
const cacheFile = join10(getOpenCodeCacheDir(), "models.json");
|
|
7660
|
-
return
|
|
7686
|
+
return existsSync10(cacheFile);
|
|
7661
7687
|
}
|
|
7662
7688
|
var init_model_availability = __esm(() => {
|
|
7663
7689
|
init_logger();
|
|
@@ -50834,7 +50860,7 @@ var init_opencode_storage_paths = __esm(() => {
|
|
|
50834
50860
|
});
|
|
50835
50861
|
|
|
50836
50862
|
// src/shared/compaction-marker.ts
|
|
50837
|
-
import { existsSync as
|
|
50863
|
+
import { existsSync as existsSync11, readdirSync, readFileSync as readFileSync7 } from "fs";
|
|
50838
50864
|
import { join as join12 } from "path";
|
|
50839
50865
|
function isCompactionPart(part) {
|
|
50840
50866
|
return typeof part === "object" && part !== null && part.type === "compaction";
|
|
@@ -50856,7 +50882,7 @@ function hasCompactionPartInStorage(messageID) {
|
|
|
50856
50882
|
return false;
|
|
50857
50883
|
}
|
|
50858
50884
|
const partDir = getCompactionPartStorageDir(messageID);
|
|
50859
|
-
if (!
|
|
50885
|
+
if (!existsSync11(partDir)) {
|
|
50860
50886
|
return false;
|
|
50861
50887
|
}
|
|
50862
50888
|
try {
|
|
@@ -50895,23 +50921,23 @@ var init_hook_message_injector = __esm(() => {
|
|
|
50895
50921
|
});
|
|
50896
50922
|
|
|
50897
50923
|
// src/shared/opencode-message-dir.ts
|
|
50898
|
-
import { existsSync as
|
|
50924
|
+
import { existsSync as existsSync12, readdirSync as readdirSync2 } from "fs";
|
|
50899
50925
|
import { join as join13 } from "path";
|
|
50900
50926
|
function getMessageDir(sessionID) {
|
|
50901
50927
|
if (!sessionID.startsWith("ses_"))
|
|
50902
50928
|
return null;
|
|
50903
50929
|
if (/[/\\]|\.\./.test(sessionID))
|
|
50904
50930
|
return null;
|
|
50905
|
-
if (!
|
|
50931
|
+
if (!existsSync12(MESSAGE_STORAGE))
|
|
50906
50932
|
return null;
|
|
50907
50933
|
const directPath = join13(MESSAGE_STORAGE, sessionID);
|
|
50908
|
-
if (
|
|
50934
|
+
if (existsSync12(directPath)) {
|
|
50909
50935
|
return directPath;
|
|
50910
50936
|
}
|
|
50911
50937
|
try {
|
|
50912
50938
|
for (const dir of readdirSync2(MESSAGE_STORAGE)) {
|
|
50913
50939
|
const sessionPath = join13(MESSAGE_STORAGE, dir, sessionID);
|
|
50914
|
-
if (
|
|
50940
|
+
if (existsSync12(sessionPath)) {
|
|
50915
50941
|
return sessionPath;
|
|
50916
50942
|
}
|
|
50917
50943
|
}
|
|
@@ -50963,26 +50989,41 @@ var init_pane_dimensions = __esm(() => {
|
|
|
50963
50989
|
init_tmux_path_resolver();
|
|
50964
50990
|
});
|
|
50965
50991
|
|
|
50992
|
+
// src/shared/tmux/tmux-utils/pane-command.ts
|
|
50993
|
+
var init_pane_command = () => {};
|
|
50994
|
+
|
|
50966
50995
|
// src/shared/tmux/tmux-utils/pane-spawn.ts
|
|
50967
50996
|
var init_pane_spawn = __esm(() => {
|
|
50968
50997
|
init_tmux_path_resolver();
|
|
50969
50998
|
init_server_health();
|
|
50999
|
+
init_pane_command();
|
|
50970
51000
|
});
|
|
50971
51001
|
// src/shared/tmux/tmux-utils/pane-replace.ts
|
|
50972
51002
|
var init_pane_replace = __esm(() => {
|
|
50973
51003
|
init_tmux_path_resolver();
|
|
51004
|
+
init_pane_command();
|
|
51005
|
+
});
|
|
51006
|
+
|
|
51007
|
+
// src/shared/tmux/tmux-utils/pane-activate.ts
|
|
51008
|
+
var init_pane_activate = __esm(() => {
|
|
51009
|
+
init_tmux_path_resolver();
|
|
51010
|
+
init_logger();
|
|
51011
|
+
init_runner();
|
|
51012
|
+
init_pane_command();
|
|
50974
51013
|
});
|
|
50975
51014
|
|
|
50976
51015
|
// src/shared/tmux/tmux-utils/window-spawn.ts
|
|
50977
51016
|
var init_window_spawn = __esm(() => {
|
|
50978
51017
|
init_tmux_path_resolver();
|
|
50979
51018
|
init_server_health();
|
|
51019
|
+
init_pane_command();
|
|
50980
51020
|
});
|
|
50981
51021
|
|
|
50982
51022
|
// src/shared/tmux/tmux-utils/session-spawn.ts
|
|
50983
51023
|
var init_session_spawn = __esm(() => {
|
|
50984
51024
|
init_tmux_path_resolver();
|
|
50985
51025
|
init_server_health();
|
|
51026
|
+
init_pane_command();
|
|
50986
51027
|
});
|
|
50987
51028
|
// src/shared/tmux/tmux-utils/stale-session-sweep.ts
|
|
50988
51029
|
var init_stale_session_sweep = () => {};
|
|
@@ -50998,9 +51039,11 @@ var init_tmux_utils = __esm(() => {
|
|
|
50998
51039
|
init_pane_dimensions();
|
|
50999
51040
|
init_pane_spawn();
|
|
51000
51041
|
init_pane_replace();
|
|
51042
|
+
init_pane_activate();
|
|
51001
51043
|
init_window_spawn();
|
|
51002
51044
|
init_session_spawn();
|
|
51003
51045
|
init_stale_session_sweep();
|
|
51046
|
+
init_pane_command();
|
|
51004
51047
|
init_layout();
|
|
51005
51048
|
});
|
|
51006
51049
|
|
|
@@ -51010,9 +51053,306 @@ var init_tmux = __esm(() => {
|
|
|
51010
51053
|
init_runner();
|
|
51011
51054
|
init_tmux_utils();
|
|
51012
51055
|
});
|
|
51056
|
+
// src/shared/session-idle-settle.ts
|
|
51057
|
+
function settleAfterSessionIdle(ms = DEFAULT_SESSION_IDLE_SETTLE_MS) {
|
|
51058
|
+
return ms > 0 ? new Promise((resolve4) => setTimeout(resolve4, ms)) : Promise.resolve();
|
|
51059
|
+
}
|
|
51060
|
+
function isRecord6(value) {
|
|
51061
|
+
return typeof value === "object" && value !== null;
|
|
51062
|
+
}
|
|
51063
|
+
function getSessionStatusPayload(response) {
|
|
51064
|
+
if (isRecord6(response) && isRecord6(response.data)) {
|
|
51065
|
+
return response.data;
|
|
51066
|
+
}
|
|
51067
|
+
if (isRecord6(response)) {
|
|
51068
|
+
return response;
|
|
51069
|
+
}
|
|
51070
|
+
return {};
|
|
51071
|
+
}
|
|
51072
|
+
function isActiveSessionStatusType(statusType) {
|
|
51073
|
+
return ACTIVE_SESSION_STATUSES.has(statusType);
|
|
51074
|
+
}
|
|
51075
|
+
async function isSessionActive(client, sessionID) {
|
|
51076
|
+
if (typeof client.session?.status !== "function") {
|
|
51077
|
+
return false;
|
|
51078
|
+
}
|
|
51079
|
+
try {
|
|
51080
|
+
const statusResult = await client.session.status();
|
|
51081
|
+
const status = getSessionStatusPayload(statusResult)[sessionID];
|
|
51082
|
+
if (!isRecord6(status)) {
|
|
51083
|
+
return false;
|
|
51084
|
+
}
|
|
51085
|
+
const statusType = status.type;
|
|
51086
|
+
return typeof statusType === "string" && isActiveSessionStatusType(statusType);
|
|
51087
|
+
} catch {
|
|
51088
|
+
return false;
|
|
51089
|
+
}
|
|
51090
|
+
}
|
|
51091
|
+
var DEFAULT_SESSION_IDLE_SETTLE_MS = 150, ACTIVE_SESSION_STATUSES;
|
|
51092
|
+
var init_session_idle_settle = __esm(() => {
|
|
51093
|
+
ACTIVE_SESSION_STATUSES = new Set(["busy", "retry", "running"]);
|
|
51094
|
+
});
|
|
51095
|
+
|
|
51096
|
+
// src/shared/prompt-async-gate.ts
|
|
51097
|
+
function getPromptGateMessagesFetchTimeoutMs() {
|
|
51098
|
+
return promptGateMessagesFetchTimeoutMsForTesting ?? DEFAULT_PROMPT_GATE_MESSAGES_FETCH_TIMEOUT_MS;
|
|
51099
|
+
}
|
|
51100
|
+
function pruneExpiredReservations(now = Date.now()) {
|
|
51101
|
+
for (const [sessionID, reservation] of promptAsyncReservations) {
|
|
51102
|
+
if (typeof reservation.expiresAt === "number" && reservation.expiresAt <= now) {
|
|
51103
|
+
promptAsyncReservations.delete(sessionID);
|
|
51104
|
+
log("[prompt-async-gate] expired reservation released", {
|
|
51105
|
+
sessionID,
|
|
51106
|
+
source: reservation.source
|
|
51107
|
+
});
|
|
51108
|
+
}
|
|
51109
|
+
}
|
|
51110
|
+
}
|
|
51111
|
+
function getActiveReservation(sessionID) {
|
|
51112
|
+
pruneExpiredReservations();
|
|
51113
|
+
return promptAsyncReservations.get(sessionID);
|
|
51114
|
+
}
|
|
51115
|
+
async function withDispatchTimeout(operation, dispatchTimeoutMs, operationName) {
|
|
51116
|
+
if (dispatchTimeoutMs <= 0) {
|
|
51117
|
+
return operation;
|
|
51118
|
+
}
|
|
51119
|
+
let timeoutID;
|
|
51120
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
51121
|
+
timeoutID = setTimeout(() => {
|
|
51122
|
+
reject(new Error(`${operationName} timed out after ${dispatchTimeoutMs}ms`));
|
|
51123
|
+
}, dispatchTimeoutMs);
|
|
51124
|
+
});
|
|
51125
|
+
try {
|
|
51126
|
+
return await Promise.race([operation, timeoutPromise]);
|
|
51127
|
+
} finally {
|
|
51128
|
+
if (timeoutID !== undefined) {
|
|
51129
|
+
clearTimeout(timeoutID);
|
|
51130
|
+
}
|
|
51131
|
+
}
|
|
51132
|
+
}
|
|
51133
|
+
function isRecord7(value) {
|
|
51134
|
+
return typeof value === "object" && value !== null;
|
|
51135
|
+
}
|
|
51136
|
+
function getPromptQuery(input) {
|
|
51137
|
+
if (!isRecord7(input)) {
|
|
51138
|
+
return { directory: "" };
|
|
51139
|
+
}
|
|
51140
|
+
const query = input.query;
|
|
51141
|
+
if (!isRecord7(query)) {
|
|
51142
|
+
return { directory: "" };
|
|
51143
|
+
}
|
|
51144
|
+
const promptQuery = { directory: "" };
|
|
51145
|
+
if (typeof query.directory === "string") {
|
|
51146
|
+
promptQuery.directory = query.directory;
|
|
51147
|
+
}
|
|
51148
|
+
if (typeof query.limit === "number") {
|
|
51149
|
+
promptQuery.limit = query.limit;
|
|
51150
|
+
}
|
|
51151
|
+
return promptQuery;
|
|
51152
|
+
}
|
|
51153
|
+
function getMessagesData(response) {
|
|
51154
|
+
if (isRecord7(response) && Array.isArray(response.data)) {
|
|
51155
|
+
return response.data;
|
|
51156
|
+
}
|
|
51157
|
+
return Array.isArray(response) ? response : [];
|
|
51158
|
+
}
|
|
51159
|
+
function messageRole(message) {
|
|
51160
|
+
if (!isRecord7(message)) {
|
|
51161
|
+
return;
|
|
51162
|
+
}
|
|
51163
|
+
const info = message.info;
|
|
51164
|
+
if (isRecord7(info) && typeof info.role === "string") {
|
|
51165
|
+
return info.role;
|
|
51166
|
+
}
|
|
51167
|
+
return typeof message.role === "string" ? message.role : undefined;
|
|
51168
|
+
}
|
|
51169
|
+
function partIsWaitingOnTool(part) {
|
|
51170
|
+
if (!isRecord7(part)) {
|
|
51171
|
+
return false;
|
|
51172
|
+
}
|
|
51173
|
+
if (part.type !== "tool" && part.type !== "tool_use") {
|
|
51174
|
+
return false;
|
|
51175
|
+
}
|
|
51176
|
+
const state = part.state;
|
|
51177
|
+
if (!isRecord7(state)) {
|
|
51178
|
+
return false;
|
|
51179
|
+
}
|
|
51180
|
+
return state.status === "pending" || state.status === "running";
|
|
51181
|
+
}
|
|
51182
|
+
function latestAssistantTurnIsWaitingOnTools(messages) {
|
|
51183
|
+
for (let index = messages.length - 1;index >= 0; index--) {
|
|
51184
|
+
const message = messages[index];
|
|
51185
|
+
const role = messageRole(message);
|
|
51186
|
+
if (role === "assistant") {
|
|
51187
|
+
if (!isRecord7(message) || !Array.isArray(message.parts)) {
|
|
51188
|
+
return false;
|
|
51189
|
+
}
|
|
51190
|
+
return message.parts.some(partIsWaitingOnTool);
|
|
51191
|
+
}
|
|
51192
|
+
if (role === "user") {
|
|
51193
|
+
return false;
|
|
51194
|
+
}
|
|
51195
|
+
}
|
|
51196
|
+
return false;
|
|
51197
|
+
}
|
|
51198
|
+
async function sessionLatestAssistantIsWaitingOnTools(args) {
|
|
51199
|
+
const session = args.client.session;
|
|
51200
|
+
if (typeof session?.messages !== "function") {
|
|
51201
|
+
return false;
|
|
51202
|
+
}
|
|
51203
|
+
const messages = session.messages.bind(session);
|
|
51204
|
+
try {
|
|
51205
|
+
const response = await withDispatchTimeout(messages({
|
|
51206
|
+
path: { id: args.sessionID },
|
|
51207
|
+
query: getPromptQuery(args.input)
|
|
51208
|
+
}), args.timeoutMs, `[prompt-async-gate] ${args.sessionName} session.messages`);
|
|
51209
|
+
return latestAssistantTurnIsWaitingOnTools(getMessagesData(response));
|
|
51210
|
+
} catch (error) {
|
|
51211
|
+
log("[prompt-async-gate] latest assistant tool-state check failed", {
|
|
51212
|
+
sessionID: args.sessionID,
|
|
51213
|
+
source: args.source,
|
|
51214
|
+
error: String(error)
|
|
51215
|
+
});
|
|
51216
|
+
return false;
|
|
51217
|
+
}
|
|
51218
|
+
}
|
|
51219
|
+
async function dispatchAfterSessionIdle(args) {
|
|
51220
|
+
const {
|
|
51221
|
+
sessionName,
|
|
51222
|
+
client,
|
|
51223
|
+
sessionID,
|
|
51224
|
+
input,
|
|
51225
|
+
source,
|
|
51226
|
+
settleMs,
|
|
51227
|
+
postDispatchHoldMs,
|
|
51228
|
+
dispatchTimeoutMs,
|
|
51229
|
+
checkStatus,
|
|
51230
|
+
checkToolState,
|
|
51231
|
+
dispatch
|
|
51232
|
+
} = args;
|
|
51233
|
+
const existing = getActiveReservation(sessionID);
|
|
51234
|
+
if (existing) {
|
|
51235
|
+
log(`[prompt-async-gate] ${sessionName} skipped because session is reserved`, {
|
|
51236
|
+
sessionID,
|
|
51237
|
+
source,
|
|
51238
|
+
reservedBy: existing.source,
|
|
51239
|
+
reservedAgeMs: Date.now() - existing.reservedAt
|
|
51240
|
+
});
|
|
51241
|
+
return { status: "reserved", reservedBy: existing.source };
|
|
51242
|
+
}
|
|
51243
|
+
const reservation = {
|
|
51244
|
+
source,
|
|
51245
|
+
reservedAt: Date.now(),
|
|
51246
|
+
token: Symbol(source)
|
|
51247
|
+
};
|
|
51248
|
+
promptAsyncReservations.set(sessionID, reservation);
|
|
51249
|
+
let dispatchAttempted = false;
|
|
51250
|
+
try {
|
|
51251
|
+
const canReadStatus = checkStatus && typeof client.session?.status === "function";
|
|
51252
|
+
if (settleMs > 0) {
|
|
51253
|
+
await settleAfterSessionIdle(settleMs);
|
|
51254
|
+
}
|
|
51255
|
+
let sessionActive = false;
|
|
51256
|
+
if (canReadStatus) {
|
|
51257
|
+
try {
|
|
51258
|
+
sessionActive = await withDispatchTimeout(isSessionActive(client, sessionID), Math.min(dispatchTimeoutMs, 5000), `[prompt-async-gate] ${sessionName} isSessionActive`);
|
|
51259
|
+
} catch {
|
|
51260
|
+
sessionActive = false;
|
|
51261
|
+
}
|
|
51262
|
+
}
|
|
51263
|
+
if (sessionActive) {
|
|
51264
|
+
log(`[prompt-async-gate] ${sessionName} skipped because session is active`, { sessionID, source });
|
|
51265
|
+
return { status: "active" };
|
|
51266
|
+
}
|
|
51267
|
+
if (checkToolState && typeof client.session?.messages === "function" && await sessionLatestAssistantIsWaitingOnTools({
|
|
51268
|
+
client,
|
|
51269
|
+
sessionID,
|
|
51270
|
+
input,
|
|
51271
|
+
sessionName,
|
|
51272
|
+
source,
|
|
51273
|
+
timeoutMs: Math.min(dispatchTimeoutMs, getPromptGateMessagesFetchTimeoutMs())
|
|
51274
|
+
})) {
|
|
51275
|
+
log(`[prompt-async-gate] ${sessionName} skipped because latest assistant is waiting on tools`, {
|
|
51276
|
+
sessionID,
|
|
51277
|
+
source
|
|
51278
|
+
});
|
|
51279
|
+
return { status: "active" };
|
|
51280
|
+
}
|
|
51281
|
+
log(`[prompt-async-gate] ${sessionName} dispatching`, { sessionID, source });
|
|
51282
|
+
dispatchAttempted = true;
|
|
51283
|
+
const response = await withDispatchTimeout(dispatch(input), dispatchTimeoutMs, `[prompt-async-gate] ${sessionName} dispatch`);
|
|
51284
|
+
log(`[prompt-async-gate] ${sessionName} dispatched`, { sessionID, source });
|
|
51285
|
+
return { status: "dispatched", response };
|
|
51286
|
+
} catch (error) {
|
|
51287
|
+
log(`[prompt-async-gate] ${sessionName} failed`, { sessionID, source, error: String(error) });
|
|
51288
|
+
return { status: "failed", error };
|
|
51289
|
+
} finally {
|
|
51290
|
+
const current = promptAsyncReservations.get(sessionID);
|
|
51291
|
+
if (current?.token === reservation.token) {
|
|
51292
|
+
if (dispatchAttempted && postDispatchHoldMs > 0) {
|
|
51293
|
+
reservation.expiresAt = Date.now() + postDispatchHoldMs;
|
|
51294
|
+
} else {
|
|
51295
|
+
promptAsyncReservations.delete(sessionID);
|
|
51296
|
+
}
|
|
51297
|
+
}
|
|
51298
|
+
}
|
|
51299
|
+
}
|
|
51300
|
+
async function dispatchInternalPrompt(args) {
|
|
51301
|
+
const {
|
|
51302
|
+
client,
|
|
51303
|
+
sessionID,
|
|
51304
|
+
input,
|
|
51305
|
+
source,
|
|
51306
|
+
settleMs = DEFAULT_SESSION_IDLE_SETTLE_MS
|
|
51307
|
+
} = args;
|
|
51308
|
+
const postDispatchHoldMs = args.postDispatchHoldMs ?? DEFAULT_PROMPT_ASYNC_POST_DISPATCH_HOLD_MS;
|
|
51309
|
+
const dispatchTimeoutMs = args.dispatchTimeoutMs ?? DEFAULT_PROMPT_DISPATCH_TIMEOUT_MS;
|
|
51310
|
+
const sessionName = args.mode === "async" ? "promptAsync" : "prompt";
|
|
51311
|
+
const dispatch = (() => {
|
|
51312
|
+
if (args.mode === "async") {
|
|
51313
|
+
const session2 = args.client.session;
|
|
51314
|
+
if (typeof session2?.promptAsync !== "function") {
|
|
51315
|
+
return;
|
|
51316
|
+
}
|
|
51317
|
+
const dispatchPromptAsync = session2.promptAsync.bind(session2);
|
|
51318
|
+
return (dispatchInput) => dispatchPromptAsync(dispatchInput);
|
|
51319
|
+
}
|
|
51320
|
+
const session = args.client.session;
|
|
51321
|
+
if (typeof session?.prompt !== "function") {
|
|
51322
|
+
return;
|
|
51323
|
+
}
|
|
51324
|
+
const dispatchPrompt = session.prompt.bind(session);
|
|
51325
|
+
return (dispatchInput) => dispatchPrompt(dispatchInput);
|
|
51326
|
+
})();
|
|
51327
|
+
if (!dispatch) {
|
|
51328
|
+
log(`[prompt-async-gate] ${sessionName} unavailable`, { sessionID, source });
|
|
51329
|
+
return { status: "unavailable" };
|
|
51330
|
+
}
|
|
51331
|
+
return dispatchAfterSessionIdle({
|
|
51332
|
+
sessionName,
|
|
51333
|
+
client,
|
|
51334
|
+
sessionID,
|
|
51335
|
+
input,
|
|
51336
|
+
source,
|
|
51337
|
+
settleMs,
|
|
51338
|
+
postDispatchHoldMs,
|
|
51339
|
+
dispatchTimeoutMs,
|
|
51340
|
+
checkStatus: args.checkStatus !== false,
|
|
51341
|
+
checkToolState: args.checkToolState !== false,
|
|
51342
|
+
dispatch
|
|
51343
|
+
});
|
|
51344
|
+
}
|
|
51345
|
+
var DEFAULT_PROMPT_ASYNC_POST_DISPATCH_HOLD_MS = 250, DEFAULT_PROMPT_DISPATCH_TIMEOUT_MS = 30000, DEFAULT_PROMPT_GATE_MESSAGES_FETCH_TIMEOUT_MS = 5000, promptGateMessagesFetchTimeoutMsForTesting, promptAsyncReservations;
|
|
51346
|
+
var init_prompt_async_gate = __esm(() => {
|
|
51347
|
+
init_logger();
|
|
51348
|
+
init_session_idle_settle();
|
|
51349
|
+
promptAsyncReservations = new Map;
|
|
51350
|
+
});
|
|
51351
|
+
|
|
51013
51352
|
// src/shared/model-suggestion-retry.ts
|
|
51014
51353
|
var init_model_suggestion_retry = __esm(() => {
|
|
51015
51354
|
init_logger();
|
|
51355
|
+
init_prompt_async_gate();
|
|
51016
51356
|
});
|
|
51017
51357
|
|
|
51018
51358
|
// src/shared/opencode-server-auth.ts
|
|
@@ -51025,7 +51365,7 @@ function getServerBasicAuthHeader() {
|
|
|
51025
51365
|
const token = Buffer.from(`${username}:${password}`, "utf8").toString("base64");
|
|
51026
51366
|
return `Basic ${token}`;
|
|
51027
51367
|
}
|
|
51028
|
-
function
|
|
51368
|
+
function isRecord8(value) {
|
|
51029
51369
|
return typeof value === "object" && value !== null;
|
|
51030
51370
|
}
|
|
51031
51371
|
function isRequestFetch(value) {
|
|
@@ -51039,11 +51379,11 @@ function wrapRequestFetch(baseFetch, auth) {
|
|
|
51039
51379
|
};
|
|
51040
51380
|
}
|
|
51041
51381
|
function getInternalClient(client) {
|
|
51042
|
-
if (!
|
|
51382
|
+
if (!isRecord8(client)) {
|
|
51043
51383
|
return null;
|
|
51044
51384
|
}
|
|
51045
51385
|
const internal = client["_client"];
|
|
51046
|
-
return
|
|
51386
|
+
return isRecord8(internal) ? internal : null;
|
|
51047
51387
|
}
|
|
51048
51388
|
function tryInjectViaSetConfigHeaders(internal, auth) {
|
|
51049
51389
|
const setConfig = internal["setConfig"];
|
|
@@ -51059,11 +51399,11 @@ function tryInjectViaSetConfigHeaders(internal, auth) {
|
|
|
51059
51399
|
}
|
|
51060
51400
|
function tryInjectViaInterceptors(internal, auth) {
|
|
51061
51401
|
const interceptors = internal["interceptors"];
|
|
51062
|
-
if (!
|
|
51402
|
+
if (!isRecord8(interceptors)) {
|
|
51063
51403
|
return false;
|
|
51064
51404
|
}
|
|
51065
51405
|
const requestInterceptors = interceptors["request"];
|
|
51066
|
-
if (!
|
|
51406
|
+
if (!isRecord8(requestInterceptors)) {
|
|
51067
51407
|
return false;
|
|
51068
51408
|
}
|
|
51069
51409
|
const use = requestInterceptors["use"];
|
|
@@ -51085,7 +51425,7 @@ function tryInjectViaFetchWrapper(internal, auth) {
|
|
|
51085
51425
|
return false;
|
|
51086
51426
|
}
|
|
51087
51427
|
const config = getConfig();
|
|
51088
|
-
if (!
|
|
51428
|
+
if (!isRecord8(config)) {
|
|
51089
51429
|
return false;
|
|
51090
51430
|
}
|
|
51091
51431
|
const fetchValue = config["fetch"];
|
|
@@ -51099,7 +51439,7 @@ function tryInjectViaFetchWrapper(internal, auth) {
|
|
|
51099
51439
|
}
|
|
51100
51440
|
function tryInjectViaMutableInternalConfig(internal, auth) {
|
|
51101
51441
|
const configValue = internal["_config"];
|
|
51102
|
-
if (!
|
|
51442
|
+
if (!isRecord8(configValue)) {
|
|
51103
51443
|
return false;
|
|
51104
51444
|
}
|
|
51105
51445
|
const fetchValue = configValue["fetch"];
|
|
@@ -51110,7 +51450,7 @@ function tryInjectViaMutableInternalConfig(internal, auth) {
|
|
|
51110
51450
|
return true;
|
|
51111
51451
|
}
|
|
51112
51452
|
function tryInjectViaTopLevelFetch(client, auth) {
|
|
51113
|
-
if (!
|
|
51453
|
+
if (!isRecord8(client)) {
|
|
51114
51454
|
return false;
|
|
51115
51455
|
}
|
|
51116
51456
|
const fetchValue = client["fetch"];
|
|
@@ -51247,11 +51587,11 @@ var init_opencode_command_dirs = __esm(() => {
|
|
|
51247
51587
|
});
|
|
51248
51588
|
|
|
51249
51589
|
// src/shared/project-discovery-dirs.ts
|
|
51250
|
-
import { existsSync as
|
|
51590
|
+
import { existsSync as existsSync13, realpathSync as realpathSync5 } from "fs";
|
|
51251
51591
|
import { dirname as dirname4, join as join14, resolve as resolve4 } from "path";
|
|
51252
51592
|
function normalizePath(path6) {
|
|
51253
51593
|
const resolvedPath = resolve4(path6);
|
|
51254
|
-
if (!
|
|
51594
|
+
if (!existsSync13(resolvedPath)) {
|
|
51255
51595
|
return resolvedPath;
|
|
51256
51596
|
}
|
|
51257
51597
|
try {
|
|
@@ -51267,7 +51607,7 @@ function findProjectOpencodePluginConfigFiles(startDirectory, stopDirectory) {
|
|
|
51267
51607
|
const resolvedStopDirectory = stopDirectory ? normalizePath(stopDirectory) : undefined;
|
|
51268
51608
|
while (true) {
|
|
51269
51609
|
const opencodeDirectory = join14(currentDirectory, ".opencode");
|
|
51270
|
-
if (
|
|
51610
|
+
if (existsSync13(opencodeDirectory)) {
|
|
51271
51611
|
const detected = detectPluginConfigFile(opencodeDirectory);
|
|
51272
51612
|
if (detected.format !== "none" && !seen.has(detected.path)) {
|
|
51273
51613
|
seen.add(detected.path);
|
|
@@ -51296,6 +51636,7 @@ var init_session_directory_resolver = () => {};
|
|
|
51296
51636
|
// src/shared/session-route.ts
|
|
51297
51637
|
var init_session_route = __esm(() => {
|
|
51298
51638
|
init_model_suggestion_retry();
|
|
51639
|
+
init_prompt_async_gate();
|
|
51299
51640
|
});
|
|
51300
51641
|
|
|
51301
51642
|
// src/shared/session-tools-store.ts
|
|
@@ -51462,6 +51803,11 @@ var init_log_legacy_plugin_startup_warning = __esm(() => {
|
|
|
51462
51803
|
init_plugin_entry_migrator();
|
|
51463
51804
|
init_plugin_identity();
|
|
51464
51805
|
});
|
|
51806
|
+
|
|
51807
|
+
// src/shared/legacy-workspace-migration.ts
|
|
51808
|
+
var init_legacy_workspace_migration = __esm(() => {
|
|
51809
|
+
init_logger();
|
|
51810
|
+
});
|
|
51465
51811
|
// src/shared/model-string-parser.ts
|
|
51466
51812
|
var KNOWN_VARIANTS2;
|
|
51467
51813
|
var init_model_string_parser = __esm(() => {
|
|
@@ -51487,6 +51833,7 @@ var init_excluded_dirs = __esm(() => {
|
|
|
51487
51833
|
"dist",
|
|
51488
51834
|
"build",
|
|
51489
51835
|
".next",
|
|
51836
|
+
".omo",
|
|
51490
51837
|
".sisyphus",
|
|
51491
51838
|
".omx",
|
|
51492
51839
|
".turbo",
|
|
@@ -51499,7 +51846,6 @@ var init_excluded_dirs = __esm(() => {
|
|
|
51499
51846
|
];
|
|
51500
51847
|
EXCLUDED_DIRS = Object.freeze(new Set(EXCLUDED_DIR_NAMES));
|
|
51501
51848
|
});
|
|
51502
|
-
|
|
51503
51849
|
// src/shared/index.ts
|
|
51504
51850
|
var init_shared = __esm(() => {
|
|
51505
51851
|
init_model_resolver();
|
|
@@ -51567,6 +51913,7 @@ var init_shared = __esm(() => {
|
|
|
51567
51913
|
init_plugin_command_discovery();
|
|
51568
51914
|
init_plugin_identity();
|
|
51569
51915
|
init_log_legacy_plugin_startup_warning();
|
|
51916
|
+
init_legacy_workspace_migration();
|
|
51570
51917
|
});
|
|
51571
51918
|
|
|
51572
51919
|
// src/cli/config-manager/config-context.ts
|
|
@@ -51646,17 +51993,17 @@ var init_plugin_name_with_version = __esm(() => {
|
|
|
51646
51993
|
});
|
|
51647
51994
|
|
|
51648
51995
|
// src/cli/config-manager/backup-config.ts
|
|
51649
|
-
import { copyFileSync as copyFileSync2, existsSync as
|
|
51996
|
+
import { copyFileSync as copyFileSync2, existsSync as existsSync14, mkdirSync as mkdirSync5 } from "fs";
|
|
51650
51997
|
import { dirname as dirname5 } from "path";
|
|
51651
51998
|
function backupConfigFile(configPath) {
|
|
51652
|
-
if (!
|
|
51999
|
+
if (!existsSync14(configPath)) {
|
|
51653
52000
|
return { success: true };
|
|
51654
52001
|
}
|
|
51655
52002
|
const timestamp2 = new Date().toISOString().replace(/[:.]/g, "-");
|
|
51656
52003
|
const backupPath = `${configPath}.backup-${timestamp2}`;
|
|
51657
52004
|
try {
|
|
51658
52005
|
const dir = dirname5(backupPath);
|
|
51659
|
-
if (!
|
|
52006
|
+
if (!existsSync14(dir)) {
|
|
51660
52007
|
mkdirSync5(dir, { recursive: true });
|
|
51661
52008
|
}
|
|
51662
52009
|
copyFileSync2(configPath, backupPath);
|
|
@@ -51671,10 +52018,10 @@ function backupConfigFile(configPath) {
|
|
|
51671
52018
|
var init_backup_config = () => {};
|
|
51672
52019
|
|
|
51673
52020
|
// src/cli/config-manager/ensure-config-directory-exists.ts
|
|
51674
|
-
import { existsSync as
|
|
52021
|
+
import { existsSync as existsSync15, mkdirSync as mkdirSync6 } from "fs";
|
|
51675
52022
|
function ensureConfigDirectoryExists() {
|
|
51676
52023
|
const configDir = getConfigDir();
|
|
51677
|
-
if (!
|
|
52024
|
+
if (!existsSync15(configDir)) {
|
|
51678
52025
|
mkdirSync6(configDir, { recursive: true });
|
|
51679
52026
|
}
|
|
51680
52027
|
}
|
|
@@ -51712,14 +52059,14 @@ function formatErrorWithSuggestion(err, context) {
|
|
|
51712
52059
|
}
|
|
51713
52060
|
|
|
51714
52061
|
// src/cli/config-manager/opencode-config-format.ts
|
|
51715
|
-
import { existsSync as
|
|
52062
|
+
import { existsSync as existsSync16 } from "fs";
|
|
51716
52063
|
function detectConfigFormat() {
|
|
51717
52064
|
const configJsonc = getConfigJsonc();
|
|
51718
52065
|
const configJson = getConfigJson();
|
|
51719
|
-
if (
|
|
52066
|
+
if (existsSync16(configJsonc)) {
|
|
51720
52067
|
return { format: "jsonc", path: configJsonc };
|
|
51721
52068
|
}
|
|
51722
|
-
if (
|
|
52069
|
+
if (existsSync16(configJson)) {
|
|
51723
52070
|
return { format: "json", path: configJson };
|
|
51724
52071
|
}
|
|
51725
52072
|
return { format: "none", path: configJson };
|
|
@@ -51729,13 +52076,13 @@ var init_opencode_config_format = __esm(() => {
|
|
|
51729
52076
|
});
|
|
51730
52077
|
|
|
51731
52078
|
// src/cli/config-manager/parse-opencode-config-file.ts
|
|
51732
|
-
import { readFileSync as readFileSync8, statSync } from "fs";
|
|
52079
|
+
import { readFileSync as readFileSync8, statSync as statSync2 } from "fs";
|
|
51733
52080
|
function isEmptyOrWhitespace(content) {
|
|
51734
52081
|
return content.trim().length === 0;
|
|
51735
52082
|
}
|
|
51736
52083
|
function parseOpenCodeConfigFileWithError(path6) {
|
|
51737
52084
|
try {
|
|
51738
|
-
const stat =
|
|
52085
|
+
const stat = statSync2(path6);
|
|
51739
52086
|
if (stat.size === 0) {
|
|
51740
52087
|
return { config: null, error: `Config file is empty: ${path6}. Delete it or add valid JSON content.` };
|
|
51741
52088
|
}
|
|
@@ -52262,7 +52609,7 @@ var init_generate_omo_config = __esm(() => {
|
|
|
52262
52609
|
});
|
|
52263
52610
|
|
|
52264
52611
|
// src/shared/migrate-legacy-config-file.ts
|
|
52265
|
-
import { existsSync as
|
|
52612
|
+
import { existsSync as existsSync17, readFileSync as readFileSync10, renameSync as renameSync3, rmSync } from "fs";
|
|
52266
52613
|
import { join as join15, dirname as dirname6, basename as basename2 } from "path";
|
|
52267
52614
|
function buildCanonicalPath(legacyPath) {
|
|
52268
52615
|
const dir = dirname6(legacyPath);
|
|
@@ -52272,7 +52619,7 @@ function buildCanonicalPath(legacyPath) {
|
|
|
52272
52619
|
function archiveLegacyConfigFile(legacyPath) {
|
|
52273
52620
|
const backupPath = `${legacyPath}.bak`;
|
|
52274
52621
|
try {
|
|
52275
|
-
|
|
52622
|
+
renameSync3(legacyPath, backupPath);
|
|
52276
52623
|
log("[migrateLegacyConfigFile] Legacy config was migrated and renamed to backup. Update the canonical file only.", {
|
|
52277
52624
|
legacyPath,
|
|
52278
52625
|
backupPath
|
|
@@ -52300,10 +52647,10 @@ function archiveLegacyConfigFile(legacyPath) {
|
|
|
52300
52647
|
}
|
|
52301
52648
|
function migrateLegacySidecarFile(legacyPath, canonicalPath) {
|
|
52302
52649
|
const legacySidecarPath = getSidecarPath(legacyPath);
|
|
52303
|
-
if (!
|
|
52650
|
+
if (!existsSync17(legacySidecarPath))
|
|
52304
52651
|
return true;
|
|
52305
52652
|
const canonicalSidecarPath = getSidecarPath(canonicalPath);
|
|
52306
|
-
if (
|
|
52653
|
+
if (existsSync17(canonicalSidecarPath))
|
|
52307
52654
|
return true;
|
|
52308
52655
|
try {
|
|
52309
52656
|
const content = readFileSync10(legacySidecarPath, "utf-8");
|
|
@@ -52323,12 +52670,12 @@ function migrateLegacySidecarFile(legacyPath, canonicalPath) {
|
|
|
52323
52670
|
}
|
|
52324
52671
|
}
|
|
52325
52672
|
function migrateLegacyConfigFile(legacyPath) {
|
|
52326
|
-
if (!
|
|
52673
|
+
if (!existsSync17(legacyPath))
|
|
52327
52674
|
return false;
|
|
52328
52675
|
if (!basename2(legacyPath).startsWith(LEGACY_CONFIG_BASENAME))
|
|
52329
52676
|
return false;
|
|
52330
52677
|
const canonicalPath = buildCanonicalPath(legacyPath);
|
|
52331
|
-
if (
|
|
52678
|
+
if (existsSync17(canonicalPath))
|
|
52332
52679
|
return false;
|
|
52333
52680
|
try {
|
|
52334
52681
|
const content = readFileSync10(legacyPath, "utf-8");
|
|
@@ -52372,7 +52719,7 @@ function deepMergeRecord(target, source) {
|
|
|
52372
52719
|
}
|
|
52373
52720
|
|
|
52374
52721
|
// src/cli/config-manager/write-omo-config.ts
|
|
52375
|
-
import { existsSync as
|
|
52722
|
+
import { existsSync as existsSync18, readFileSync as readFileSync11, statSync as statSync3, writeFileSync as writeFileSync4 } from "fs";
|
|
52376
52723
|
import { basename as basename3, dirname as dirname7, extname, join as join16 } from "path";
|
|
52377
52724
|
function isEmptyOrWhitespace2(content) {
|
|
52378
52725
|
return content.trim().length === 0;
|
|
@@ -52390,10 +52737,10 @@ function writeOmoConfig(installConfig) {
|
|
|
52390
52737
|
const detectedConfigPath = getOmoConfigPath();
|
|
52391
52738
|
const canonicalConfigPath = join16(dirname7(detectedConfigPath), `${CONFIG_BASENAME}${extname(detectedConfigPath) || ".json"}`);
|
|
52392
52739
|
const shouldMigrateLegacyPath = basename3(detectedConfigPath).startsWith(LEGACY_CONFIG_BASENAME);
|
|
52393
|
-
const omoConfigPath = shouldMigrateLegacyPath ? migrateLegacyConfigFile(detectedConfigPath) ||
|
|
52740
|
+
const omoConfigPath = shouldMigrateLegacyPath ? migrateLegacyConfigFile(detectedConfigPath) || existsSync18(canonicalConfigPath) ? canonicalConfigPath : detectedConfigPath : detectedConfigPath;
|
|
52394
52741
|
try {
|
|
52395
52742
|
const newConfig = generateOmoConfig(installConfig);
|
|
52396
|
-
if (
|
|
52743
|
+
if (existsSync18(omoConfigPath)) {
|
|
52397
52744
|
const backupResult = backupConfigFile(omoConfigPath);
|
|
52398
52745
|
if (!backupResult.success) {
|
|
52399
52746
|
return {
|
|
@@ -52403,7 +52750,7 @@ function writeOmoConfig(installConfig) {
|
|
|
52403
52750
|
};
|
|
52404
52751
|
}
|
|
52405
52752
|
try {
|
|
52406
|
-
const stat =
|
|
52753
|
+
const stat = statSync3(omoConfigPath);
|
|
52407
52754
|
const content = readFileSync11(omoConfigPath, "utf-8");
|
|
52408
52755
|
if (stat.size === 0 || isEmptyOrWhitespace2(content)) {
|
|
52409
52756
|
writeFileSync4(omoConfigPath, JSON.stringify(newConfig, null, 2) + `
|
|
@@ -52600,10 +52947,10 @@ var init_opencode_binary = __esm(() => {
|
|
|
52600
52947
|
});
|
|
52601
52948
|
|
|
52602
52949
|
// src/cli/config-manager/detect-current-config.ts
|
|
52603
|
-
import { existsSync as
|
|
52950
|
+
import { existsSync as existsSync19, readFileSync as readFileSync12 } from "fs";
|
|
52604
52951
|
function detectProvidersFromOmoConfig() {
|
|
52605
52952
|
const omoConfigPath = getOmoConfigPath();
|
|
52606
|
-
if (!
|
|
52953
|
+
if (!existsSync19(omoConfigPath)) {
|
|
52607
52954
|
return {
|
|
52608
52955
|
hasOpenAI: true,
|
|
52609
52956
|
hasOpencodeZen: true,
|
|
@@ -52703,7 +53050,7 @@ var init_detect_current_config = __esm(() => {
|
|
|
52703
53050
|
});
|
|
52704
53051
|
|
|
52705
53052
|
// src/cli/config-manager/bun-install.ts
|
|
52706
|
-
import { existsSync as
|
|
53053
|
+
import { existsSync as existsSync20 } from "fs";
|
|
52707
53054
|
import { join as join17 } from "path";
|
|
52708
53055
|
function getDefaultWorkspaceDir() {
|
|
52709
53056
|
return join17(getOpenCodeCacheDir(), "packages");
|
|
@@ -52732,7 +53079,7 @@ async function runBunInstallWithDetails(options) {
|
|
|
52732
53079
|
const outputMode = options?.outputMode ?? "pipe";
|
|
52733
53080
|
const cacheDir = options?.workspaceDir ?? getDefaultWorkspaceDir();
|
|
52734
53081
|
const packageJsonPath = `${cacheDir}/package.json`;
|
|
52735
|
-
if (!
|
|
53082
|
+
if (!existsSync20(packageJsonPath)) {
|
|
52736
53083
|
return {
|
|
52737
53084
|
success: false,
|
|
52738
53085
|
error: `Workspace not initialized: ${packageJsonPath} not found. OpenCode should create this on first run.`
|
|
@@ -53530,17 +53877,21 @@ function readPackageVersion(packageJsonPath) {
|
|
|
53530
53877
|
const pkg = JSON.parse(content);
|
|
53531
53878
|
return pkg.version ?? null;
|
|
53532
53879
|
}
|
|
53533
|
-
function getCachedVersion() {
|
|
53880
|
+
function getCachedVersion(options = {}) {
|
|
53881
|
+
const packageJsonCandidates = options.packageJsonCandidates ?? INSTALLED_PACKAGE_JSON_CANDIDATES;
|
|
53882
|
+
const findPackageJson = options.findPackageJson ?? findPackageJsonUp;
|
|
53534
53883
|
try {
|
|
53535
|
-
const currentDir = path10.dirname(fileURLToPath2(import.meta.url));
|
|
53536
|
-
|
|
53537
|
-
|
|
53538
|
-
|
|
53884
|
+
const currentDir = options.currentDir === undefined ? path10.dirname(fileURLToPath2(import.meta.url)) : options.currentDir;
|
|
53885
|
+
if (currentDir) {
|
|
53886
|
+
const pkgPath = findPackageJson(currentDir);
|
|
53887
|
+
if (pkgPath) {
|
|
53888
|
+
return readPackageVersion(pkgPath);
|
|
53889
|
+
}
|
|
53539
53890
|
}
|
|
53540
53891
|
} catch (err) {
|
|
53541
53892
|
log("[auto-update-checker] Failed to resolve version from current directory:", err);
|
|
53542
53893
|
}
|
|
53543
|
-
for (const candidate of
|
|
53894
|
+
for (const candidate of packageJsonCandidates) {
|
|
53544
53895
|
try {
|
|
53545
53896
|
if (fs9.existsSync(candidate)) {
|
|
53546
53897
|
return readPackageVersion(candidate);
|
|
@@ -53548,10 +53899,12 @@ function getCachedVersion() {
|
|
|
53548
53899
|
} catch {}
|
|
53549
53900
|
}
|
|
53550
53901
|
try {
|
|
53551
|
-
const execDir = path10.dirname(fs9.realpathSync(process.execPath));
|
|
53552
|
-
|
|
53553
|
-
|
|
53554
|
-
|
|
53902
|
+
const execDir = options.execDir === undefined ? path10.dirname(fs9.realpathSync(process.execPath)) : options.execDir;
|
|
53903
|
+
if (execDir) {
|
|
53904
|
+
const pkgPath = findPackageJson(execDir);
|
|
53905
|
+
if (pkgPath) {
|
|
53906
|
+
return readPackageVersion(pkgPath);
|
|
53907
|
+
}
|
|
53555
53908
|
}
|
|
53556
53909
|
} catch (err) {
|
|
53557
53910
|
log("[auto-update-checker] Failed to resolve version from execPath:", err);
|
|
@@ -53800,17 +54153,22 @@ import * as path12 from "path";
|
|
|
53800
54153
|
function stripTrailingCommas(json3) {
|
|
53801
54154
|
return json3.replace(/,(\s*[}\]])/g, "$1");
|
|
53802
54155
|
}
|
|
53803
|
-
function removeFromTextBunLock(lockPath,
|
|
54156
|
+
function removeFromTextBunLock(lockPath, packageNames) {
|
|
53804
54157
|
try {
|
|
53805
54158
|
const content = fs11.readFileSync(lockPath, "utf-8");
|
|
53806
54159
|
const lock = JSON.parse(stripTrailingCommas(content));
|
|
53807
|
-
|
|
53808
|
-
|
|
54160
|
+
let removed = false;
|
|
54161
|
+
for (const packageName of packageNames) {
|
|
54162
|
+
if (lock.packages?.[packageName]) {
|
|
54163
|
+
delete lock.packages[packageName];
|
|
54164
|
+
log(`[auto-update-checker] Removed from bun.lock: ${packageName}`);
|
|
54165
|
+
removed = true;
|
|
54166
|
+
}
|
|
54167
|
+
}
|
|
54168
|
+
if (removed) {
|
|
53809
54169
|
fs11.writeFileSync(lockPath, JSON.stringify(lock, null, 2));
|
|
53810
|
-
log(`[auto-update-checker] Removed from bun.lock: ${packageName}`);
|
|
53811
|
-
return true;
|
|
53812
54170
|
}
|
|
53813
|
-
return
|
|
54171
|
+
return removed;
|
|
53814
54172
|
} catch {
|
|
53815
54173
|
return false;
|
|
53816
54174
|
}
|
|
@@ -53824,26 +54182,57 @@ function deleteBinaryBunLock(lockPath) {
|
|
|
53824
54182
|
return false;
|
|
53825
54183
|
}
|
|
53826
54184
|
}
|
|
53827
|
-
function removeFromBunLock(
|
|
53828
|
-
const textLockPath = path12.join(
|
|
53829
|
-
const binaryLockPath = path12.join(
|
|
54185
|
+
function removeFromBunLock(cacheDir, packageNames) {
|
|
54186
|
+
const textLockPath = path12.join(cacheDir, "bun.lock");
|
|
54187
|
+
const binaryLockPath = path12.join(cacheDir, "bun.lockb");
|
|
53830
54188
|
if (fs11.existsSync(textLockPath)) {
|
|
53831
|
-
return removeFromTextBunLock(textLockPath,
|
|
54189
|
+
return removeFromTextBunLock(textLockPath, packageNames);
|
|
53832
54190
|
}
|
|
53833
54191
|
if (fs11.existsSync(binaryLockPath)) {
|
|
53834
54192
|
return deleteBinaryBunLock(binaryLockPath);
|
|
53835
54193
|
}
|
|
53836
54194
|
return false;
|
|
53837
54195
|
}
|
|
53838
|
-
function
|
|
54196
|
+
function getInvalidationPackageNames(packageName, defaultPackageName, acceptedPackageNames) {
|
|
54197
|
+
if (packageName === defaultPackageName) {
|
|
54198
|
+
return acceptedPackageNames;
|
|
54199
|
+
}
|
|
54200
|
+
return [packageName];
|
|
54201
|
+
}
|
|
54202
|
+
function removeSpecifierRootDirs(cacheDir, packageNames) {
|
|
54203
|
+
const parentDirs = [cacheDir, path12.join(cacheDir, "packages")];
|
|
54204
|
+
const prefixes = packageNames.map((packageName) => `${packageName}@`);
|
|
54205
|
+
let removed = false;
|
|
54206
|
+
for (const parentDir of parentDirs) {
|
|
54207
|
+
if (!fs11.existsSync(parentDir)) {
|
|
54208
|
+
continue;
|
|
54209
|
+
}
|
|
54210
|
+
for (const entry of fs11.readdirSync(parentDir, { withFileTypes: true })) {
|
|
54211
|
+
if (!entry.isDirectory() || !prefixes.some((prefix) => entry.name.startsWith(prefix))) {
|
|
54212
|
+
continue;
|
|
54213
|
+
}
|
|
54214
|
+
const specifierDir = path12.join(parentDir, entry.name);
|
|
54215
|
+
fs11.rmSync(specifierDir, { recursive: true, force: true });
|
|
54216
|
+
log(`[auto-update-checker] Specifier cache removed: ${specifierDir}`);
|
|
54217
|
+
removed = true;
|
|
54218
|
+
}
|
|
54219
|
+
}
|
|
54220
|
+
return removed;
|
|
54221
|
+
}
|
|
54222
|
+
function invalidatePackage(packageName = PACKAGE_NAME2, options = {}) {
|
|
53839
54223
|
try {
|
|
53840
|
-
const
|
|
53841
|
-
const
|
|
53842
|
-
|
|
53843
|
-
|
|
53844
|
-
|
|
54224
|
+
const acceptedPackageNames = options.acceptedPackageNames ?? ACCEPTED_PACKAGE_NAMES2;
|
|
54225
|
+
const cacheDir = options.cacheDir ?? CACHE_DIR;
|
|
54226
|
+
const defaultPackageName = options.defaultPackageName ?? PACKAGE_NAME2;
|
|
54227
|
+
const userConfigDir = options.userConfigDir ?? getUserConfigDir();
|
|
54228
|
+
const packageNames = getInvalidationPackageNames(packageName, defaultPackageName, acceptedPackageNames);
|
|
54229
|
+
const pkgDirs = packageNames.flatMap((name) => [
|
|
54230
|
+
path12.join(userConfigDir, "node_modules", name),
|
|
54231
|
+
path12.join(cacheDir, "node_modules", name)
|
|
54232
|
+
]);
|
|
53845
54233
|
let packageRemoved = false;
|
|
53846
54234
|
let lockRemoved = false;
|
|
54235
|
+
let specifierRemoved = false;
|
|
53847
54236
|
for (const pkgDir of pkgDirs) {
|
|
53848
54237
|
if (fs11.existsSync(pkgDir)) {
|
|
53849
54238
|
fs11.rmSync(pkgDir, { recursive: true, force: true });
|
|
@@ -53851,8 +54240,9 @@ function invalidatePackage(packageName = PACKAGE_NAME2) {
|
|
|
53851
54240
|
packageRemoved = true;
|
|
53852
54241
|
}
|
|
53853
54242
|
}
|
|
53854
|
-
|
|
53855
|
-
|
|
54243
|
+
specifierRemoved = removeSpecifierRootDirs(cacheDir, packageNames);
|
|
54244
|
+
lockRemoved = removeFromBunLock(cacheDir, packageNames);
|
|
54245
|
+
if (!packageRemoved && !specifierRemoved && !lockRemoved) {
|
|
53856
54246
|
log(`[auto-update-checker] Package not found, nothing to invalidate: ${packageName}`);
|
|
53857
54247
|
return false;
|
|
53858
54248
|
}
|
|
@@ -53900,7 +54290,7 @@ var init_update_toasts = __esm(() => {
|
|
|
53900
54290
|
});
|
|
53901
54291
|
|
|
53902
54292
|
// src/hooks/auto-update-checker/hook/background-update-check.ts
|
|
53903
|
-
import { existsSync as
|
|
54293
|
+
import { existsSync as existsSync33 } from "fs";
|
|
53904
54294
|
import { join as join30 } from "path";
|
|
53905
54295
|
function getCacheWorkspaceDir(deps) {
|
|
53906
54296
|
return deps.join(deps.getOpenCodeCacheDir(), "packages");
|
|
@@ -53951,7 +54341,7 @@ async function primeCacheWorkspace(activeWorkspace, deps) {
|
|
|
53951
54341
|
return runBunInstallSafe(cacheWorkspace, deps);
|
|
53952
54342
|
}
|
|
53953
54343
|
function createBackgroundUpdateCheckRunner(overrides = {}) {
|
|
53954
|
-
const deps = { ...
|
|
54344
|
+
const deps = { ...defaultDeps3, ...overrides };
|
|
53955
54345
|
return async function runBackgroundUpdateCheck(ctx, autoUpdate, getToastMessage) {
|
|
53956
54346
|
const pluginInfo = deps.findPluginEntry(ctx.directory);
|
|
53957
54347
|
if (!pluginInfo) {
|
|
@@ -54009,7 +54399,7 @@ function createBackgroundUpdateCheckRunner(overrides = {}) {
|
|
|
54009
54399
|
deps.log("[auto-update-checker] bun install failed; update not installed (falling back to notification-only)");
|
|
54010
54400
|
};
|
|
54011
54401
|
}
|
|
54012
|
-
var
|
|
54402
|
+
var defaultDeps3, runBackgroundUpdateCheck;
|
|
54013
54403
|
var init_background_update_check = __esm(() => {
|
|
54014
54404
|
init_config_manager();
|
|
54015
54405
|
init_logger();
|
|
@@ -54018,8 +54408,8 @@ var init_background_update_check = __esm(() => {
|
|
|
54018
54408
|
init_constants3();
|
|
54019
54409
|
init_checker();
|
|
54020
54410
|
init_update_toasts();
|
|
54021
|
-
|
|
54022
|
-
existsSync:
|
|
54411
|
+
defaultDeps3 = {
|
|
54412
|
+
existsSync: existsSync33,
|
|
54023
54413
|
join: join30,
|
|
54024
54414
|
runBunInstallWithDetails,
|
|
54025
54415
|
log,
|
|
@@ -54205,7 +54595,7 @@ var init_startup_toasts = __esm(() => {
|
|
|
54205
54595
|
});
|
|
54206
54596
|
|
|
54207
54597
|
// src/hooks/auto-update-checker/hook.ts
|
|
54208
|
-
function createAutoUpdateCheckerHook(ctx, options = {}, deps =
|
|
54598
|
+
function createAutoUpdateCheckerHook(ctx, options = {}, deps = defaultDeps4) {
|
|
54209
54599
|
const {
|
|
54210
54600
|
showStartupToast = true,
|
|
54211
54601
|
isSisyphusEnabled = false,
|
|
@@ -54262,13 +54652,13 @@ v${latestVersion} available. Restart OpenCode to apply.` : "OpenCode is now on S
|
|
|
54262
54652
|
}
|
|
54263
54653
|
};
|
|
54264
54654
|
}
|
|
54265
|
-
var
|
|
54655
|
+
var defaultDeps4, isRecord9 = (value) => {
|
|
54266
54656
|
return typeof value === "object" && value !== null;
|
|
54267
54657
|
}, getParentID = (properties) => {
|
|
54268
|
-
if (!
|
|
54658
|
+
if (!isRecord9(properties))
|
|
54269
54659
|
return;
|
|
54270
54660
|
const { info } = properties;
|
|
54271
|
-
if (!
|
|
54661
|
+
if (!isRecord9(info))
|
|
54272
54662
|
return;
|
|
54273
54663
|
const { parentID } = info;
|
|
54274
54664
|
return typeof parentID === "string" && parentID.length > 0 ? parentID : undefined;
|
|
@@ -54282,7 +54672,7 @@ var init_hook = __esm(() => {
|
|
|
54282
54672
|
init_model_capabilities_status();
|
|
54283
54673
|
init_model_cache_warning();
|
|
54284
54674
|
init_startup_toasts();
|
|
54285
|
-
|
|
54675
|
+
defaultDeps4 = {
|
|
54286
54676
|
getCachedVersion,
|
|
54287
54677
|
getLocalDevVersion,
|
|
54288
54678
|
showConfigErrorsIfAny,
|
|
@@ -54332,7 +54722,7 @@ var {
|
|
|
54332
54722
|
// package.json
|
|
54333
54723
|
var package_default = {
|
|
54334
54724
|
name: "oh-my-opencode",
|
|
54335
|
-
version: "4.1
|
|
54725
|
+
version: "4.2.1",
|
|
54336
54726
|
description: "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
|
|
54337
54727
|
main: "./dist/index.js",
|
|
54338
54728
|
types: "dist/index.d.ts",
|
|
@@ -54344,7 +54734,8 @@ var package_default = {
|
|
|
54344
54734
|
files: [
|
|
54345
54735
|
"dist",
|
|
54346
54736
|
"bin",
|
|
54347
|
-
"postinstall.mjs"
|
|
54737
|
+
"postinstall.mjs",
|
|
54738
|
+
"packages/lsp-tools-mcp/dist"
|
|
54348
54739
|
],
|
|
54349
54740
|
exports: {
|
|
54350
54741
|
".": {
|
|
@@ -54355,6 +54746,7 @@ var package_default = {
|
|
|
54355
54746
|
},
|
|
54356
54747
|
scripts: {
|
|
54357
54748
|
build: "bun build src/index.ts --outdir dist --target bun --format esm --external @ast-grep/napi --external zod && bun run build:node-require-shim && tsc --emitDeclarationOnly && bun build src/cli/index.ts --outdir dist/cli --target bun --format esm --external @ast-grep/napi && bun run build:schema",
|
|
54749
|
+
"build:lsp-tools-mcp": "npm --prefix packages/lsp-tools-mcp ci && npm --prefix packages/lsp-tools-mcp run build",
|
|
54358
54750
|
"build:node-require-shim": "bun run script/patch-node-require-shim.ts",
|
|
54359
54751
|
"build:all": "bun run build && bun run build:binaries",
|
|
54360
54752
|
"build:binaries": "bun run script/build-binaries.ts",
|
|
@@ -54363,11 +54755,11 @@ var package_default = {
|
|
|
54363
54755
|
clean: "rm -rf dist",
|
|
54364
54756
|
prepare: "bun run build",
|
|
54365
54757
|
postinstall: "node postinstall.mjs",
|
|
54366
|
-
prepublishOnly: "bun run clean && bun run build",
|
|
54758
|
+
prepublishOnly: "bun run clean && bun run build:lsp-tools-mcp && bun run build",
|
|
54367
54759
|
"test:model-capabilities": "bun test src/shared/model-capability-aliases.test.ts src/shared/model-capability-guardrails.test.ts src/shared/model-capabilities.test.ts src/cli/doctor/checks/model-resolution.test.ts --bail",
|
|
54368
54760
|
typecheck: "tsgo --noEmit",
|
|
54369
54761
|
"typecheck:script": "tsgo --noEmit -p script/tsconfig.json",
|
|
54370
|
-
test: "bun
|
|
54762
|
+
test: "bun test"
|
|
54371
54763
|
},
|
|
54372
54764
|
keywords: [
|
|
54373
54765
|
"opencode",
|
|
@@ -54392,7 +54784,7 @@ var package_default = {
|
|
|
54392
54784
|
"@ast-grep/cli": "^0.41.1",
|
|
54393
54785
|
"@ast-grep/napi": "^0.41.1",
|
|
54394
54786
|
"@clack/prompts": "^0.11.0",
|
|
54395
|
-
"@code-yeongyu/comment-checker": "^0.7.
|
|
54787
|
+
"@code-yeongyu/comment-checker": "^0.7.1",
|
|
54396
54788
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
54397
54789
|
"@opencode-ai/plugin": "^1.4.0",
|
|
54398
54790
|
"@opencode-ai/sdk": "^1.4.0",
|
|
@@ -54415,17 +54807,17 @@ var package_default = {
|
|
|
54415
54807
|
zod: "^4.4.3"
|
|
54416
54808
|
},
|
|
54417
54809
|
optionalDependencies: {
|
|
54418
|
-
"oh-my-opencode-darwin-arm64": "4.1
|
|
54419
|
-
"oh-my-opencode-darwin-x64": "4.1
|
|
54420
|
-
"oh-my-opencode-darwin-x64-baseline": "4.1
|
|
54421
|
-
"oh-my-opencode-linux-arm64": "4.1
|
|
54422
|
-
"oh-my-opencode-linux-arm64-musl": "4.1
|
|
54423
|
-
"oh-my-opencode-linux-x64": "4.1
|
|
54424
|
-
"oh-my-opencode-linux-x64-baseline": "4.1
|
|
54425
|
-
"oh-my-opencode-linux-x64-musl": "4.1
|
|
54426
|
-
"oh-my-opencode-linux-x64-musl-baseline": "4.1
|
|
54427
|
-
"oh-my-opencode-windows-x64": "4.1
|
|
54428
|
-
"oh-my-opencode-windows-x64-baseline": "4.1
|
|
54810
|
+
"oh-my-opencode-darwin-arm64": "4.2.1",
|
|
54811
|
+
"oh-my-opencode-darwin-x64": "4.2.1",
|
|
54812
|
+
"oh-my-opencode-darwin-x64-baseline": "4.2.1",
|
|
54813
|
+
"oh-my-opencode-linux-arm64": "4.2.1",
|
|
54814
|
+
"oh-my-opencode-linux-arm64-musl": "4.2.1",
|
|
54815
|
+
"oh-my-opencode-linux-x64": "4.2.1",
|
|
54816
|
+
"oh-my-opencode-linux-x64-baseline": "4.2.1",
|
|
54817
|
+
"oh-my-opencode-linux-x64-musl": "4.2.1",
|
|
54818
|
+
"oh-my-opencode-linux-x64-musl-baseline": "4.2.1",
|
|
54819
|
+
"oh-my-opencode-windows-x64": "4.2.1",
|
|
54820
|
+
"oh-my-opencode-windows-x64-baseline": "4.2.1"
|
|
54429
54821
|
},
|
|
54430
54822
|
overrides: {
|
|
54431
54823
|
hono: "^4.12.18",
|
|
@@ -70868,7 +71260,7 @@ var NotificationConfigSchema = exports_external.object({
|
|
|
70868
71260
|
force_enable: exports_external.boolean().optional()
|
|
70869
71261
|
});
|
|
70870
71262
|
// src/mcp/types.ts
|
|
70871
|
-
var McpNameSchema = exports_external.enum(["websearch", "context7", "grep_app"]);
|
|
71263
|
+
var McpNameSchema = exports_external.enum(["websearch", "context7", "grep_app", "lsp"]);
|
|
70872
71264
|
var AnyMcpNameSchema = exports_external.string().min(1);
|
|
70873
71265
|
|
|
70874
71266
|
// src/config/schema/agent-definitions.ts
|
|
@@ -71235,7 +71627,10 @@ function loadConfigFromPath(configPath, _ctx) {
|
|
|
71235
71627
|
const result = OhMyOpenCodeConfigSchema.safeParse(rawConfig);
|
|
71236
71628
|
if (result.success) {
|
|
71237
71629
|
addAgentOrderWarnings(configPath, result.data.agent_order);
|
|
71238
|
-
log(`Config loaded from ${configPath}`, {
|
|
71630
|
+
log(`Config loaded from ${configPath}`, {
|
|
71631
|
+
agents: result.data.agents,
|
|
71632
|
+
team_mode: result.data.team_mode
|
|
71633
|
+
});
|
|
71239
71634
|
return result.data;
|
|
71240
71635
|
}
|
|
71241
71636
|
const errorMsg = result.error.issues.map((i2) => `${i2.path.join(".")}: ${i2.message}`).join(", ");
|
|
@@ -71247,7 +71642,10 @@ function loadConfigFromPath(configPath, _ctx) {
|
|
|
71247
71642
|
const partialResult = parseConfigPartially(rawConfig);
|
|
71248
71643
|
if (partialResult) {
|
|
71249
71644
|
addAgentOrderWarnings(configPath, partialResult.agent_order);
|
|
71250
|
-
log(`Partial config loaded from ${configPath}`, {
|
|
71645
|
+
log(`Partial config loaded from ${configPath}`, {
|
|
71646
|
+
agents: partialResult.agents,
|
|
71647
|
+
team_mode: partialResult.team_mode
|
|
71648
|
+
});
|
|
71251
71649
|
return partialResult;
|
|
71252
71650
|
}
|
|
71253
71651
|
return null;
|
|
@@ -71393,6 +71791,7 @@ function loadPluginConfig(directory, ctx) {
|
|
|
71393
71791
|
};
|
|
71394
71792
|
log("Final merged config", {
|
|
71395
71793
|
agents: config2.agents,
|
|
71794
|
+
team_mode: config2.team_mode,
|
|
71396
71795
|
disabled_agents: config2.disabled_agents,
|
|
71397
71796
|
disabled_mcps: config2.disabled_mcps,
|
|
71398
71797
|
disabled_hooks: config2.disabled_hooks,
|
|
@@ -72989,6 +73388,14 @@ async function withWorkingOpencodePath(startServer, finder = findWorkingOpencode
|
|
|
72989
73388
|
|
|
72990
73389
|
// src/cli/run/server-connection.ts
|
|
72991
73390
|
var LOOPBACK_HOSTS = new Set(["127.0.0.1", "localhost", "::1", "[::1]", "0.0.0.0"]);
|
|
73391
|
+
var defaultDeps2 = {
|
|
73392
|
+
createOpencode,
|
|
73393
|
+
createOpencodeClient,
|
|
73394
|
+
injectServerAuthIntoClient,
|
|
73395
|
+
isPortAvailable,
|
|
73396
|
+
getAvailableServerPort,
|
|
73397
|
+
withWorkingOpencodePath
|
|
73398
|
+
};
|
|
72992
73399
|
function isLoopbackAttachUrl(url2) {
|
|
72993
73400
|
try {
|
|
72994
73401
|
const parsed = new URL(url2);
|
|
@@ -73009,19 +73416,19 @@ function isPortRangeExhausted(error51) {
|
|
|
73009
73416
|
}
|
|
73010
73417
|
return error51.message.includes("No available port found in range");
|
|
73011
73418
|
}
|
|
73012
|
-
async function startServer(options) {
|
|
73419
|
+
async function startServer(options, deps) {
|
|
73013
73420
|
const { signal, port } = options;
|
|
73014
|
-
const { client: client3, server: server2 } = await withWorkingOpencodePath(() => createOpencode({ signal, port, hostname: "127.0.0.1" }));
|
|
73421
|
+
const { client: client3, server: server2 } = await deps.withWorkingOpencodePath(() => deps.createOpencode({ signal, port, hostname: "127.0.0.1" }));
|
|
73015
73422
|
console.log(import_picocolors10.default.dim("Server listening at"), import_picocolors10.default.cyan(server2.url));
|
|
73016
73423
|
return { client: client3, cleanup: () => server2.close() };
|
|
73017
73424
|
}
|
|
73018
|
-
async function
|
|
73425
|
+
async function createServerConnectionWithDeps(options, deps) {
|
|
73019
73426
|
const { port, attach, signal } = options;
|
|
73020
73427
|
if (attach !== undefined) {
|
|
73021
73428
|
console.log(import_picocolors10.default.dim("Attaching to existing server at"), import_picocolors10.default.cyan(attach));
|
|
73022
|
-
const client3 = createOpencodeClient({ baseUrl: attach });
|
|
73429
|
+
const client3 = deps.createOpencodeClient({ baseUrl: attach });
|
|
73023
73430
|
if (isLoopbackAttachUrl(attach)) {
|
|
73024
|
-
injectServerAuthIntoClient(client3);
|
|
73431
|
+
deps.injectServerAuthIntoClient(client3);
|
|
73025
73432
|
}
|
|
73026
73433
|
return { client: client3, cleanup: () => {} };
|
|
73027
73434
|
}
|
|
@@ -73029,47 +73436,47 @@ async function createServerConnection(options) {
|
|
|
73029
73436
|
if (port < 1 || port > 65535) {
|
|
73030
73437
|
throw new Error("Port must be between 1 and 65535");
|
|
73031
73438
|
}
|
|
73032
|
-
const available = await isPortAvailable(port, "127.0.0.1");
|
|
73439
|
+
const available = await deps.isPortAvailable(port, "127.0.0.1");
|
|
73033
73440
|
if (available) {
|
|
73034
73441
|
console.log(import_picocolors10.default.dim("Starting server on port"), import_picocolors10.default.cyan(port.toString()));
|
|
73035
73442
|
try {
|
|
73036
|
-
return await startServer({ signal, port });
|
|
73443
|
+
return await startServer({ signal, port }, deps);
|
|
73037
73444
|
} catch (error51) {
|
|
73038
73445
|
if (!isPortStartFailure(error51, port)) {
|
|
73039
73446
|
throw error51;
|
|
73040
73447
|
}
|
|
73041
|
-
const stillAvailable = await isPortAvailable(port, "127.0.0.1");
|
|
73448
|
+
const stillAvailable = await deps.isPortAvailable(port, "127.0.0.1");
|
|
73042
73449
|
if (stillAvailable) {
|
|
73043
73450
|
throw error51;
|
|
73044
73451
|
}
|
|
73045
73452
|
console.log(import_picocolors10.default.dim("Port"), import_picocolors10.default.cyan(port.toString()), import_picocolors10.default.dim("became occupied, attaching to existing server"));
|
|
73046
|
-
const client4 = createOpencodeClient({ baseUrl: `http://127.0.0.1:${port}` });
|
|
73047
|
-
injectServerAuthIntoClient(client4);
|
|
73453
|
+
const client4 = deps.createOpencodeClient({ baseUrl: `http://127.0.0.1:${port}` });
|
|
73454
|
+
deps.injectServerAuthIntoClient(client4);
|
|
73048
73455
|
return { client: client4, cleanup: () => {} };
|
|
73049
73456
|
}
|
|
73050
73457
|
}
|
|
73051
73458
|
console.log(import_picocolors10.default.dim("Port"), import_picocolors10.default.cyan(port.toString()), import_picocolors10.default.dim("is occupied, attaching to existing server"));
|
|
73052
|
-
const client3 = createOpencodeClient({ baseUrl: `http://127.0.0.1:${port}` });
|
|
73053
|
-
injectServerAuthIntoClient(client3);
|
|
73459
|
+
const client3 = deps.createOpencodeClient({ baseUrl: `http://127.0.0.1:${port}` });
|
|
73460
|
+
deps.injectServerAuthIntoClient(client3);
|
|
73054
73461
|
return { client: client3, cleanup: () => {} };
|
|
73055
73462
|
}
|
|
73056
73463
|
let selectedPort;
|
|
73057
73464
|
let wasAutoSelected;
|
|
73058
73465
|
try {
|
|
73059
|
-
const selected = await getAvailableServerPort(DEFAULT_SERVER_PORT, "127.0.0.1");
|
|
73466
|
+
const selected = await deps.getAvailableServerPort(DEFAULT_SERVER_PORT, "127.0.0.1");
|
|
73060
73467
|
selectedPort = selected.port;
|
|
73061
73468
|
wasAutoSelected = selected.wasAutoSelected;
|
|
73062
73469
|
} catch (error51) {
|
|
73063
73470
|
if (!isPortRangeExhausted(error51)) {
|
|
73064
73471
|
throw error51;
|
|
73065
73472
|
}
|
|
73066
|
-
const defaultPortIsAvailable = await isPortAvailable(DEFAULT_SERVER_PORT, "127.0.0.1");
|
|
73473
|
+
const defaultPortIsAvailable = await deps.isPortAvailable(DEFAULT_SERVER_PORT, "127.0.0.1");
|
|
73067
73474
|
if (defaultPortIsAvailable) {
|
|
73068
73475
|
throw error51;
|
|
73069
73476
|
}
|
|
73070
73477
|
console.log(import_picocolors10.default.dim("Port range exhausted, attaching to existing server on"), import_picocolors10.default.cyan(DEFAULT_SERVER_PORT.toString()));
|
|
73071
|
-
const client3 = createOpencodeClient({ baseUrl: `http://127.0.0.1:${DEFAULT_SERVER_PORT}` });
|
|
73072
|
-
injectServerAuthIntoClient(client3);
|
|
73478
|
+
const client3 = deps.createOpencodeClient({ baseUrl: `http://127.0.0.1:${DEFAULT_SERVER_PORT}` });
|
|
73479
|
+
deps.injectServerAuthIntoClient(client3);
|
|
73073
73480
|
return { client: client3, cleanup: () => {} };
|
|
73074
73481
|
}
|
|
73075
73482
|
if (wasAutoSelected) {
|
|
@@ -73078,16 +73485,19 @@ async function createServerConnection(options) {
|
|
|
73078
73485
|
console.log(import_picocolors10.default.dim("Starting server on port"), import_picocolors10.default.cyan(selectedPort.toString()));
|
|
73079
73486
|
}
|
|
73080
73487
|
try {
|
|
73081
|
-
return await startServer({ signal, port: selectedPort });
|
|
73488
|
+
return await startServer({ signal, port: selectedPort }, deps);
|
|
73082
73489
|
} catch (error51) {
|
|
73083
73490
|
if (!isPortStartFailure(error51, selectedPort)) {
|
|
73084
73491
|
throw error51;
|
|
73085
73492
|
}
|
|
73086
|
-
const { port: retryPort } = await getAvailableServerPort(selectedPort + 1, "127.0.0.1");
|
|
73493
|
+
const { port: retryPort } = await deps.getAvailableServerPort(selectedPort + 1, "127.0.0.1");
|
|
73087
73494
|
console.log(import_picocolors10.default.dim("Retrying server start on port"), import_picocolors10.default.cyan(retryPort.toString()));
|
|
73088
|
-
return await startServer({ signal, port: retryPort });
|
|
73495
|
+
return await startServer({ signal, port: retryPort }, deps);
|
|
73089
73496
|
}
|
|
73090
73497
|
}
|
|
73498
|
+
async function createServerConnection(options) {
|
|
73499
|
+
return await createServerConnectionWithDeps(options, defaultDeps2);
|
|
73500
|
+
}
|
|
73091
73501
|
|
|
73092
73502
|
// src/cli/run/session-resolver.ts
|
|
73093
73503
|
init_shared();
|
|
@@ -73338,13 +73748,13 @@ var import_picocolors14 = __toESM(require_picocolors(), 1);
|
|
|
73338
73748
|
init_shared();
|
|
73339
73749
|
var import_picocolors13 = __toESM(require_picocolors(), 1);
|
|
73340
73750
|
// src/features/boulder-state/constants.ts
|
|
73341
|
-
var BOULDER_DIR = ".
|
|
73751
|
+
var BOULDER_DIR = ".omo";
|
|
73342
73752
|
var BOULDER_FILE = "boulder.json";
|
|
73343
73753
|
var BOULDER_STATE_PATH = `${BOULDER_DIR}/${BOULDER_FILE}`;
|
|
73344
73754
|
var NOTEPAD_DIR = "notepads";
|
|
73345
73755
|
var NOTEPAD_BASE_PATH = `${BOULDER_DIR}/${NOTEPAD_DIR}`;
|
|
73346
73756
|
// src/features/boulder-state/storage.ts
|
|
73347
|
-
import { existsSync as
|
|
73757
|
+
import { existsSync as existsSync22, readFileSync as readFileSync14, writeFileSync as writeFileSync5, mkdirSync as mkdirSync7, readdirSync as readdirSync3 } from "fs";
|
|
73348
73758
|
import { basename as basename5, dirname as dirname10, isAbsolute as isAbsolute3, join as join20, relative as relative2, resolve as resolve5 } from "path";
|
|
73349
73759
|
var RESERVED_KEYS = new Set(["__proto__", "prototype", "constructor"]);
|
|
73350
73760
|
function parseIsoToMs(value) {
|
|
@@ -73424,11 +73834,11 @@ function resolveBoulderPlanPath(directory, state) {
|
|
|
73424
73834
|
}
|
|
73425
73835
|
const absoluteWorktreePath = resolveTrackedPath(directory, worktreePath);
|
|
73426
73836
|
const worktreePlanPath = resolve5(absoluteWorktreePath, relativePlanPath);
|
|
73427
|
-
return
|
|
73837
|
+
return existsSync22(worktreePlanPath) ? worktreePlanPath : absolutePlanPath;
|
|
73428
73838
|
}
|
|
73429
73839
|
function readBoulderState(directory) {
|
|
73430
73840
|
const filePath = getBoulderFilePath(directory);
|
|
73431
|
-
if (!
|
|
73841
|
+
if (!existsSync22(filePath)) {
|
|
73432
73842
|
return null;
|
|
73433
73843
|
}
|
|
73434
73844
|
try {
|
|
@@ -73471,7 +73881,7 @@ var CHECKED_CHECKBOX_PATTERN = /^(\s*)[-*]\s*\[[xX]\]\s*(.+)$/;
|
|
|
73471
73881
|
var TODO_TASK_PATTERN = /^\d+\.\s+/;
|
|
73472
73882
|
var FINAL_WAVE_TASK_PATTERN = /^F\d+\.\s+/i;
|
|
73473
73883
|
function getPlanProgress(planPath) {
|
|
73474
|
-
if (!
|
|
73884
|
+
if (!existsSync22(planPath)) {
|
|
73475
73885
|
return { total: 0, completed: 0, isComplete: false };
|
|
73476
73886
|
}
|
|
73477
73887
|
try {
|
|
@@ -73550,7 +73960,7 @@ function resolveBoulderPlanPathForWork(directory, work) {
|
|
|
73550
73960
|
return resolveBoulderPlanPath(directory, work);
|
|
73551
73961
|
}
|
|
73552
73962
|
// src/features/boulder-state/top-level-task.ts
|
|
73553
|
-
import { existsSync as
|
|
73963
|
+
import { existsSync as existsSync23, readFileSync as readFileSync15 } from "fs";
|
|
73554
73964
|
var TODO_HEADING_PATTERN2 = /^##\s+TODOs\b/i;
|
|
73555
73965
|
var FINAL_VERIFICATION_HEADING_PATTERN2 = /^##\s+Final Verification Wave\b/i;
|
|
73556
73966
|
var SECOND_LEVEL_HEADING_PATTERN2 = /^##\s+/;
|
|
@@ -73573,7 +73983,7 @@ function buildTaskRef(section, taskLabel) {
|
|
|
73573
73983
|
};
|
|
73574
73984
|
}
|
|
73575
73985
|
function readCurrentTopLevelTask(planPath) {
|
|
73576
|
-
if (!
|
|
73986
|
+
if (!existsSync23(planPath)) {
|
|
73577
73987
|
return null;
|
|
73578
73988
|
}
|
|
73579
73989
|
try {
|
|
@@ -73615,16 +74025,16 @@ function getSessionAgent(sessionID) {
|
|
|
73615
74025
|
return sessionAgentMap.get(sessionID);
|
|
73616
74026
|
}
|
|
73617
74027
|
// src/features/run-continuation-state/constants.ts
|
|
73618
|
-
var CONTINUATION_MARKER_DIR = ".
|
|
74028
|
+
var CONTINUATION_MARKER_DIR = ".omo/run-continuation";
|
|
73619
74029
|
// src/features/run-continuation-state/storage.ts
|
|
73620
|
-
import { existsSync as
|
|
74030
|
+
import { existsSync as existsSync24, mkdirSync as mkdirSync8, readFileSync as readFileSync16, rmSync as rmSync2, writeFileSync as writeFileSync6 } from "fs";
|
|
73621
74031
|
import { join as join21 } from "path";
|
|
73622
74032
|
function getMarkerPath(directory, sessionID) {
|
|
73623
74033
|
return join21(directory, CONTINUATION_MARKER_DIR, `${sessionID}.json`);
|
|
73624
74034
|
}
|
|
73625
74035
|
function readContinuationMarker(directory, sessionID) {
|
|
73626
74036
|
const markerPath = getMarkerPath(directory, sessionID);
|
|
73627
|
-
if (!
|
|
74037
|
+
if (!existsSync24(markerPath))
|
|
73628
74038
|
return null;
|
|
73629
74039
|
try {
|
|
73630
74040
|
const raw = readFileSync16(markerPath, "utf-8");
|
|
@@ -73770,11 +74180,11 @@ init_agent_display_names();
|
|
|
73770
74180
|
|
|
73771
74181
|
// src/hooks/ralph-loop/storage.ts
|
|
73772
74182
|
init_frontmatter();
|
|
73773
|
-
import { existsSync as
|
|
74183
|
+
import { existsSync as existsSync25, readFileSync as readFileSync18, writeFileSync as writeFileSync7, unlinkSync as unlinkSync4, mkdirSync as mkdirSync9 } from "fs";
|
|
73774
74184
|
import { dirname as dirname11, join as join23 } from "path";
|
|
73775
74185
|
|
|
73776
74186
|
// src/hooks/ralph-loop/constants.ts
|
|
73777
|
-
var DEFAULT_STATE_FILE = ".
|
|
74187
|
+
var DEFAULT_STATE_FILE = ".omo/ralph-loop.local.md";
|
|
73778
74188
|
var DEFAULT_MAX_ITERATIONS = 100;
|
|
73779
74189
|
var DEFAULT_COMPLETION_PROMISE = "DONE";
|
|
73780
74190
|
|
|
@@ -73784,7 +74194,7 @@ function getStateFilePath(directory, customPath) {
|
|
|
73784
74194
|
}
|
|
73785
74195
|
function readState(directory, customPath) {
|
|
73786
74196
|
const filePath = getStateFilePath(directory, customPath);
|
|
73787
|
-
if (!
|
|
74197
|
+
if (!existsSync25(filePath)) {
|
|
73788
74198
|
return null;
|
|
73789
74199
|
}
|
|
73790
74200
|
try {
|
|
@@ -73989,6 +74399,13 @@ var ERROR_GRACE_CYCLES = 3;
|
|
|
73989
74399
|
var MIN_STABILIZATION_MS = 1000;
|
|
73990
74400
|
var DEFAULT_EVENT_WATCHDOG_MS = 30000;
|
|
73991
74401
|
var DEFAULT_SECONDARY_MEANINGFUL_WORK_TIMEOUT_MS = 60000;
|
|
74402
|
+
function isIncompleteTodo(value) {
|
|
74403
|
+
if (!isRecord(value)) {
|
|
74404
|
+
return true;
|
|
74405
|
+
}
|
|
74406
|
+
const status = value.status;
|
|
74407
|
+
return status !== "completed" && status !== "cancelled";
|
|
74408
|
+
}
|
|
73992
74409
|
async function pollForCompletion(ctx, eventState, abortController, options = {}) {
|
|
73993
74410
|
const pollIntervalMs = options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;
|
|
73994
74411
|
const requiredConsecutive = options.requiredConsecutive ?? DEFAULT_REQUIRED_CONSECUTIVE;
|
|
@@ -74068,7 +74485,7 @@ Session ended with error: ${eventState.lastError}`));
|
|
|
74068
74485
|
});
|
|
74069
74486
|
const todos = normalizeSDKResponse(todosRes, []);
|
|
74070
74487
|
const hasActiveChildren = Array.isArray(children) && children.length > 0;
|
|
74071
|
-
const hasActiveTodos = Array.isArray(todos) && todos.some(
|
|
74488
|
+
const hasActiveTodos = Array.isArray(todos) && todos.some(isIncompleteTodo);
|
|
74072
74489
|
const hasActiveWork = hasActiveChildren || hasActiveTodos;
|
|
74073
74490
|
if (hasActiveWork) {
|
|
74074
74491
|
eventState.hasReceivedMeaningfulWork = true;
|
|
@@ -79328,7 +79745,7 @@ init_data_path();
|
|
|
79328
79745
|
init_logger();
|
|
79329
79746
|
init_plugin_identity();
|
|
79330
79747
|
init_write_file_atomically();
|
|
79331
|
-
import { existsSync as
|
|
79748
|
+
import { existsSync as existsSync26, mkdirSync as mkdirSync10, readFileSync as readFileSync19 } from "fs";
|
|
79332
79749
|
import { join as join24 } from "path";
|
|
79333
79750
|
var POSTHOG_ACTIVITY_STATE_FILE = "posthog-activity.json";
|
|
79334
79751
|
function getPostHogActivityStateFilePath() {
|
|
@@ -79342,7 +79759,7 @@ function isPostHogActivityState(value) {
|
|
|
79342
79759
|
}
|
|
79343
79760
|
function readPostHogActivityState() {
|
|
79344
79761
|
const stateFilePath = getPostHogActivityStateFilePath();
|
|
79345
|
-
if (!
|
|
79762
|
+
if (!existsSync26(stateFilePath)) {
|
|
79346
79763
|
return {};
|
|
79347
79764
|
}
|
|
79348
79765
|
try {
|
|
@@ -79508,6 +79925,7 @@ function createCliPostHog() {
|
|
|
79508
79925
|
}
|
|
79509
79926
|
|
|
79510
79927
|
// src/cli/run/runner.ts
|
|
79928
|
+
init_prompt_async_gate();
|
|
79511
79929
|
var EVENT_PROCESSOR_SHUTDOWN_TIMEOUT_MS = 2000;
|
|
79512
79930
|
async function waitForEventProcessorShutdown(eventProcessor, timeoutMs = EVENT_PROCESSOR_SHUTDOWN_TIMEOUT_MS) {
|
|
79513
79931
|
const completed = await Promise.race([
|
|
@@ -79576,18 +79994,31 @@ Interrupted. Shutting down...`));
|
|
|
79576
79994
|
const eventState = createEventState();
|
|
79577
79995
|
eventState.agentColorsByName = await loadAgentProfileColors(client3);
|
|
79578
79996
|
const eventProcessor = processEvents(ctx, events.stream, eventState).catch(() => {});
|
|
79579
|
-
await
|
|
79580
|
-
|
|
79581
|
-
|
|
79582
|
-
|
|
79583
|
-
|
|
79584
|
-
|
|
79585
|
-
|
|
79997
|
+
const promptResult = await dispatchInternalPrompt({
|
|
79998
|
+
mode: "async",
|
|
79999
|
+
client: client3,
|
|
80000
|
+
sessionID,
|
|
80001
|
+
source: "cli-run",
|
|
80002
|
+
settleMs: 0,
|
|
80003
|
+
input: {
|
|
80004
|
+
path: { id: sessionID },
|
|
80005
|
+
body: {
|
|
80006
|
+
agent: resolvedAgent,
|
|
80007
|
+
...resolvedModel ? { model: resolvedModel } : {},
|
|
80008
|
+
tools: {
|
|
80009
|
+
question: false
|
|
80010
|
+
},
|
|
80011
|
+
parts: [{ type: "text", text: message }]
|
|
79586
80012
|
},
|
|
79587
|
-
|
|
79588
|
-
}
|
|
79589
|
-
query: { directory }
|
|
80013
|
+
query: { directory }
|
|
80014
|
+
}
|
|
79590
80015
|
});
|
|
80016
|
+
if (promptResult.status === "failed") {
|
|
80017
|
+
throw promptResult.error;
|
|
80018
|
+
}
|
|
80019
|
+
if (promptResult.status !== "dispatched") {
|
|
80020
|
+
throw new Error(`Session ${sessionID} is not idle; promptAsync skipped by gate: ${promptResult.status}`);
|
|
80021
|
+
}
|
|
79591
80022
|
const exitCode = await pollForCompletion(ctx, eventState, abortController);
|
|
79592
80023
|
abortController.abort();
|
|
79593
80024
|
await waitForEventProcessorShutdown(eventProcessor);
|
|
@@ -79786,10 +80217,10 @@ async function getLocalVersion(options = {}) {
|
|
|
79786
80217
|
}
|
|
79787
80218
|
}
|
|
79788
80219
|
// src/cli/doctor/checks/system.ts
|
|
79789
|
-
import { existsSync as
|
|
80220
|
+
import { existsSync as existsSync37, readFileSync as readFileSync29 } from "fs";
|
|
79790
80221
|
|
|
79791
80222
|
// src/cli/doctor/checks/system-binary.ts
|
|
79792
|
-
import { existsSync as
|
|
80223
|
+
import { existsSync as existsSync34 } from "fs";
|
|
79793
80224
|
import { homedir as homedir8 } from "os";
|
|
79794
80225
|
import { join as join31 } from "path";
|
|
79795
80226
|
|
|
@@ -79861,7 +80292,7 @@ function buildVersionCommand(binaryPath, platform) {
|
|
|
79861
80292
|
}
|
|
79862
80293
|
return [binaryPath, "--version"];
|
|
79863
80294
|
}
|
|
79864
|
-
function findDesktopBinary(platform = process.platform, checkExists =
|
|
80295
|
+
function findDesktopBinary(platform = process.platform, checkExists = existsSync34) {
|
|
79865
80296
|
for (const desktopPath of getDesktopAppPaths(platform)) {
|
|
79866
80297
|
if (checkExists(desktopPath)) {
|
|
79867
80298
|
return { binary: "opencode", path: desktopPath };
|
|
@@ -79907,12 +80338,12 @@ function compareVersions3(current, minimum) {
|
|
|
79907
80338
|
|
|
79908
80339
|
// src/cli/doctor/checks/system-plugin.ts
|
|
79909
80340
|
init_shared();
|
|
79910
|
-
import { existsSync as
|
|
80341
|
+
import { existsSync as existsSync35, readFileSync as readFileSync27 } from "fs";
|
|
79911
80342
|
function detectConfigPath() {
|
|
79912
80343
|
const paths = getOpenCodeConfigPaths({ binary: "opencode", version: null });
|
|
79913
|
-
if (
|
|
80344
|
+
if (existsSync35(paths.configJsonc))
|
|
79914
80345
|
return paths.configJsonc;
|
|
79915
|
-
if (
|
|
80346
|
+
if (existsSync35(paths.configJson))
|
|
79916
80347
|
return paths.configJson;
|
|
79917
80348
|
return null;
|
|
79918
80349
|
}
|
|
@@ -79996,7 +80427,7 @@ function getPluginInfo() {
|
|
|
79996
80427
|
init_file_utils();
|
|
79997
80428
|
init_checker();
|
|
79998
80429
|
init_auto_update_checker();
|
|
79999
|
-
import { existsSync as
|
|
80430
|
+
import { existsSync as existsSync36, readFileSync as readFileSync28 } from "fs";
|
|
80000
80431
|
import { homedir as homedir9 } from "os";
|
|
80001
80432
|
import { join as join32 } from "path";
|
|
80002
80433
|
init_shared();
|
|
@@ -80013,17 +80444,17 @@ function resolveOpenCodeCacheDir() {
|
|
|
80013
80444
|
return join32(xdgCacheHome, "opencode");
|
|
80014
80445
|
const fromShared = getOpenCodeCacheDir();
|
|
80015
80446
|
const platformDefault = join32(getPlatformDefaultCacheDir(), "opencode");
|
|
80016
|
-
if (
|
|
80447
|
+
if (existsSync36(fromShared) || !existsSync36(platformDefault))
|
|
80017
80448
|
return fromShared;
|
|
80018
80449
|
return platformDefault;
|
|
80019
80450
|
}
|
|
80020
80451
|
function resolveExistingDir(dirPath) {
|
|
80021
|
-
if (!
|
|
80452
|
+
if (!existsSync36(dirPath))
|
|
80022
80453
|
return dirPath;
|
|
80023
80454
|
return resolveSymlink(dirPath);
|
|
80024
80455
|
}
|
|
80025
80456
|
function readPackageJson(filePath) {
|
|
80026
|
-
if (!
|
|
80457
|
+
if (!existsSync36(filePath))
|
|
80027
80458
|
return null;
|
|
80028
80459
|
try {
|
|
80029
80460
|
const content = readFileSync28(filePath, "utf-8");
|
|
@@ -80045,7 +80476,7 @@ function createPackageCandidates(rootDir) {
|
|
|
80045
80476
|
}));
|
|
80046
80477
|
}
|
|
80047
80478
|
function selectInstalledPackage(candidate) {
|
|
80048
|
-
return candidate.packageCandidates.find((packageCandidate) =>
|
|
80479
|
+
return candidate.packageCandidates.find((packageCandidate) => existsSync36(packageCandidate.installedPackagePath)) ?? candidate.packageCandidates[0];
|
|
80049
80480
|
}
|
|
80050
80481
|
function getExpectedVersion(cachePackage, packageName) {
|
|
80051
80482
|
return normalizeVersion(cachePackage?.dependencies?.[packageName]) ?? normalizeVersion(cachePackage?.dependencies?.[PACKAGE_NAME]);
|
|
@@ -80066,7 +80497,7 @@ function getLoadedPluginVersion() {
|
|
|
80066
80497
|
packageCandidates: createPackageCandidates(cacheDir)
|
|
80067
80498
|
}
|
|
80068
80499
|
];
|
|
80069
|
-
const selectedCandidate = candidates.find((candidate) => candidate.packageCandidates.some((packageCandidate) =>
|
|
80500
|
+
const selectedCandidate = candidates.find((candidate) => candidate.packageCandidates.some((packageCandidate) => existsSync36(packageCandidate.installedPackagePath))) ?? candidates[0];
|
|
80070
80501
|
const { cacheDir: selectedDir, cachePackagePath } = selectedCandidate;
|
|
80071
80502
|
const selectedPackage = selectInstalledPackage(selectedCandidate);
|
|
80072
80503
|
const installedPackagePath = selectedPackage.installedPackagePath;
|
|
@@ -80093,7 +80524,7 @@ function getSuggestedInstallTag(currentVersion) {
|
|
|
80093
80524
|
// src/cli/doctor/checks/system.ts
|
|
80094
80525
|
init_shared();
|
|
80095
80526
|
init_plugin_identity();
|
|
80096
|
-
var
|
|
80527
|
+
var defaultDeps5 = {
|
|
80097
80528
|
findOpenCodeBinary,
|
|
80098
80529
|
getOpenCodeVersion: getOpenCodeVersion3,
|
|
80099
80530
|
compareVersions: compareVersions3,
|
|
@@ -80105,7 +80536,7 @@ var defaultDeps4 = {
|
|
|
80105
80536
|
function isConfigValid(configPath) {
|
|
80106
80537
|
if (!configPath)
|
|
80107
80538
|
return true;
|
|
80108
|
-
if (!
|
|
80539
|
+
if (!existsSync37(configPath))
|
|
80109
80540
|
return false;
|
|
80110
80541
|
try {
|
|
80111
80542
|
parseJsonc(readFileSync29(configPath, "utf-8"));
|
|
@@ -80128,7 +80559,7 @@ function buildMessage(status, issues) {
|
|
|
80128
80559
|
return `${issues.length} system issue(s) detected`;
|
|
80129
80560
|
return `${issues.length} system warning(s) detected`;
|
|
80130
80561
|
}
|
|
80131
|
-
async function gatherSystemInfo(deps =
|
|
80562
|
+
async function gatherSystemInfo(deps = defaultDeps5) {
|
|
80132
80563
|
const [binaryInfo, pluginInfo] = await Promise.all([
|
|
80133
80564
|
deps.findOpenCodeBinary(),
|
|
80134
80565
|
Promise.resolve(deps.getPluginInfo())
|
|
@@ -80147,7 +80578,7 @@ async function gatherSystemInfo(deps = defaultDeps4) {
|
|
|
80147
80578
|
isLocalDev: pluginInfo.isLocalDev
|
|
80148
80579
|
};
|
|
80149
80580
|
}
|
|
80150
|
-
async function checkSystem(deps =
|
|
80581
|
+
async function checkSystem(deps = defaultDeps5) {
|
|
80151
80582
|
const [systemInfo, pluginInfo] = await Promise.all([
|
|
80152
80583
|
gatherSystemInfo(deps),
|
|
80153
80584
|
Promise.resolve(deps.getPluginInfo())
|
|
@@ -80236,7 +80667,7 @@ init_shared();
|
|
|
80236
80667
|
|
|
80237
80668
|
// src/cli/doctor/checks/model-resolution-cache.ts
|
|
80238
80669
|
init_shared();
|
|
80239
|
-
import { existsSync as
|
|
80670
|
+
import { existsSync as existsSync38, readFileSync as readFileSync30 } from "fs";
|
|
80240
80671
|
import { homedir as homedir10 } from "os";
|
|
80241
80672
|
import { join as join33 } from "path";
|
|
80242
80673
|
function getUserConfigDir2() {
|
|
@@ -80252,7 +80683,7 @@ function loadCustomProviderNames() {
|
|
|
80252
80683
|
join33(configDir, "opencode.jsonc")
|
|
80253
80684
|
];
|
|
80254
80685
|
for (const configPath of candidatePaths) {
|
|
80255
|
-
if (!
|
|
80686
|
+
if (!existsSync38(configPath))
|
|
80256
80687
|
continue;
|
|
80257
80688
|
try {
|
|
80258
80689
|
const content = readFileSync30(configPath, "utf-8");
|
|
@@ -80267,7 +80698,7 @@ function loadCustomProviderNames() {
|
|
|
80267
80698
|
function loadAvailableModelsFromCache() {
|
|
80268
80699
|
const cacheFile = join33(getOpenCodeCacheDir(), "models.json");
|
|
80269
80700
|
const customProviders = loadCustomProviderNames();
|
|
80270
|
-
if (!
|
|
80701
|
+
if (!existsSync38(cacheFile)) {
|
|
80271
80702
|
if (customProviders.length > 0) {
|
|
80272
80703
|
return { providers: customProviders, modelCount: 0, cacheExists: true };
|
|
80273
80704
|
}
|
|
@@ -80642,7 +81073,7 @@ async function checkConfig() {
|
|
|
80642
81073
|
}
|
|
80643
81074
|
|
|
80644
81075
|
// src/cli/doctor/checks/dependencies.ts
|
|
80645
|
-
import { existsSync as
|
|
81076
|
+
import { existsSync as existsSync39 } from "fs";
|
|
80646
81077
|
import { createRequire } from "module";
|
|
80647
81078
|
import { dirname as dirname16, join as join38 } from "path";
|
|
80648
81079
|
|
|
@@ -80726,7 +81157,7 @@ async function checkAstGrepNapi() {
|
|
|
80726
81157
|
path: null
|
|
80727
81158
|
};
|
|
80728
81159
|
} catch {
|
|
80729
|
-
const { existsSync:
|
|
81160
|
+
const { existsSync: existsSync40 } = await import("fs");
|
|
80730
81161
|
const { join: join39 } = await import("path");
|
|
80731
81162
|
const { homedir: homedir12 } = await import("os");
|
|
80732
81163
|
const pathsToCheck = [
|
|
@@ -80734,7 +81165,7 @@ async function checkAstGrepNapi() {
|
|
|
80734
81165
|
join39(process.cwd(), "node_modules", "@ast-grep", "napi")
|
|
80735
81166
|
];
|
|
80736
81167
|
for (const napiPath of pathsToCheck) {
|
|
80737
|
-
if (
|
|
81168
|
+
if (existsSync40(napiPath)) {
|
|
80738
81169
|
return {
|
|
80739
81170
|
name: "AST-Grep NAPI",
|
|
80740
81171
|
required: false,
|
|
@@ -80760,7 +81191,7 @@ function findCommentCheckerPackageBinary() {
|
|
|
80760
81191
|
const require2 = createRequire(import.meta.url);
|
|
80761
81192
|
const pkgPath = require2.resolve("@code-yeongyu/comment-checker/package.json");
|
|
80762
81193
|
const binaryPath = join38(dirname16(pkgPath), "bin", binaryName);
|
|
80763
|
-
if (
|
|
81194
|
+
if (existsSync39(binaryPath))
|
|
80764
81195
|
return binaryPath;
|
|
80765
81196
|
} catch {}
|
|
80766
81197
|
return null;
|
|
@@ -80890,261 +81321,120 @@ async function getGhCliInfo() {
|
|
|
80890
81321
|
error: authStatus.error
|
|
80891
81322
|
};
|
|
80892
81323
|
}
|
|
80893
|
-
|
|
80894
|
-
|
|
80895
|
-
|
|
80896
|
-
deno: { command: ["deno", "lsp"], extensions: [".ts", ".tsx", ".js", ".jsx", ".mjs"] },
|
|
80897
|
-
vue: { command: ["vue-language-server", "--stdio"], extensions: [".vue"] },
|
|
80898
|
-
eslint: { command: ["vscode-eslint-language-server", "--stdio"], extensions: [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".mts", ".cts", ".vue"] },
|
|
80899
|
-
oxlint: { command: ["oxlint", "--lsp"], extensions: [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".mts", ".cts", ".vue", ".astro", ".svelte"] },
|
|
80900
|
-
biome: { command: ["biome", "lsp-proxy", "--stdio"], extensions: [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".mts", ".cts", ".json", ".jsonc", ".vue", ".astro", ".svelte", ".css", ".graphql", ".gql", ".html"] },
|
|
80901
|
-
gopls: { command: ["gopls"], extensions: [".go"] },
|
|
80902
|
-
"ruby-lsp": { command: ["rubocop", "--lsp"], extensions: [".rb", ".rake", ".gemspec", ".ru"] },
|
|
80903
|
-
basedpyright: { command: ["basedpyright-langserver", "--stdio"], extensions: [".py", ".pyi"] },
|
|
80904
|
-
pyright: { command: ["pyright-langserver", "--stdio"], extensions: [".py", ".pyi"] },
|
|
80905
|
-
ty: { command: ["ty", "server"], extensions: [".py", ".pyi"] },
|
|
80906
|
-
ruff: { command: ["ruff", "server"], extensions: [".py", ".pyi"] },
|
|
80907
|
-
"elixir-ls": { command: ["elixir-ls"], extensions: [".ex", ".exs"] },
|
|
80908
|
-
zls: { command: ["zls"], extensions: [".zig", ".zon"] },
|
|
80909
|
-
csharp: { command: ["csharp-ls"], extensions: [".cs"] },
|
|
80910
|
-
fsharp: { command: ["fsautocomplete"], extensions: [".fs", ".fsi", ".fsx", ".fsscript"] },
|
|
80911
|
-
"sourcekit-lsp": { command: ["sourcekit-lsp"], extensions: [".swift", ".objc", ".objcpp"] },
|
|
80912
|
-
rust: { command: ["rust-analyzer"], extensions: [".rs"] },
|
|
80913
|
-
clangd: { command: ["clangd", "--background-index", "--clang-tidy"], extensions: [".c", ".cpp", ".cc", ".cxx", ".c++", ".h", ".hpp", ".hh", ".hxx", ".h++"] },
|
|
80914
|
-
svelte: { command: ["svelteserver", "--stdio"], extensions: [".svelte"] },
|
|
80915
|
-
astro: { command: ["astro-ls", "--stdio"], extensions: [".astro"] },
|
|
80916
|
-
bash: { command: ["bash-language-server", "start"], extensions: [".sh", ".bash", ".zsh", ".ksh"] },
|
|
80917
|
-
"bash-ls": { command: ["bash-language-server", "start"], extensions: [".sh", ".bash", ".zsh", ".ksh"] },
|
|
80918
|
-
jdtls: { command: ["jdtls"], extensions: [".java"] },
|
|
80919
|
-
"yaml-ls": { command: ["yaml-language-server", "--stdio"], extensions: [".yaml", ".yml"] },
|
|
80920
|
-
"lua-ls": { command: ["lua-language-server"], extensions: [".lua"] },
|
|
80921
|
-
php: { command: ["intelephense", "--stdio"], extensions: [".php"] },
|
|
80922
|
-
dart: { command: ["dart", "language-server", "--lsp"], extensions: [".dart"] },
|
|
80923
|
-
terraform: { command: ["terraform-ls", "serve"], extensions: [".tf", ".tfvars"] },
|
|
80924
|
-
"terraform-ls": { command: ["terraform-ls", "serve"], extensions: [".tf", ".tfvars"] },
|
|
80925
|
-
prisma: { command: ["prisma", "language-server"], extensions: [".prisma"] },
|
|
80926
|
-
"ocaml-lsp": { command: ["ocamllsp"], extensions: [".ml", ".mli"] },
|
|
80927
|
-
texlab: { command: ["texlab"], extensions: [".tex", ".bib"] },
|
|
80928
|
-
dockerfile: { command: ["docker-langserver", "--stdio"], extensions: [".dockerfile"] },
|
|
80929
|
-
gleam: { command: ["gleam", "lsp"], extensions: [".gleam"] },
|
|
80930
|
-
"clojure-lsp": { command: ["clojure-lsp", "listen"], extensions: [".clj", ".cljs", ".cljc", ".edn"] },
|
|
80931
|
-
nixd: { command: ["nixd"], extensions: [".nix"] },
|
|
80932
|
-
tinymist: { command: ["tinymist"], extensions: [".typ", ".typc"] },
|
|
80933
|
-
"haskell-language-server": { command: ["haskell-language-server-wrapper", "--lsp"], extensions: [".hs", ".lhs"] },
|
|
80934
|
-
"kotlin-ls": { command: ["kotlin-lsp"], extensions: [".kt", ".kts"] }
|
|
80935
|
-
};
|
|
80936
|
-
// src/tools/lsp/server-config-loader.ts
|
|
80937
|
-
import { existsSync as existsSync39, readFileSync as readFileSync33 } from "fs";
|
|
81324
|
+
|
|
81325
|
+
// src/cli/doctor/checks/tools-lsp.ts
|
|
81326
|
+
import { readFileSync as readFileSync33 } from "fs";
|
|
80938
81327
|
import { join as join39 } from "path";
|
|
80939
|
-
|
|
80940
|
-
|
|
80941
|
-
|
|
80942
|
-
|
|
80943
|
-
|
|
81328
|
+
|
|
81329
|
+
// src/mcp/lsp.ts
|
|
81330
|
+
import { existsSync as existsSync40 } from "fs";
|
|
81331
|
+
import { dirname as dirname17, resolve as resolve6 } from "path";
|
|
81332
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
81333
|
+
var SUBMODULE_REL = "packages/lsp-tools-mcp";
|
|
81334
|
+
var DIST_CLI_REL = "dist/cli.js";
|
|
81335
|
+
var SOURCE_CLI_REL = "src/cli.ts";
|
|
81336
|
+
var PROJECT_LSP_CONFIG = ".opencode/lsp.json";
|
|
81337
|
+
function addAncestorCommandCandidates(startDirectory, target, seenPaths, pathExists) {
|
|
81338
|
+
let currentDirectory = resolve6(startDirectory);
|
|
81339
|
+
while (true) {
|
|
81340
|
+
const distCliPath = resolve6(currentDirectory, SUBMODULE_REL, DIST_CLI_REL);
|
|
81341
|
+
if (!seenPaths.has(distCliPath)) {
|
|
81342
|
+
seenPaths.add(distCliPath);
|
|
81343
|
+
target.push({ command: ["node", distCliPath, "mcp"], path: distCliPath, exists: pathExists(distCliPath) });
|
|
81344
|
+
}
|
|
81345
|
+
const sourceCliPath = resolve6(currentDirectory, SUBMODULE_REL, SOURCE_CLI_REL);
|
|
81346
|
+
if (!seenPaths.has(sourceCliPath)) {
|
|
81347
|
+
seenPaths.add(sourceCliPath);
|
|
81348
|
+
target.push({ command: ["bun", sourceCliPath, "mcp"], path: sourceCliPath, exists: pathExists(sourceCliPath) });
|
|
81349
|
+
}
|
|
81350
|
+
const parentDirectory = resolve6(currentDirectory, "..");
|
|
81351
|
+
if (parentDirectory === currentDirectory) {
|
|
81352
|
+
return;
|
|
81353
|
+
}
|
|
81354
|
+
currentDirectory = parentDirectory;
|
|
81355
|
+
}
|
|
81356
|
+
}
|
|
81357
|
+
function getModuleDirectory(moduleUrl) {
|
|
80944
81358
|
try {
|
|
80945
|
-
return
|
|
81359
|
+
return dirname17(fileURLToPath3(moduleUrl));
|
|
80946
81360
|
} catch {
|
|
80947
81361
|
return null;
|
|
80948
81362
|
}
|
|
80949
81363
|
}
|
|
80950
|
-
function
|
|
80951
|
-
const
|
|
80952
|
-
const
|
|
80953
|
-
|
|
80954
|
-
|
|
80955
|
-
|
|
80956
|
-
|
|
80957
|
-
};
|
|
80958
|
-
}
|
|
80959
|
-
function loadAllConfigs() {
|
|
80960
|
-
const paths = getConfigPaths2();
|
|
80961
|
-
const configs = new Map;
|
|
80962
|
-
const project = loadJsonFile(paths.project);
|
|
80963
|
-
if (project)
|
|
80964
|
-
configs.set("project", project);
|
|
80965
|
-
const user = loadJsonFile(paths.user);
|
|
80966
|
-
if (user)
|
|
80967
|
-
configs.set("user", user);
|
|
80968
|
-
const opencode = loadJsonFile(paths.opencode);
|
|
80969
|
-
if (opencode)
|
|
80970
|
-
configs.set("opencode", opencode);
|
|
80971
|
-
return configs;
|
|
80972
|
-
}
|
|
80973
|
-
function getMergedServers() {
|
|
80974
|
-
const configs = loadAllConfigs();
|
|
80975
|
-
const servers = [];
|
|
80976
|
-
const disabled = new Set;
|
|
80977
|
-
const seen = new Set;
|
|
80978
|
-
const sources = ["project", "user", "opencode"];
|
|
80979
|
-
for (const source of sources) {
|
|
80980
|
-
const config2 = configs.get(source);
|
|
80981
|
-
if (!config2?.lsp)
|
|
80982
|
-
continue;
|
|
80983
|
-
for (const [id, entry] of Object.entries(config2.lsp)) {
|
|
80984
|
-
if (entry.disabled) {
|
|
80985
|
-
disabled.add(id);
|
|
80986
|
-
continue;
|
|
80987
|
-
}
|
|
80988
|
-
if (seen.has(id))
|
|
80989
|
-
continue;
|
|
80990
|
-
if (!entry.command || !entry.extensions)
|
|
80991
|
-
continue;
|
|
80992
|
-
servers.push({
|
|
80993
|
-
id,
|
|
80994
|
-
command: entry.command,
|
|
80995
|
-
extensions: entry.extensions,
|
|
80996
|
-
priority: entry.priority ?? 0,
|
|
80997
|
-
env: entry.env,
|
|
80998
|
-
initialization: entry.initialization,
|
|
80999
|
-
source
|
|
81000
|
-
});
|
|
81001
|
-
seen.add(id);
|
|
81002
|
-
}
|
|
81364
|
+
function resolveLspCommand(options = {}) {
|
|
81365
|
+
const pathExists = options.exists ?? existsSync40;
|
|
81366
|
+
const candidates = [];
|
|
81367
|
+
const seenPaths = new Set;
|
|
81368
|
+
const moduleDirectory = getModuleDirectory(options.moduleUrl ?? import.meta.url);
|
|
81369
|
+
if (moduleDirectory) {
|
|
81370
|
+
addAncestorCommandCandidates(moduleDirectory, candidates, seenPaths, pathExists);
|
|
81003
81371
|
}
|
|
81004
|
-
|
|
81005
|
-
|
|
81006
|
-
|
|
81007
|
-
|
|
81008
|
-
id,
|
|
81009
|
-
command: config2.command,
|
|
81010
|
-
extensions: config2.extensions,
|
|
81011
|
-
priority: -100,
|
|
81012
|
-
source: "opencode"
|
|
81013
|
-
});
|
|
81372
|
+
addAncestorCommandCandidates(options.cwd ?? process.cwd(), candidates, seenPaths, pathExists);
|
|
81373
|
+
const distCandidate = candidates.find((candidate) => candidate.path.endsWith(DIST_CLI_REL) && candidate.exists);
|
|
81374
|
+
if (distCandidate) {
|
|
81375
|
+
return distCandidate.command;
|
|
81014
81376
|
}
|
|
81015
|
-
|
|
81016
|
-
|
|
81017
|
-
|
|
81018
|
-
|
|
81377
|
+
const sourceCandidate = candidates.find((candidate) => candidate.path.endsWith(SOURCE_CLI_REL) && candidate.exists);
|
|
81378
|
+
if (sourceCandidate) {
|
|
81379
|
+
return sourceCandidate.command;
|
|
81380
|
+
}
|
|
81381
|
+
return candidates[0]?.command ?? ["node", resolve6(process.cwd(), SUBMODULE_REL, DIST_CLI_REL), "mcp"];
|
|
81382
|
+
}
|
|
81383
|
+
function createLspMcpConfig(options = {}) {
|
|
81384
|
+
return {
|
|
81385
|
+
type: "local",
|
|
81386
|
+
command: resolveLspCommand(options),
|
|
81387
|
+
enabled: true,
|
|
81388
|
+
environment: {
|
|
81389
|
+
LSP_TOOLS_MCP_PROJECT_CONFIG: PROJECT_LSP_CONFIG
|
|
81019
81390
|
}
|
|
81020
|
-
|
|
81021
|
-
});
|
|
81391
|
+
};
|
|
81022
81392
|
}
|
|
81023
81393
|
|
|
81024
|
-
// src/
|
|
81025
|
-
import { existsSync as existsSync40 } from "fs";
|
|
81026
|
-
import { delimiter as delimiter2, join as join41 } from "path";
|
|
81027
|
-
|
|
81028
|
-
// src/tools/lsp/server-path-bases.ts
|
|
81394
|
+
// src/cli/doctor/checks/tools-lsp.ts
|
|
81029
81395
|
init_shared();
|
|
81030
|
-
|
|
81031
|
-
function
|
|
81032
|
-
const
|
|
81033
|
-
|
|
81034
|
-
|
|
81035
|
-
join40(workingDirectory, "node_modules", ".bin"),
|
|
81036
|
-
join40(configDir, "bin"),
|
|
81037
|
-
join40(configDir, "node_modules", ".bin"),
|
|
81038
|
-
join40(dataDir, "bin"),
|
|
81039
|
-
join40(dataDir, "bin", "node_modules", ".bin")
|
|
81040
|
-
];
|
|
81041
|
-
}
|
|
81042
|
-
|
|
81043
|
-
// src/tools/lsp/server-installation.ts
|
|
81044
|
-
function isServerInstalled(command) {
|
|
81045
|
-
if (command.length === 0)
|
|
81046
|
-
return false;
|
|
81047
|
-
const cmd = command[0];
|
|
81048
|
-
if (cmd.includes("/") || cmd.includes("\\")) {
|
|
81049
|
-
if (existsSync40(cmd))
|
|
81050
|
-
return true;
|
|
81051
|
-
}
|
|
81052
|
-
const isWindows = process.platform === "win32";
|
|
81053
|
-
let exts = [""];
|
|
81054
|
-
if (isWindows) {
|
|
81055
|
-
const pathExt = process.env.PATHEXT || "";
|
|
81056
|
-
if (pathExt) {
|
|
81057
|
-
const systemExts = pathExt.split(";").filter(Boolean);
|
|
81058
|
-
exts = [...new Set([...exts, ...systemExts, ".exe", ".cmd", ".bat", ".ps1"])];
|
|
81059
|
-
} else {
|
|
81060
|
-
exts = ["", ".exe", ".cmd", ".bat", ".ps1"];
|
|
81061
|
-
}
|
|
81062
|
-
}
|
|
81063
|
-
let pathEnv = process.env.PATH || "";
|
|
81064
|
-
if (isWindows && !pathEnv) {
|
|
81065
|
-
pathEnv = process.env.Path || "";
|
|
81066
|
-
}
|
|
81067
|
-
const paths = pathEnv.split(delimiter2);
|
|
81068
|
-
for (const p2 of paths) {
|
|
81069
|
-
for (const suffix of exts) {
|
|
81070
|
-
if (existsSync40(join41(p2, cmd + suffix))) {
|
|
81071
|
-
return true;
|
|
81072
|
-
}
|
|
81073
|
-
}
|
|
81074
|
-
}
|
|
81075
|
-
for (const base of getLspServerAdditionalPathBases(process.cwd())) {
|
|
81076
|
-
for (const suffix of exts) {
|
|
81077
|
-
if (existsSync40(join41(base, cmd + suffix))) {
|
|
81078
|
-
return true;
|
|
81079
|
-
}
|
|
81080
|
-
}
|
|
81396
|
+
var PROJECT_CONFIG_DIR3 = join39(process.cwd(), ".opencode");
|
|
81397
|
+
function readOmoConfig(configDirectory) {
|
|
81398
|
+
const detected = detectPluginConfigFile(configDirectory);
|
|
81399
|
+
if (detected.format === "none") {
|
|
81400
|
+
return null;
|
|
81081
81401
|
}
|
|
81082
|
-
|
|
81083
|
-
|
|
81402
|
+
try {
|
|
81403
|
+
const content = readFileSync33(detected.path, "utf-8");
|
|
81404
|
+
return parseJsonc(content);
|
|
81405
|
+
} catch {
|
|
81406
|
+
return null;
|
|
81084
81407
|
}
|
|
81085
|
-
return false;
|
|
81086
81408
|
}
|
|
81087
|
-
|
|
81088
|
-
|
|
81089
|
-
|
|
81090
|
-
const
|
|
81091
|
-
const
|
|
81092
|
-
|
|
81093
|
-
|
|
81094
|
-
|
|
81095
|
-
|
|
81096
|
-
for (const [id, entry] of Object.entries(config2.lsp)) {
|
|
81097
|
-
if (entry.disabled)
|
|
81098
|
-
disabled.add(id);
|
|
81099
|
-
}
|
|
81100
|
-
}
|
|
81101
|
-
const result = [];
|
|
81102
|
-
const seen = new Set;
|
|
81103
|
-
for (const server2 of servers) {
|
|
81104
|
-
if (seen.has(server2.id))
|
|
81105
|
-
continue;
|
|
81106
|
-
result.push({
|
|
81107
|
-
id: server2.id,
|
|
81108
|
-
installed: isServerInstalled(server2.command),
|
|
81109
|
-
extensions: server2.extensions,
|
|
81110
|
-
disabled: false,
|
|
81111
|
-
source: server2.source,
|
|
81112
|
-
priority: server2.priority
|
|
81113
|
-
});
|
|
81114
|
-
seen.add(server2.id);
|
|
81115
|
-
}
|
|
81116
|
-
for (const id of disabled) {
|
|
81117
|
-
if (seen.has(id))
|
|
81118
|
-
continue;
|
|
81119
|
-
const builtin = BUILTIN_SERVERS[id];
|
|
81120
|
-
result.push({
|
|
81121
|
-
id,
|
|
81122
|
-
installed: builtin ? isServerInstalled(builtin.command) : false,
|
|
81123
|
-
extensions: builtin?.extensions || [],
|
|
81124
|
-
disabled: true,
|
|
81125
|
-
source: "disabled",
|
|
81126
|
-
priority: 0
|
|
81127
|
-
});
|
|
81128
|
-
}
|
|
81129
|
-
return result;
|
|
81409
|
+
function isLspMcpDisabled() {
|
|
81410
|
+
const userConfigDirectory = getOpenCodeConfigDir({ binary: "opencode" });
|
|
81411
|
+
const userConfig = readOmoConfig(userConfigDirectory);
|
|
81412
|
+
const projectConfig = readOmoConfig(PROJECT_CONFIG_DIR3);
|
|
81413
|
+
const disabledMcps = new Set([
|
|
81414
|
+
...userConfig?.disabled_mcps ?? [],
|
|
81415
|
+
...projectConfig?.disabled_mcps ?? []
|
|
81416
|
+
]);
|
|
81417
|
+
return disabledMcps.has("lsp");
|
|
81130
81418
|
}
|
|
81131
|
-
// src/cli/doctor/checks/tools-lsp.ts
|
|
81132
81419
|
function getInstalledLspServers() {
|
|
81133
|
-
|
|
81134
|
-
|
|
81420
|
+
if (isLspMcpDisabled()) {
|
|
81421
|
+
return [];
|
|
81422
|
+
}
|
|
81423
|
+
const lspMcpConfig = createLspMcpConfig();
|
|
81424
|
+
return lspMcpConfig.enabled ? [{ id: "lsp-tools-mcp", extensions: ["*"] }] : [];
|
|
81135
81425
|
}
|
|
81136
81426
|
|
|
81137
81427
|
// src/cli/doctor/checks/tools-mcp.ts
|
|
81138
81428
|
init_shared();
|
|
81139
81429
|
import { existsSync as existsSync41, readFileSync as readFileSync34 } from "fs";
|
|
81140
81430
|
import { homedir as homedir12 } from "os";
|
|
81141
|
-
import { join as
|
|
81431
|
+
import { join as join40 } from "path";
|
|
81142
81432
|
var BUILTIN_MCP_SERVERS = ["context7", "grep_app"];
|
|
81143
81433
|
function getMcpConfigPaths() {
|
|
81144
81434
|
return [
|
|
81145
|
-
|
|
81146
|
-
|
|
81147
|
-
|
|
81435
|
+
join40(homedir12(), ".claude", ".mcp.json"),
|
|
81436
|
+
join40(process.cwd(), ".mcp.json"),
|
|
81437
|
+
join40(process.cwd(), ".claude", ".mcp.json")
|
|
81148
81438
|
];
|
|
81149
81439
|
}
|
|
81150
81440
|
function loadUserMcpConfig() {
|
|
@@ -81749,11 +82039,11 @@ async function refreshModelCapabilities(options, deps = {}) {
|
|
|
81749
82039
|
|
|
81750
82040
|
// src/features/mcp-oauth/storage.ts
|
|
81751
82041
|
init_shared();
|
|
81752
|
-
import { chmodSync as chmodSync2, existsSync as existsSync42, mkdirSync as mkdirSync12, readFileSync as readFileSync36, renameSync as
|
|
81753
|
-
import { dirname as
|
|
82042
|
+
import { chmodSync as chmodSync2, existsSync as existsSync42, mkdirSync as mkdirSync12, readFileSync as readFileSync36, renameSync as renameSync5, unlinkSync as unlinkSync7, writeFileSync as writeFileSync10 } from "fs";
|
|
82043
|
+
import { dirname as dirname18, join as join41 } from "path";
|
|
81754
82044
|
var STORAGE_FILE_NAME = "mcp-oauth.json";
|
|
81755
82045
|
function getMcpOauthStoragePath() {
|
|
81756
|
-
return
|
|
82046
|
+
return join41(getOpenCodeConfigDir({ binary: "opencode" }), STORAGE_FILE_NAME);
|
|
81757
82047
|
}
|
|
81758
82048
|
function normalizeHost2(serverHost) {
|
|
81759
82049
|
let host = serverHost.trim();
|
|
@@ -81803,14 +82093,14 @@ function readStore() {
|
|
|
81803
82093
|
function writeStore(store2) {
|
|
81804
82094
|
const filePath = getMcpOauthStoragePath();
|
|
81805
82095
|
try {
|
|
81806
|
-
const dir =
|
|
82096
|
+
const dir = dirname18(filePath);
|
|
81807
82097
|
if (!existsSync42(dir)) {
|
|
81808
82098
|
mkdirSync12(dir, { recursive: true });
|
|
81809
82099
|
}
|
|
81810
82100
|
const tempPath = `${filePath}.tmp.${Date.now()}`;
|
|
81811
82101
|
writeFileSync10(tempPath, JSON.stringify(store2, null, 2), { encoding: "utf-8", mode: 384 });
|
|
81812
82102
|
chmodSync2(tempPath, 384);
|
|
81813
|
-
|
|
82103
|
+
renameSync5(tempPath, filePath);
|
|
81814
82104
|
return true;
|
|
81815
82105
|
} catch {
|
|
81816
82106
|
return false;
|
|
@@ -81842,7 +82132,7 @@ function deleteToken(serverHost, resource) {
|
|
|
81842
82132
|
try {
|
|
81843
82133
|
const filePath = getMcpOauthStoragePath();
|
|
81844
82134
|
if (existsSync42(filePath)) {
|
|
81845
|
-
|
|
82135
|
+
unlinkSync7(filePath);
|
|
81846
82136
|
}
|
|
81847
82137
|
return true;
|
|
81848
82138
|
} catch {
|
|
@@ -82010,7 +82300,7 @@ async function getOrRegisterClient(options) {
|
|
|
82010
82300
|
}
|
|
82011
82301
|
}
|
|
82012
82302
|
function parseRegistrationResponse(data) {
|
|
82013
|
-
if (!
|
|
82303
|
+
if (!isRecord10(data))
|
|
82014
82304
|
return null;
|
|
82015
82305
|
const clientId = data.client_id;
|
|
82016
82306
|
if (typeof clientId !== "string" || clientId.length === 0)
|
|
@@ -82021,7 +82311,7 @@ function parseRegistrationResponse(data) {
|
|
|
82021
82311
|
}
|
|
82022
82312
|
return { clientId };
|
|
82023
82313
|
}
|
|
82024
|
-
function
|
|
82314
|
+
function isRecord10(value) {
|
|
82025
82315
|
return typeof value === "object" && value !== null;
|
|
82026
82316
|
}
|
|
82027
82317
|
|
|
@@ -82061,7 +82351,7 @@ function buildAuthorizationUrl(authorizationEndpoint, options) {
|
|
|
82061
82351
|
}
|
|
82062
82352
|
var CALLBACK_TIMEOUT_MS = 5 * 60 * 1000;
|
|
82063
82353
|
function startCallbackServer(port) {
|
|
82064
|
-
return new Promise((
|
|
82354
|
+
return new Promise((resolve7, reject) => {
|
|
82065
82355
|
let timeoutId;
|
|
82066
82356
|
const server2 = createServer2((request, response) => {
|
|
82067
82357
|
clearTimeout(timeoutId);
|
|
@@ -82087,7 +82377,7 @@ function startCallbackServer(port) {
|
|
|
82087
82377
|
response.writeHead(200, { "content-type": "text/html" });
|
|
82088
82378
|
response.end("<html><body><h1>Authorization successful. You can close this tab.</h1></body></html>");
|
|
82089
82379
|
server2.close();
|
|
82090
|
-
|
|
82380
|
+
resolve7({ code, state: state2 });
|
|
82091
82381
|
});
|
|
82092
82382
|
timeoutId = setTimeout(() => {
|
|
82093
82383
|
server2.close();
|