oh-my-opencode 5.0.0-beta.30 → 5.0.0-beta.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +178 -37
- package/dist/cli-node/index.js +178 -37
- package/dist/config/schema/background-task.d.ts +1 -0
- package/dist/config/schema/oh-my-opencode-config.d.ts +1 -0
- package/dist/features/background-agent/constants.d.ts +0 -7
- package/dist/features/background-agent/manager.d.ts +2 -1
- package/dist/features/background-agent/parent-wake-dispatched-tracker.d.ts +0 -1
- package/dist/features/background-agent/parent-wake-notifier-types.d.ts +1 -1
- package/dist/features/background-agent/parent-wake-prompt-dispatch.d.ts +1 -1
- package/dist/features/background-agent/parent-wake-session-inspector.d.ts +1 -1
- package/dist/features/background-agent/subagent-spawn-limits.d.ts +8 -0
- package/dist/features/monitor/manager-internals.d.ts +1 -1
- package/dist/features/monitor/output-injector-types.d.ts +1 -1
- package/dist/features/task-toast-manager/manager.d.ts +0 -24
- package/dist/features/team-mode/tools/messaging-live-delivery-recipient.d.ts +1 -0
- package/dist/features/team-mode/tools/messaging-runtime.d.ts +1 -0
- package/dist/hooks/anthropic-context-window-limit-recovery/message-storage-directory.d.ts +0 -3
- package/dist/hooks/anthropic-context-window-limit-recovery/state.d.ts +1 -0
- package/dist/hooks/anthropic-context-window-limit-recovery/storage/empty-messages.d.ts +0 -1
- package/dist/hooks/anthropic-context-window-limit-recovery/tool-result-storage.d.ts +11 -0
- package/dist/hooks/claude-code-hooks/session-hook-state.d.ts +1 -0
- package/dist/hooks/claude-code-hooks/stop.d.ts +2 -0
- package/dist/hooks/claude-code-hooks/todo.d.ts +0 -1
- package/dist/hooks/claude-code-hooks/transcript.d.ts +2 -0
- package/dist/hooks/fsync-skip-warning/index.d.ts +4 -0
- package/dist/hooks/hashline-edit-diff-enhancer/hook.d.ts +1 -0
- package/dist/hooks/hashline-edit-diff-enhancer/pending-captures.d.ts +13 -0
- package/dist/hooks/keyword-detector/hook.d.ts +7 -0
- package/dist/hooks/keyword-detector/ultrawork/source-detector.d.ts +0 -1
- package/dist/hooks/model-fallback/hook.d.ts +1 -1
- package/dist/index.js +681 -273
- package/dist/oh-my-opencode.schema.json +5 -0
- package/dist/plugin-dispose.d.ts +3 -0
- package/dist/shared/agent-tool-restrictions.d.ts +0 -1
- package/dist/skills/ultimate-browsing/references/insane-search/README.md +9 -2
- package/dist/tools/delegate-task/sync-session-cleanup.d.ts +3 -0
- package/dist/tools/delegate-task/sync-session-poller.d.ts +1 -0
- package/dist/tools/delegate-task/types.d.ts +1 -0
- package/dist/tools/session-manager/directory-filter.d.ts +2 -0
- package/dist/tui.js +148 -9
- package/package.json +16 -15
- package/packages/git-bash-mcp/dist/cli.js +1 -0
- package/packages/lsp-core/src/lsp/client-diagnostics-freshness.integration.test.ts +47 -19
- package/packages/lsp-core/src/lsp/client-diagnostics-pull-timeout.test.ts +64 -0
- package/packages/lsp-core/src/lsp/client-wrapper.test.ts +97 -0
- package/packages/lsp-core/src/lsp/client-wrapper.ts +21 -6
- package/packages/lsp-core/src/lsp/client.ts +6 -3
- package/packages/lsp-core/src/lsp/constants.ts +5 -0
- package/packages/lsp-core/src/lsp/controlled-clock-test-support.ts +61 -0
- package/packages/lsp-core/src/lsp/errors.ts +15 -0
- package/packages/lsp-core/src/lsp/fixtures/workspace-edit-server.mjs +10 -3
- package/packages/lsp-core/src/lsp/manager-lifecycle.test.ts +262 -0
- package/packages/lsp-core/src/lsp/manager.ts +106 -13
- package/packages/lsp-core/src/lsp/timer-provider.ts +13 -0
- package/packages/lsp-core/src/lsp/transport-request-timeout.test.ts +73 -0
- package/packages/lsp-core/src/lsp/transport.ts +7 -2
- package/packages/lsp-core/src/lsp/workspace-document-state.test.ts +84 -1
- package/packages/lsp-core/src/lsp/workspace-document-state.ts +30 -11
- package/packages/lsp-core/src/lsp/workspace-markers.ts +18 -1
- package/packages/lsp-core/src/mcp.ts +3 -0
- package/packages/lsp-core/src/tools/parameters.test.ts +51 -0
- package/packages/lsp-daemon/dist/cli.js +155 -34
- package/packages/lsp-daemon/dist/client.js +155 -34
- package/packages/lsp-daemon/dist/index.js +155 -34
- package/packages/lsp-daemon/dist/proxy.js +3 -0
- package/packages/lsp-tools-mcp/dist/cli.js +155 -34
- package/packages/lsp-tools-mcp/dist/lsp/manager.js +134 -28
- package/packages/lsp-tools-mcp/dist/mcp.js +155 -34
- package/packages/lsp-tools-mcp/dist/tools.js +154 -34
- package/packages/lsp-tools-mcp/package.json +1 -1
- package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
- package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +17 -2
- package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +17 -2
- package/packages/omo-codex/plugin/components/codegraph/package.json +1 -1
- package/packages/omo-codex/plugin/components/codegraph/src/mcp-unavailable.ts +12 -0
- package/packages/omo-codex/plugin/components/codegraph/test/serve-unavailable-idle.test.ts +47 -0
- package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
- package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
- package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +3 -3
- package/packages/omo-codex/plugin/components/lsp/dist/cli.js +152 -34
- package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
- package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
- package/packages/omo-codex/plugin/components/rules/package.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/AGENTS.md +5 -4
- package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +489 -4
- package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -2
- package/packages/omo-codex/plugin/components/ultrawork/scripts/sync-directive.mjs +30 -14
- package/packages/omo-codex/plugin/components/ultrawork/src/directive-content.ts +4 -0
- package/packages/omo-codex/plugin/components/ultrawork/src/directive.ts +5 -2
- package/packages/omo-codex/plugin/components/ultrawork/test/directive-source.test.ts +14 -8
- package/packages/omo-codex/plugin/components/ultrawork/test/package-smoke.test.ts +12 -1
- package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/ulw-execute-continuation/package.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/AGENTS.md +5 -2
- package/packages/omo-codex/plugin/components/ulw-loop/README.md +1 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-continuation.js +9 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-reconciliation.d.ts +14 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-reconciliation.js +10 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-template.d.ts +8 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-template.js +113 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.js +9 -5
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-commands.js +2 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.d.ts +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.js +1 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-subcommands.js +2 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +856 -347
- package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.d.ts +2 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.js +27 -6
- package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-snapshot.d.ts +13 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-snapshot.js +14 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/domain-types.d.ts +17 -9
- package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.js +17 -2
- package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-missing-recovery.d.ts +13 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-missing-recovery.js +19 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-aggregate.d.ts +2 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-aggregate.js +53 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-artifacts.d.ts +9 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-artifacts.js +85 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-fields.js +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.d.ts +4 -2
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.js +41 -102
- package/packages/omo-codex/plugin/components/ulw-loop/dist/review-blockers.js +4 -2
- package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-guard.js +185 -14
- package/packages/omo-codex/plugin/components/ulw-loop/dist/status-next-actions.d.ts +6 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/status-next-actions.js +33 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/surface.d.ts +18 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/surface.js +65 -0
- package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +4 -4
- package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +17 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-continuation.ts +7 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-reconciliation.ts +25 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-template.ts +127 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint.ts +10 -12
- package/packages/omo-codex/plugin/components/ulw-loop/src/cli-commands.ts +2 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/cli-output.ts +1 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/cli-subcommands.ts +2 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-instruction.ts +34 -5
- package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-snapshot.ts +23 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/domain-types.ts +19 -9
- package/packages/omo-codex/plugin/components/ulw-loop/src/plan-io.ts +18 -3
- package/packages/omo-codex/plugin/components/ulw-loop/src/plan-missing-recovery.ts +27 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-aggregate.ts +57 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-artifacts.ts +103 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-fields.ts +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate.ts +54 -123
- package/packages/omo-codex/plugin/components/ulw-loop/src/review-blockers.ts +4 -2
- package/packages/omo-codex/plugin/components/ulw-loop/src/spawn-guard.ts +187 -12
- package/packages/omo-codex/plugin/components/ulw-loop/src/status-next-actions.ts +36 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/surface.ts +95 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-final.test.ts +107 -1
- package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-template.test.ts +92 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/cli-status-next-actions.test.ts +183 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-instruction.test.ts +35 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/quality-gate-builder.ts +7 -3
- package/packages/omo-codex/plugin/components/ulw-loop/test/guided-recovery.test.ts +105 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-aggregate.test.ts +101 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-roles.test.ts +46 -2
- package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-senpi-surface.test.ts +131 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate.test.ts +5 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/spawn-guard.test.ts +318 -1
- package/packages/omo-codex/plugin/components/ulw-loop/test/surface.test.ts +74 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/ultrawork-directive.test.ts +9 -3
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
- package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +1 -1
- package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
- package/packages/omo-codex/plugin/hooks/subagent-stop-checking-ulw-execute-continuation.json +1 -1
- package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
- package/packages/omo-codex/plugin/package-lock.json +13 -13
- package/packages/omo-codex/plugin/package.json +1 -1
- package/packages/omo-codex/plugin/scripts/sync-skills.mjs +31 -2
- package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/README.md +9 -2
- package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +17 -0
- package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +11 -1
- package/packages/omo-codex/plugin/test/sync-skills.test.mjs +13 -0
- package/packages/omo-codex/plugin/test/ultrawork-skill-pointer.test.mjs +5 -2
- package/packages/omo-codex/scripts/install-dist/install-local.mjs +2 -2
- package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/README.md +9 -2
- package/dist/features/builtin-skills/index.d.ts +0 -1
- package/dist/features/builtin-skills/skill-file-loader.d.ts +0 -1
- package/dist/features/builtin-skills/skills/agent-browser-skill.d.ts +0 -1
- package/dist/features/builtin-skills/skills/agent-browser-template.d.ts +0 -1
- package/dist/features/builtin-skills/skills/debugging.d.ts +0 -1
- package/dist/features/builtin-skills/skills/dev-browser.d.ts +0 -1
- package/dist/features/builtin-skills/skills/frontend.d.ts +0 -1
- package/dist/features/builtin-skills/skills/git-master-sections/commit-atomic-planning.d.ts +0 -1
- package/dist/features/builtin-skills/skills/git-master-sections/commit-context-analysis.d.ts +0 -1
- package/dist/features/builtin-skills/skills/git-master-sections/commit-execution-verification.d.ts +0 -1
- package/dist/features/builtin-skills/skills/git-master-sections/commit-workflow.d.ts +0 -1
- package/dist/features/builtin-skills/skills/git-master-sections/history-search-workflow.d.ts +0 -1
- package/dist/features/builtin-skills/skills/git-master-sections/overview.d.ts +0 -1
- package/dist/features/builtin-skills/skills/git-master-sections/quick-reference.d.ts +0 -1
- package/dist/features/builtin-skills/skills/git-master-sections/rebase-workflow.d.ts +0 -1
- package/dist/features/builtin-skills/skills/git-master-skill-metadata.d.ts +0 -1
- package/dist/features/builtin-skills/skills/git-master.d.ts +0 -1
- package/dist/features/builtin-skills/skills/index.d.ts +0 -1
- package/dist/features/builtin-skills/skills/init-deep.d.ts +0 -1
- package/dist/features/builtin-skills/skills/playwright-cli.d.ts +0 -1
- package/dist/features/builtin-skills/skills/playwright-mcp-skill.d.ts +0 -1
- package/dist/features/builtin-skills/skills/playwright.d.ts +0 -1
- package/dist/features/builtin-skills/skills/remove-ai-slops.d.ts +0 -1
- package/dist/features/builtin-skills/skills/review-work.d.ts +0 -1
- package/dist/features/builtin-skills/skills/security-research.d.ts +0 -1
- package/dist/features/builtin-skills/skills/security-review.d.ts +0 -1
- package/dist/features/builtin-skills/skills/team-mode.d.ts +0 -1
- package/dist/features/builtin-skills/skills/visual-qa.d.ts +0 -1
- package/dist/features/builtin-skills/skills.d.ts +0 -1
- package/dist/features/builtin-skills/types.d.ts +0 -1
- package/dist/features/claude-code-plugin-loader/agent-loader.d.ts +0 -1
- package/dist/features/claude-code-plugin-loader/command-loader.d.ts +0 -1
- package/dist/features/claude-code-plugin-loader/discovery-core.d.ts +0 -1
- package/dist/features/claude-code-plugin-loader/discovery-paths.d.ts +0 -1
- package/dist/features/claude-code-plugin-loader/discovery.d.ts +0 -1
- package/dist/features/claude-code-plugin-loader/hook-loader.d.ts +0 -1
- package/dist/features/claude-code-plugin-loader/index.d.ts +0 -1
- package/dist/features/claude-code-plugin-loader/install-path-resolver.d.ts +0 -1
- package/dist/features/claude-code-plugin-loader/installed-plugin-database.d.ts +0 -1
- package/dist/features/claude-code-plugin-loader/loaded-plugin.d.ts +0 -1
- package/dist/features/claude-code-plugin-loader/loader.d.ts +0 -1
- package/dist/features/claude-code-plugin-loader/mcp-server-loader.d.ts +0 -1
- package/dist/features/claude-code-plugin-loader/plugin-key.d.ts +0 -1
- package/dist/features/claude-code-plugin-loader/plugin-manifest.d.ts +0 -1
- package/dist/features/claude-code-plugin-loader/plugin-path-resolver.d.ts +0 -1
- package/dist/features/claude-code-plugin-loader/plugin-settings.d.ts +0 -1
- package/dist/features/claude-code-plugin-loader/scope-filter.d.ts +0 -1
- package/dist/features/claude-code-plugin-loader/skill-loader.d.ts +0 -1
- package/dist/features/claude-code-plugin-loader/types.d.ts +0 -1
- package/dist/hooks/ralph-loop/completion-promise-detector-test-input.d.ts +0 -11
- package/dist/hooks/ralph-loop/loop-session-recovery.d.ts +0 -7
- package/dist/shared/prompt-async-gate/message-inspection-error.d.ts +0 -1
- package/dist/shared/prompt-async-gate/pending-tool-turn.d.ts +0 -1
- package/dist/shared/prompt-async-gate/prompt-message-state.d.ts +0 -1
- package/dist/shared/prompt-async-gate/queue.d.ts +0 -1
- package/dist/shared/prompt-async-gate/recent-dispatches.d.ts +0 -1
- package/dist/shared/prompt-async-gate/reservations.d.ts +0 -1
- package/dist/shared/prompt-async-gate/semantic-dedupe.d.ts +0 -1
- package/dist/shared/prompt-async-gate/session-idle-dispatch.d.ts +0 -1
- package/dist/shared/prompt-async-gate/timing.d.ts +0 -1
- package/dist/shared/prompt-async-gate/types.d.ts +0 -1
- package/dist/tools/call-omo-agent/message-storage-directory.d.ts +0 -1
- package/dist/tools/delegate-task/model-string-parser.d.ts +0 -1
- package/packages/lsp-tools-mcp/dist/lsp/cleanup-errors.d.ts +0 -1
- package/packages/lsp-tools-mcp/dist/lsp/constants.d.ts +0 -1
- package/packages/lsp-tools-mcp/dist/lsp/language-mappings.d.ts +0 -1
- package/packages/lsp-tools-mcp/dist/lsp/process-signal-cleanup.d.ts +0 -1
- package/packages/lsp-tools-mcp/dist/missing-dependency-result.d.ts +0 -1
- package/packages/omo-codex/plugin/components/ultrawork/directive.md +0 -483
- package/packages/omo-codex/plugin/components/ultrawork/skills/ultrawork/SKILL.md +0 -490
|
@@ -15,6 +15,13 @@ import { pathToFileURL as pathToFileURL3 } from "node:url";
|
|
|
15
15
|
// ../lsp-core/src/lsp/connection.ts
|
|
16
16
|
import { pathToFileURL } from "node:url";
|
|
17
17
|
|
|
18
|
+
// ../lsp-core/src/lsp/timer-provider.ts
|
|
19
|
+
var realTimerProvider = {
|
|
20
|
+
now: () => Date.now(),
|
|
21
|
+
setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
|
|
22
|
+
clearTimeout: (handle) => clearTimeout(handle)
|
|
23
|
+
};
|
|
24
|
+
|
|
18
25
|
// ../lsp-core/src/lsp/constants.ts
|
|
19
26
|
var DEFAULT_MAX_REFERENCES = 200;
|
|
20
27
|
var DEFAULT_MAX_SYMBOLS = 200;
|
|
@@ -27,6 +34,8 @@ var MAX_RESIDENT_CLIENTS = 6;
|
|
|
27
34
|
var REAPER_INTERVAL_MS = 60000;
|
|
28
35
|
var STOP_HARD_KILL_TIMEOUT_MS = 5000;
|
|
29
36
|
var STOP_SIGKILL_GRACE_MS = 1000;
|
|
37
|
+
var CLIENT_RESPAWN_RETRY_LIMIT = 2;
|
|
38
|
+
var CLIENT_RESPAWN_COOLDOWN_MS = 60000;
|
|
30
39
|
|
|
31
40
|
// ../lsp-core/src/lsp/errors.ts
|
|
32
41
|
class LspConnectionClosedError extends Error {
|
|
@@ -91,6 +100,16 @@ class LspProcessSpawnError extends Error {
|
|
|
91
100
|
this.name = "LspProcessSpawnError";
|
|
92
101
|
}
|
|
93
102
|
}
|
|
103
|
+
|
|
104
|
+
class LspClientRespawnBudgetExceededError extends Error {
|
|
105
|
+
constructor(serverId, root, retryLimit) {
|
|
106
|
+
super(`LSP server ${serverId} at ${root} failed to stay alive; respawn budget exhausted ` + `(${retryLimit} consecutive dead generations). Retrying after the cooldown may succeed.`);
|
|
107
|
+
this.serverId = serverId;
|
|
108
|
+
this.root = root;
|
|
109
|
+
this.retryLimit = retryLimit;
|
|
110
|
+
this.name = "LspClientRespawnBudgetExceededError";
|
|
111
|
+
}
|
|
112
|
+
}
|
|
94
113
|
function isLspDeadConnectionError(err) {
|
|
95
114
|
return err instanceof LspConnectionClosedError || err instanceof LspProcessExitedError;
|
|
96
115
|
}
|
|
@@ -619,6 +638,7 @@ class LspClientTransport {
|
|
|
619
638
|
this.documentFormattingSupported = false;
|
|
620
639
|
this.requestTimeoutMs = timeouts.requestTimeoutMs ?? REQUEST_TIMEOUT_MS;
|
|
621
640
|
this.initializeTimeoutMs = timeouts.initializeTimeoutMs ?? INIT_TIMEOUT_MS;
|
|
641
|
+
this.timerProvider = timeouts.timerProvider ?? realTimerProvider;
|
|
622
642
|
}
|
|
623
643
|
pid() {
|
|
624
644
|
return this.proc?.pid;
|
|
@@ -719,7 +739,7 @@ class LspClientTransport {
|
|
|
719
739
|
const options = args[1];
|
|
720
740
|
const timeoutMs = options?.timeoutMs ?? this.requestTimeoutMs;
|
|
721
741
|
const timeoutController = new AbortController;
|
|
722
|
-
const timeoutHandle = setTimeout(() => {
|
|
742
|
+
const timeoutHandle = this.timerProvider.setTimeout(() => {
|
|
723
743
|
const stderrTail = this.stderrBuffer.slice(-5).join(`
|
|
724
744
|
`);
|
|
725
745
|
timeoutController.abort(new LspRequestTimeoutError(method, stderrTail || undefined));
|
|
@@ -738,7 +758,7 @@ class LspClientTransport {
|
|
|
738
758
|
}
|
|
739
759
|
throw error;
|
|
740
760
|
} finally {
|
|
741
|
-
clearTimeout(timeoutHandle);
|
|
761
|
+
this.timerProvider.clearTimeout(timeoutHandle);
|
|
742
762
|
combinedSignal.dispose();
|
|
743
763
|
}
|
|
744
764
|
}
|
|
@@ -1129,6 +1149,17 @@ function canonicalPath(filePath) {
|
|
|
1129
1149
|
return absolute;
|
|
1130
1150
|
}
|
|
1131
1151
|
}
|
|
1152
|
+
function normalizeDocumentUri(uri) {
|
|
1153
|
+
let decoded = uri;
|
|
1154
|
+
try {
|
|
1155
|
+
decoded = decodeURIComponent(uri);
|
|
1156
|
+
} catch {
|
|
1157
|
+
decoded = uri;
|
|
1158
|
+
}
|
|
1159
|
+
if (process.platform !== "win32")
|
|
1160
|
+
return decoded;
|
|
1161
|
+
return decoded.replace(/^(file:\/\/\/)([a-z]):/, (_match, prefix, drive) => `${prefix}${drive.toUpperCase()}:`);
|
|
1162
|
+
}
|
|
1132
1163
|
function isSameOrDescendant(candidate, parent) {
|
|
1133
1164
|
const suffix = relative(parent, candidate);
|
|
1134
1165
|
return suffix === "" || !suffix.startsWith("..") && suffix !== "..";
|
|
@@ -1145,7 +1176,12 @@ class WorkspaceDocumentState {
|
|
|
1145
1176
|
this.openDocuments = new Map;
|
|
1146
1177
|
this.openByUri = new Map;
|
|
1147
1178
|
this.openPromises = new Map;
|
|
1148
|
-
this.
|
|
1179
|
+
this.timerProvider = options.timerProvider ?? {
|
|
1180
|
+
now: options.now ?? (() => Date.now()),
|
|
1181
|
+
setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
|
|
1182
|
+
clearTimeout: (handle) => clearTimeout(handle)
|
|
1183
|
+
};
|
|
1184
|
+
this.now = () => this.timerProvider.now();
|
|
1149
1185
|
this.versionlessPublishQuiescenceMs = options.versionlessPublishQuiescenceMs ?? DEFAULT_VERSIONLESS_PUBLISH_QUIESCENCE_MS;
|
|
1150
1186
|
}
|
|
1151
1187
|
async openFile(filePath) {
|
|
@@ -1167,7 +1203,7 @@ class WorkspaceDocumentState {
|
|
|
1167
1203
|
return this.openDocuments.get(canonicalPath(filePath))?.version;
|
|
1168
1204
|
}
|
|
1169
1205
|
getStoredDiagnostics(uri) {
|
|
1170
|
-
const state = this.openByUri.get(uri);
|
|
1206
|
+
const state = this.openByUri.get(normalizeDocumentUri(uri));
|
|
1171
1207
|
if (!state)
|
|
1172
1208
|
return [];
|
|
1173
1209
|
return state.lastPublish?.diagnostics ?? state.pullCache?.diagnostics ?? [];
|
|
@@ -1189,13 +1225,13 @@ class WorkspaceDocumentState {
|
|
|
1189
1225
|
return state !== undefined && state.uri === snapshot.uri && state.version === snapshot.version && state.generation === snapshot.documentGeneration;
|
|
1190
1226
|
}
|
|
1191
1227
|
getPullCache(snapshot) {
|
|
1192
|
-
const state = this.openByUri.get(snapshot.uri);
|
|
1228
|
+
const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
|
|
1193
1229
|
if (!state?.pullCache || state.pullCache.documentVersion !== snapshot.version)
|
|
1194
1230
|
return null;
|
|
1195
1231
|
return state.pullCache;
|
|
1196
1232
|
}
|
|
1197
1233
|
recordPullDiagnostics(snapshot, report) {
|
|
1198
|
-
const state = this.openByUri.get(snapshot.uri);
|
|
1234
|
+
const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
|
|
1199
1235
|
if (!state)
|
|
1200
1236
|
return;
|
|
1201
1237
|
state.pullCache = {
|
|
@@ -1205,7 +1241,7 @@ class WorkspaceDocumentState {
|
|
|
1205
1241
|
};
|
|
1206
1242
|
}
|
|
1207
1243
|
recordPublishedDiagnostics(params) {
|
|
1208
|
-
const state = this.openByUri.get(params.uri);
|
|
1244
|
+
const state = this.openByUri.get(normalizeDocumentUri(params.uri));
|
|
1209
1245
|
if (!state)
|
|
1210
1246
|
return;
|
|
1211
1247
|
state.publishGeneration += 1;
|
|
@@ -1219,7 +1255,7 @@ class WorkspaceDocumentState {
|
|
|
1219
1255
|
this.notifyWaiters(state);
|
|
1220
1256
|
}
|
|
1221
1257
|
resolvePushDiagnostics(snapshot) {
|
|
1222
|
-
const state = this.openByUri.get(snapshot.uri);
|
|
1258
|
+
const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
|
|
1223
1259
|
if (!state?.lastPublish)
|
|
1224
1260
|
return { status: "missing" };
|
|
1225
1261
|
const publish = state.lastPublish;
|
|
@@ -1233,7 +1269,7 @@ class WorkspaceDocumentState {
|
|
|
1233
1269
|
return waitMs === 0 ? { status: "ready", diagnostics: publish.diagnostics } : { status: "wait", waitMs };
|
|
1234
1270
|
}
|
|
1235
1271
|
waitForDiagnosticsActivity(snapshot, timeoutMs) {
|
|
1236
|
-
const state = this.openByUri.get(snapshot.uri);
|
|
1272
|
+
const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
|
|
1237
1273
|
if (!state || timeoutMs <= 0)
|
|
1238
1274
|
return Promise.resolve();
|
|
1239
1275
|
return new Promise((resolveActivity) => {
|
|
@@ -1242,11 +1278,11 @@ class WorkspaceDocumentState {
|
|
|
1242
1278
|
if (settled)
|
|
1243
1279
|
return;
|
|
1244
1280
|
settled = true;
|
|
1245
|
-
clearTimeout(timer);
|
|
1281
|
+
this.timerProvider.clearTimeout(timer);
|
|
1246
1282
|
state.waiters.delete(finish);
|
|
1247
1283
|
resolveActivity();
|
|
1248
1284
|
};
|
|
1249
|
-
const timer = setTimeout(finish, timeoutMs);
|
|
1285
|
+
const timer = this.timerProvider.setTimeout(finish, timeoutMs);
|
|
1250
1286
|
if (typeof timer.unref === "function")
|
|
1251
1287
|
timer.unref();
|
|
1252
1288
|
state.waiters.add(finish);
|
|
@@ -1354,7 +1390,7 @@ class WorkspaceDocumentState {
|
|
|
1354
1390
|
waiters: new Set
|
|
1355
1391
|
};
|
|
1356
1392
|
this.openDocuments.set(path, state);
|
|
1357
|
-
this.openByUri.set(state.uri, state);
|
|
1393
|
+
this.openByUri.set(normalizeDocumentUri(state.uri), state);
|
|
1358
1394
|
this.notifyWaiters(state);
|
|
1359
1395
|
await this.sendNotification("textDocument/didOpen", {
|
|
1360
1396
|
textDocument: { uri: state.uri, languageId: state.languageId, version: state.version, text }
|
|
@@ -1379,7 +1415,7 @@ class WorkspaceDocumentState {
|
|
|
1379
1415
|
}
|
|
1380
1416
|
async closeDocument(state) {
|
|
1381
1417
|
this.openDocuments.delete(state.path);
|
|
1382
|
-
this.openByUri.delete(state.uri);
|
|
1418
|
+
this.openByUri.delete(normalizeDocumentUri(state.uri));
|
|
1383
1419
|
this.clearDiagnostics(state.uri);
|
|
1384
1420
|
this.notifyWaiters(state);
|
|
1385
1421
|
await this.sendNotification("textDocument/didClose", { textDocument: { uri: state.uri } });
|
|
@@ -2466,6 +2502,7 @@ class LspClient extends LspClientConnection {
|
|
|
2466
2502
|
this.diagnosticPullErrors = [];
|
|
2467
2503
|
this.diagnosticsFreshnessTimeoutMs = options.diagnosticsFreshnessTimeoutMs ?? DIAGNOSTICS_FRESHNESS_TIMEOUT_MS;
|
|
2468
2504
|
this.documents = new WorkspaceDocumentState((method, params) => this.sendNotification(method, params), (uri) => this.diagnosticsStore.delete(uri), {
|
|
2505
|
+
timerProvider: this.timerProvider,
|
|
2469
2506
|
versionlessPublishQuiescenceMs: options.versionlessPublishQuiescenceMs ?? VERSIONLESS_PUBLISH_QUIESCENCE_MS
|
|
2470
2507
|
});
|
|
2471
2508
|
this.workspaceMutations = new WorkspaceMutationController(root, this.documents);
|
|
@@ -2569,7 +2606,7 @@ class LspClient extends LspClientConnection {
|
|
|
2569
2606
|
const absPath = this.resolveWorkspacePath(filePath);
|
|
2570
2607
|
const uri = pathToFileURL3(absPath).href;
|
|
2571
2608
|
await this.openFile(absPath);
|
|
2572
|
-
const deadlineAt =
|
|
2609
|
+
const deadlineAt = this.timerProvider.now() + this.diagnosticsFreshnessTimeoutMs;
|
|
2573
2610
|
for (;; ) {
|
|
2574
2611
|
signal?.throwIfAborted();
|
|
2575
2612
|
const snapshot = this.documents.captureDiagnosticSnapshot(absPath);
|
|
@@ -2582,7 +2619,7 @@ class LspClient extends LspClientConnection {
|
|
|
2582
2619
|
if (!pushFallbackOnly) {
|
|
2583
2620
|
const cached = this.documents.getPullCache(snapshot);
|
|
2584
2621
|
try {
|
|
2585
|
-
const remainingMs2 = deadlineAt -
|
|
2622
|
+
const remainingMs2 = deadlineAt - this.timerProvider.now();
|
|
2586
2623
|
if (remainingMs2 <= 0)
|
|
2587
2624
|
return this.freshnessTimeout(absPath);
|
|
2588
2625
|
const result = await this.sendRequest("textDocument/diagnostic", {
|
|
@@ -2617,7 +2654,7 @@ class LspClient extends LspClientConnection {
|
|
|
2617
2654
|
}
|
|
2618
2655
|
if (!pushFallbackOnly)
|
|
2619
2656
|
continue;
|
|
2620
|
-
const remainingMs = deadlineAt -
|
|
2657
|
+
const remainingMs = deadlineAt - this.timerProvider.now();
|
|
2621
2658
|
if (remainingMs <= 0) {
|
|
2622
2659
|
if (!this.isDiagnosticPullSupported() && snapshot.publishGeneration === 0) {
|
|
2623
2660
|
const cached = this.documents.getPullCache(snapshot);
|
|
@@ -2777,6 +2814,8 @@ function awaitWithSignal(promise, signal) {
|
|
|
2777
2814
|
class LspManager {
|
|
2778
2815
|
constructor(options = {}) {
|
|
2779
2816
|
this.clients = new Map;
|
|
2817
|
+
this.pendingStops = new Map;
|
|
2818
|
+
this.respawnBudgets = new Map;
|
|
2780
2819
|
this.reaperHandle = null;
|
|
2781
2820
|
this.signalDisposer = null;
|
|
2782
2821
|
this.disposed = false;
|
|
@@ -2802,17 +2841,52 @@ class LspManager {
|
|
|
2802
2841
|
getKey(root, serverId) {
|
|
2803
2842
|
return `${root}::${serverId}`;
|
|
2804
2843
|
}
|
|
2844
|
+
tombstoneStop(key, client) {
|
|
2845
|
+
const stop = stopClientBestEffort(client);
|
|
2846
|
+
this.pendingStops.set(key, stop);
|
|
2847
|
+
stop.finally(() => {
|
|
2848
|
+
if (this.pendingStops.get(key) === stop) {
|
|
2849
|
+
this.pendingStops.delete(key);
|
|
2850
|
+
}
|
|
2851
|
+
});
|
|
2852
|
+
return stop;
|
|
2853
|
+
}
|
|
2854
|
+
recordDeadGeneration(key) {
|
|
2855
|
+
let budget = this.respawnBudgets.get(key);
|
|
2856
|
+
if (budget === undefined) {
|
|
2857
|
+
budget = { deadGenerations: 0, exhaustedAt: null };
|
|
2858
|
+
this.respawnBudgets.set(key, budget);
|
|
2859
|
+
}
|
|
2860
|
+
budget.deadGenerations += 1;
|
|
2861
|
+
}
|
|
2862
|
+
markHealthyGeneration(key) {
|
|
2863
|
+
this.respawnBudgets.delete(key);
|
|
2864
|
+
}
|
|
2865
|
+
ensureRespawnAllowed(key, root, serverId) {
|
|
2866
|
+
const budget = this.respawnBudgets.get(key);
|
|
2867
|
+
if (budget === undefined || budget.deadGenerations < CLIENT_RESPAWN_RETRY_LIMIT)
|
|
2868
|
+
return;
|
|
2869
|
+
if (budget.exhaustedAt === null) {
|
|
2870
|
+
budget.exhaustedAt = this.now();
|
|
2871
|
+
throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
|
|
2872
|
+
}
|
|
2873
|
+
if (this.now() - budget.exhaustedAt < CLIENT_RESPAWN_COOLDOWN_MS) {
|
|
2874
|
+
throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
|
|
2875
|
+
}
|
|
2876
|
+
budget.deadGenerations = 0;
|
|
2877
|
+
budget.exhaustedAt = null;
|
|
2878
|
+
}
|
|
2805
2879
|
reapStale() {
|
|
2806
2880
|
const t = this.now();
|
|
2807
2881
|
for (const [key, managed] of this.clients) {
|
|
2808
2882
|
if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
|
|
2809
|
-
stopClientBestEffort(managed.client);
|
|
2810
2883
|
this.clients.delete(key);
|
|
2884
|
+
this.tombstoneStop(key, managed.client);
|
|
2811
2885
|
continue;
|
|
2812
2886
|
}
|
|
2813
2887
|
if (!managed.isInitializing && managed.refCount === 0 && managed.pendingWaiters === 0 && t - managed.lastUsedAt > this.idleTimeoutMs) {
|
|
2814
|
-
stopClientBestEffort(managed.client);
|
|
2815
2888
|
this.clients.delete(key);
|
|
2889
|
+
this.tombstoneStop(key, managed.client);
|
|
2816
2890
|
}
|
|
2817
2891
|
}
|
|
2818
2892
|
}
|
|
@@ -2822,7 +2896,7 @@ class LspManager {
|
|
|
2822
2896
|
if (!victim)
|
|
2823
2897
|
return;
|
|
2824
2898
|
this.clients.delete(victim.key);
|
|
2825
|
-
|
|
2899
|
+
this.tombstoneStop(victim.key, victim.managed.client);
|
|
2826
2900
|
}
|
|
2827
2901
|
}
|
|
2828
2902
|
leastRecentlyUsedIdleClient() {
|
|
@@ -2839,7 +2913,7 @@ class LspManager {
|
|
|
2839
2913
|
async tryDeleteIfOrphaned(key, managed) {
|
|
2840
2914
|
if (managed.refCount === 0 && managed.pendingWaiters === 0 && !managed.isInitializing && this.clients.get(key) === managed) {
|
|
2841
2915
|
this.clients.delete(key);
|
|
2842
|
-
await
|
|
2916
|
+
await this.tombstoneStop(key, managed.client);
|
|
2843
2917
|
}
|
|
2844
2918
|
}
|
|
2845
2919
|
async getClient(root, server, signal) {
|
|
@@ -2848,12 +2922,22 @@ class LspManager {
|
|
|
2848
2922
|
}
|
|
2849
2923
|
signal?.throwIfAborted();
|
|
2850
2924
|
const key = this.getKey(root, server.id);
|
|
2925
|
+
for (;; ) {
|
|
2926
|
+
const pendingStop = this.pendingStops.get(key);
|
|
2927
|
+
if (pendingStop === undefined)
|
|
2928
|
+
break;
|
|
2929
|
+
await awaitWithSignal(pendingStop, signal);
|
|
2930
|
+
signal?.throwIfAborted();
|
|
2931
|
+
}
|
|
2932
|
+
if (this.disposed) {
|
|
2933
|
+
throw new Error("LspManager has been disposed");
|
|
2934
|
+
}
|
|
2851
2935
|
let managed = this.clients.get(key);
|
|
2852
2936
|
if (managed) {
|
|
2853
2937
|
const t = this.now();
|
|
2854
2938
|
if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
|
|
2855
|
-
await stopClientBestEffort(managed.client);
|
|
2856
2939
|
this.clients.delete(key);
|
|
2940
|
+
await this.tombstoneStop(key, managed.client);
|
|
2857
2941
|
managed = undefined;
|
|
2858
2942
|
}
|
|
2859
2943
|
}
|
|
@@ -2874,15 +2958,20 @@ class LspManager {
|
|
|
2874
2958
|
signal.throwIfAborted();
|
|
2875
2959
|
}
|
|
2876
2960
|
if (!managed.client.isAlive()) {
|
|
2877
|
-
|
|
2878
|
-
this.clients.
|
|
2961
|
+
this.recordDeadGeneration(key);
|
|
2962
|
+
if (this.clients.get(key) === managed) {
|
|
2963
|
+
this.clients.delete(key);
|
|
2964
|
+
}
|
|
2965
|
+
await this.tombstoneStop(key, managed.client);
|
|
2879
2966
|
return this.getClient(root, server, signal);
|
|
2880
2967
|
}
|
|
2968
|
+
this.markHealthyGeneration(key);
|
|
2881
2969
|
managed.refCount++;
|
|
2882
2970
|
managed.lastUsedAt = this.now();
|
|
2883
2971
|
return managed.client;
|
|
2884
2972
|
}
|
|
2885
2973
|
this.evictForAdmission();
|
|
2974
|
+
this.ensureRespawnAllowed(key, root, server.id);
|
|
2886
2975
|
const client = this.clientFactory(root, server);
|
|
2887
2976
|
const initStartedAt = this.now();
|
|
2888
2977
|
const initPromise = (async () => {
|
|
@@ -2906,7 +2995,7 @@ class LspManager {
|
|
|
2906
2995
|
if (this.clients.get(key) === newManaged) {
|
|
2907
2996
|
this.clients.delete(key);
|
|
2908
2997
|
}
|
|
2909
|
-
await
|
|
2998
|
+
await this.tombstoneStop(key, client);
|
|
2910
2999
|
throw err;
|
|
2911
3000
|
}
|
|
2912
3001
|
newManaged.pendingWaiters--;
|
|
@@ -2917,6 +3006,15 @@ class LspManager {
|
|
|
2917
3006
|
await this.tryDeleteIfOrphaned(key, newManaged);
|
|
2918
3007
|
signal.throwIfAborted();
|
|
2919
3008
|
}
|
|
3009
|
+
if (!client.isAlive()) {
|
|
3010
|
+
this.recordDeadGeneration(key);
|
|
3011
|
+
if (this.clients.get(key) === newManaged) {
|
|
3012
|
+
this.clients.delete(key);
|
|
3013
|
+
}
|
|
3014
|
+
await this.tombstoneStop(key, client);
|
|
3015
|
+
return this.getClient(root, server, signal);
|
|
3016
|
+
}
|
|
3017
|
+
this.markHealthyGeneration(key);
|
|
2920
3018
|
newManaged.refCount++;
|
|
2921
3019
|
newManaged.lastUsedAt = this.now();
|
|
2922
3020
|
return client;
|
|
@@ -2937,15 +3035,20 @@ class LspManager {
|
|
|
2937
3035
|
if (client && managed.client !== client)
|
|
2938
3036
|
return;
|
|
2939
3037
|
this.clients.delete(key);
|
|
2940
|
-
|
|
3038
|
+
this.tombstoneStop(key, managed.client);
|
|
2941
3039
|
}
|
|
2942
3040
|
warmupClient(root, server) {
|
|
2943
3041
|
if (this.disposed)
|
|
2944
3042
|
return;
|
|
2945
3043
|
const key = this.getKey(root, server.id);
|
|
2946
|
-
if (this.clients.has(key))
|
|
3044
|
+
if (this.clients.has(key) || this.pendingStops.has(key))
|
|
2947
3045
|
return;
|
|
2948
3046
|
this.evictForAdmission();
|
|
3047
|
+
try {
|
|
3048
|
+
this.ensureRespawnAllowed(key, root, server.id);
|
|
3049
|
+
} catch {
|
|
3050
|
+
return;
|
|
3051
|
+
}
|
|
2949
3052
|
const client = this.clientFactory(root, server);
|
|
2950
3053
|
const initStartedAt = this.now();
|
|
2951
3054
|
const initPromise = (async () => {
|
|
@@ -2971,7 +3074,7 @@ class LspManager {
|
|
|
2971
3074
|
if (this.clients.get(key) === managed) {
|
|
2972
3075
|
this.clients.delete(key);
|
|
2973
3076
|
}
|
|
2974
|
-
|
|
3077
|
+
this.tombstoneStop(key, client);
|
|
2975
3078
|
});
|
|
2976
3079
|
}
|
|
2977
3080
|
isServerInitializing(root, serverId) {
|
|
@@ -3015,8 +3118,11 @@ class LspManager {
|
|
|
3015
3118
|
for (const managed of this.clients.values()) {
|
|
3016
3119
|
stopPromises.push(stopClientBestEffort(managed.client));
|
|
3017
3120
|
}
|
|
3121
|
+
const tombstonedStops = [...this.pendingStops.values()];
|
|
3018
3122
|
this.clients.clear();
|
|
3019
|
-
|
|
3123
|
+
this.respawnBudgets.clear();
|
|
3124
|
+
await Promise.allSettled([...stopPromises, ...tombstonedStops]);
|
|
3125
|
+
this.pendingStops.clear();
|
|
3020
3126
|
}
|
|
3021
3127
|
}
|
|
3022
3128
|
var _defaultInstance = null;
|
|
@@ -4038,6 +4144,7 @@ async function runJsonRpcStdioServer(config) {
|
|
|
4038
4144
|
const idleTimer = createIdleTimer(idleTimeoutMs, log, () => {
|
|
4039
4145
|
isClosed = true;
|
|
4040
4146
|
config.onIdleTimeout?.();
|
|
4147
|
+
config.input.destroy();
|
|
4041
4148
|
});
|
|
4042
4149
|
const watchdog = createParentWatchdog(config.parentWatchdog, (parentPid, pollIntervalMs) => {
|
|
4043
4150
|
isClosed = true;
|
|
@@ -4181,7 +4288,16 @@ import { existsSync as existsSync7, realpathSync as realpathSync4 } from "node:f
|
|
|
4181
4288
|
import { dirname as dirname7, join as join3 } from "node:path";
|
|
4182
4289
|
|
|
4183
4290
|
// ../lsp-core/src/lsp/workspace-markers.ts
|
|
4184
|
-
var
|
|
4291
|
+
var GIT_WORKSPACE_MARKER = ".git";
|
|
4292
|
+
var PROJECT_WORKSPACE_MARKERS = [
|
|
4293
|
+
"package.json",
|
|
4294
|
+
"pyproject.toml",
|
|
4295
|
+
"Cargo.toml",
|
|
4296
|
+
"go.mod",
|
|
4297
|
+
"pom.xml",
|
|
4298
|
+
"build.gradle"
|
|
4299
|
+
];
|
|
4300
|
+
var WORKSPACE_MARKERS = [GIT_WORKSPACE_MARKER, ...PROJECT_WORKSPACE_MARKERS];
|
|
4185
4301
|
|
|
4186
4302
|
// ../lsp-core/src/lsp/outside-context-workspace.ts
|
|
4187
4303
|
function findWorkspaceRootOutsideContext(directory) {
|
|
@@ -4870,20 +4986,25 @@ function findWorkspaceRoot(filePath) {
|
|
|
4870
4986
|
if (!isPathInside(cwd, abs))
|
|
4871
4987
|
return findWorkspaceRootOutsideContext(dir);
|
|
4872
4988
|
const fallbackRoot = nearestExistingDirectoryInsideContext(dir, cwd) ?? cwd;
|
|
4989
|
+
let nearestPackageRoot;
|
|
4873
4990
|
while (isPathInside(cwd, dir)) {
|
|
4874
4991
|
const canonicalDir = existingDirectoryInsideContext(dir, cwd);
|
|
4875
4992
|
if (canonicalDir !== undefined) {
|
|
4876
|
-
|
|
4877
|
-
|
|
4878
|
-
|
|
4879
|
-
|
|
4993
|
+
if (existsSync11(join5(dir, GIT_WORKSPACE_MARKER))) {
|
|
4994
|
+
return canonicalDir;
|
|
4995
|
+
}
|
|
4996
|
+
if (nearestPackageRoot === undefined && hasProjectWorkspaceMarker(dir)) {
|
|
4997
|
+
nearestPackageRoot = canonicalDir;
|
|
4880
4998
|
}
|
|
4881
4999
|
}
|
|
4882
5000
|
if (dir === cwd)
|
|
4883
5001
|
break;
|
|
4884
5002
|
dir = dirname10(dir);
|
|
4885
5003
|
}
|
|
4886
|
-
return fallbackRoot;
|
|
5004
|
+
return nearestPackageRoot ?? fallbackRoot;
|
|
5005
|
+
}
|
|
5006
|
+
function hasProjectWorkspaceMarker(directory) {
|
|
5007
|
+
return PROJECT_WORKSPACE_MARKERS.some((marker) => existsSync11(join5(directory, marker)));
|
|
4887
5008
|
}
|
|
4888
5009
|
function resolveReadablePathInsideContext(filePath) {
|
|
4889
5010
|
const cwd = contextCwd();
|
|
@@ -58,6 +58,9 @@ export async function runMcpStdioProxy(options = {}) {
|
|
|
58
58
|
await runJsonRpcStdioServer({
|
|
59
59
|
input,
|
|
60
60
|
output,
|
|
61
|
+
// Idle stays disabled: the opencode host does not respawn a stdio MCP
|
|
62
|
+
// server that exits — transport close marks it failed until a user
|
|
63
|
+
// reconnects via /mcp — so an idle kill would strand a live session.
|
|
61
64
|
idleTimeoutMs: 0,
|
|
62
65
|
parentWatchdog: options.parentWatchdog ?? {},
|
|
63
66
|
handler: (request, requestOptions) => {
|