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
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
clientOptions,
|
|
5
|
+
optionalBoolean,
|
|
6
|
+
optionalNumber,
|
|
7
|
+
optionalString,
|
|
8
|
+
requireNumber,
|
|
9
|
+
requireString,
|
|
10
|
+
severityFilter,
|
|
11
|
+
} from "./parameters.js";
|
|
12
|
+
|
|
13
|
+
describe("LSP tool parameter helpers", () => {
|
|
14
|
+
test("#given required string parameter #when value is missing or empty #then throws clear error", () => {
|
|
15
|
+
expect(requireString({ filePath: "index.ts" }, "filePath")).toBe("index.ts");
|
|
16
|
+
expect(() => requireString({}, "filePath")).toThrow("Missing required string parameter 'filePath'");
|
|
17
|
+
expect(() => requireString({ filePath: "" }, "filePath")).toThrow("Missing required string parameter 'filePath'");
|
|
18
|
+
expect(() => requireString({ filePath: 42 }, "filePath")).toThrow("Missing required string parameter 'filePath'");
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test("#given required number parameter #when value is non-finite #then throws clear error", () => {
|
|
22
|
+
expect(requireNumber({ line: 3 }, "line")).toBe(3);
|
|
23
|
+
expect(() => requireNumber({}, "line")).toThrow("Missing required number parameter 'line'");
|
|
24
|
+
expect(() => requireNumber({ line: Number.NaN }, "line")).toThrow("Missing required number parameter 'line'");
|
|
25
|
+
expect(() => requireNumber({ line: Number.POSITIVE_INFINITY }, "line")).toThrow(
|
|
26
|
+
"Missing required number parameter 'line'",
|
|
27
|
+
);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
test("#given optional parameters #when values have wrong type #then ignores them", () => {
|
|
31
|
+
expect(optionalString({ query: "symbol" }, "query")).toBe("symbol");
|
|
32
|
+
expect(optionalString({ query: 7 }, "query")).toBeUndefined();
|
|
33
|
+
expect(optionalNumber({ limit: 10 }, "limit")).toBe(10);
|
|
34
|
+
expect(optionalNumber({ limit: Number.NaN }, "limit")).toBeUndefined();
|
|
35
|
+
expect(optionalBoolean({ includeDeclaration: false }, "includeDeclaration")).toBe(false);
|
|
36
|
+
expect(optionalBoolean({ includeDeclaration: "false" }, "includeDeclaration")).toBeUndefined();
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
test("#given severity parameter #when value is unknown #then defaults to all", () => {
|
|
40
|
+
expect(severityFilter({ severity: "warning" })).toBe("warning");
|
|
41
|
+
expect(severityFilter({ severity: "fatal" })).toBe("all");
|
|
42
|
+
expect(severityFilter({})).toBe("all");
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test("#given optional abort signal #when building client options #then includes only defined signal", () => {
|
|
46
|
+
const controller = new AbortController();
|
|
47
|
+
|
|
48
|
+
expect(clientOptions(undefined)).toEqual({});
|
|
49
|
+
expect(clientOptions(controller.signal)).toEqual({ signal: controller.signal });
|
|
50
|
+
});
|
|
51
|
+
});
|
|
@@ -184,6 +184,7 @@ async function runJsonRpcStdioServer(config) {
|
|
|
184
184
|
const idleTimer = createIdleTimer(idleTimeoutMs, log, () => {
|
|
185
185
|
isClosed = true;
|
|
186
186
|
config.onIdleTimeout?.();
|
|
187
|
+
config.input.destroy();
|
|
187
188
|
});
|
|
188
189
|
const watchdog = createParentWatchdog(config.parentWatchdog, (parentPid, pollIntervalMs) => {
|
|
189
190
|
isClosed = true;
|
|
@@ -563,6 +564,16 @@ class LspProcessSpawnError extends Error {
|
|
|
563
564
|
this.name = "LspProcessSpawnError";
|
|
564
565
|
}
|
|
565
566
|
}
|
|
567
|
+
|
|
568
|
+
class LspClientRespawnBudgetExceededError extends Error {
|
|
569
|
+
constructor(serverId, root, retryLimit) {
|
|
570
|
+
super(`LSP server ${serverId} at ${root} failed to stay alive; respawn budget exhausted ` + `(${retryLimit} consecutive dead generations). Retrying after the cooldown may succeed.`);
|
|
571
|
+
this.serverId = serverId;
|
|
572
|
+
this.root = root;
|
|
573
|
+
this.retryLimit = retryLimit;
|
|
574
|
+
this.name = "LspClientRespawnBudgetExceededError";
|
|
575
|
+
}
|
|
576
|
+
}
|
|
566
577
|
function isLspDeadConnectionError(err) {
|
|
567
578
|
return err instanceof LspConnectionClosedError || err instanceof LspProcessExitedError;
|
|
568
579
|
}
|
|
@@ -584,6 +595,13 @@ import { pathToFileURL as pathToFileURL3 } from "node:url";
|
|
|
584
595
|
// ../lsp-core/src/lsp/connection.ts
|
|
585
596
|
import { pathToFileURL } from "node:url";
|
|
586
597
|
|
|
598
|
+
// ../lsp-core/src/lsp/timer-provider.ts
|
|
599
|
+
var realTimerProvider = {
|
|
600
|
+
now: () => Date.now(),
|
|
601
|
+
setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
|
|
602
|
+
clearTimeout: (handle) => clearTimeout(handle)
|
|
603
|
+
};
|
|
604
|
+
|
|
587
605
|
// ../lsp-core/src/lsp/constants.ts
|
|
588
606
|
var DEFAULT_MAX_REFERENCES = 200;
|
|
589
607
|
var DEFAULT_MAX_SYMBOLS = 200;
|
|
@@ -596,6 +614,8 @@ var MAX_RESIDENT_CLIENTS = 6;
|
|
|
596
614
|
var REAPER_INTERVAL_MS = 60000;
|
|
597
615
|
var STOP_HARD_KILL_TIMEOUT_MS = 5000;
|
|
598
616
|
var STOP_SIGKILL_GRACE_MS = 1000;
|
|
617
|
+
var CLIENT_RESPAWN_RETRY_LIMIT = 2;
|
|
618
|
+
var CLIENT_RESPAWN_COOLDOWN_MS = 60000;
|
|
599
619
|
|
|
600
620
|
// ../lsp-core/src/lsp/json-rpc-connection.ts
|
|
601
621
|
var HEADER_SEPARATOR2 = `\r
|
|
@@ -1121,6 +1141,7 @@ class LspClientTransport {
|
|
|
1121
1141
|
this.documentFormattingSupported = false;
|
|
1122
1142
|
this.requestTimeoutMs = timeouts.requestTimeoutMs ?? REQUEST_TIMEOUT_MS;
|
|
1123
1143
|
this.initializeTimeoutMs = timeouts.initializeTimeoutMs ?? INIT_TIMEOUT_MS;
|
|
1144
|
+
this.timerProvider = timeouts.timerProvider ?? realTimerProvider;
|
|
1124
1145
|
}
|
|
1125
1146
|
pid() {
|
|
1126
1147
|
return this.proc?.pid;
|
|
@@ -1221,7 +1242,7 @@ class LspClientTransport {
|
|
|
1221
1242
|
const options = args[1];
|
|
1222
1243
|
const timeoutMs = options?.timeoutMs ?? this.requestTimeoutMs;
|
|
1223
1244
|
const timeoutController = new AbortController;
|
|
1224
|
-
const timeoutHandle = setTimeout(() => {
|
|
1245
|
+
const timeoutHandle = this.timerProvider.setTimeout(() => {
|
|
1225
1246
|
const stderrTail = this.stderrBuffer.slice(-5).join(`
|
|
1226
1247
|
`);
|
|
1227
1248
|
timeoutController.abort(new LspRequestTimeoutError(method, stderrTail || undefined));
|
|
@@ -1240,7 +1261,7 @@ class LspClientTransport {
|
|
|
1240
1261
|
}
|
|
1241
1262
|
throw error;
|
|
1242
1263
|
} finally {
|
|
1243
|
-
clearTimeout(timeoutHandle);
|
|
1264
|
+
this.timerProvider.clearTimeout(timeoutHandle);
|
|
1244
1265
|
combinedSignal.dispose();
|
|
1245
1266
|
}
|
|
1246
1267
|
}
|
|
@@ -1621,6 +1642,17 @@ function canonicalPath(filePath) {
|
|
|
1621
1642
|
return absolute;
|
|
1622
1643
|
}
|
|
1623
1644
|
}
|
|
1645
|
+
function normalizeDocumentUri(uri) {
|
|
1646
|
+
let decoded = uri;
|
|
1647
|
+
try {
|
|
1648
|
+
decoded = decodeURIComponent(uri);
|
|
1649
|
+
} catch {
|
|
1650
|
+
decoded = uri;
|
|
1651
|
+
}
|
|
1652
|
+
if (process.platform !== "win32")
|
|
1653
|
+
return decoded;
|
|
1654
|
+
return decoded.replace(/^(file:\/\/\/)([a-z]):/, (_match, prefix, drive) => `${prefix}${drive.toUpperCase()}:`);
|
|
1655
|
+
}
|
|
1624
1656
|
function isSameOrDescendant(candidate, parent) {
|
|
1625
1657
|
const suffix = relative2(parent, candidate);
|
|
1626
1658
|
return suffix === "" || !suffix.startsWith("..") && suffix !== "..";
|
|
@@ -1637,7 +1669,12 @@ class WorkspaceDocumentState {
|
|
|
1637
1669
|
this.openDocuments = new Map;
|
|
1638
1670
|
this.openByUri = new Map;
|
|
1639
1671
|
this.openPromises = new Map;
|
|
1640
|
-
this.
|
|
1672
|
+
this.timerProvider = options.timerProvider ?? {
|
|
1673
|
+
now: options.now ?? (() => Date.now()),
|
|
1674
|
+
setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
|
|
1675
|
+
clearTimeout: (handle) => clearTimeout(handle)
|
|
1676
|
+
};
|
|
1677
|
+
this.now = () => this.timerProvider.now();
|
|
1641
1678
|
this.versionlessPublishQuiescenceMs = options.versionlessPublishQuiescenceMs ?? DEFAULT_VERSIONLESS_PUBLISH_QUIESCENCE_MS;
|
|
1642
1679
|
}
|
|
1643
1680
|
async openFile(filePath) {
|
|
@@ -1659,7 +1696,7 @@ class WorkspaceDocumentState {
|
|
|
1659
1696
|
return this.openDocuments.get(canonicalPath(filePath))?.version;
|
|
1660
1697
|
}
|
|
1661
1698
|
getStoredDiagnostics(uri) {
|
|
1662
|
-
const state = this.openByUri.get(uri);
|
|
1699
|
+
const state = this.openByUri.get(normalizeDocumentUri(uri));
|
|
1663
1700
|
if (!state)
|
|
1664
1701
|
return [];
|
|
1665
1702
|
return state.lastPublish?.diagnostics ?? state.pullCache?.diagnostics ?? [];
|
|
@@ -1681,13 +1718,13 @@ class WorkspaceDocumentState {
|
|
|
1681
1718
|
return state !== undefined && state.uri === snapshot.uri && state.version === snapshot.version && state.generation === snapshot.documentGeneration;
|
|
1682
1719
|
}
|
|
1683
1720
|
getPullCache(snapshot) {
|
|
1684
|
-
const state = this.openByUri.get(snapshot.uri);
|
|
1721
|
+
const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
|
|
1685
1722
|
if (!state?.pullCache || state.pullCache.documentVersion !== snapshot.version)
|
|
1686
1723
|
return null;
|
|
1687
1724
|
return state.pullCache;
|
|
1688
1725
|
}
|
|
1689
1726
|
recordPullDiagnostics(snapshot, report) {
|
|
1690
|
-
const state = this.openByUri.get(snapshot.uri);
|
|
1727
|
+
const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
|
|
1691
1728
|
if (!state)
|
|
1692
1729
|
return;
|
|
1693
1730
|
state.pullCache = {
|
|
@@ -1697,7 +1734,7 @@ class WorkspaceDocumentState {
|
|
|
1697
1734
|
};
|
|
1698
1735
|
}
|
|
1699
1736
|
recordPublishedDiagnostics(params) {
|
|
1700
|
-
const state = this.openByUri.get(params.uri);
|
|
1737
|
+
const state = this.openByUri.get(normalizeDocumentUri(params.uri));
|
|
1701
1738
|
if (!state)
|
|
1702
1739
|
return;
|
|
1703
1740
|
state.publishGeneration += 1;
|
|
@@ -1711,7 +1748,7 @@ class WorkspaceDocumentState {
|
|
|
1711
1748
|
this.notifyWaiters(state);
|
|
1712
1749
|
}
|
|
1713
1750
|
resolvePushDiagnostics(snapshot) {
|
|
1714
|
-
const state = this.openByUri.get(snapshot.uri);
|
|
1751
|
+
const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
|
|
1715
1752
|
if (!state?.lastPublish)
|
|
1716
1753
|
return { status: "missing" };
|
|
1717
1754
|
const publish = state.lastPublish;
|
|
@@ -1725,7 +1762,7 @@ class WorkspaceDocumentState {
|
|
|
1725
1762
|
return waitMs === 0 ? { status: "ready", diagnostics: publish.diagnostics } : { status: "wait", waitMs };
|
|
1726
1763
|
}
|
|
1727
1764
|
waitForDiagnosticsActivity(snapshot, timeoutMs) {
|
|
1728
|
-
const state = this.openByUri.get(snapshot.uri);
|
|
1765
|
+
const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
|
|
1729
1766
|
if (!state || timeoutMs <= 0)
|
|
1730
1767
|
return Promise.resolve();
|
|
1731
1768
|
return new Promise((resolveActivity) => {
|
|
@@ -1734,11 +1771,11 @@ class WorkspaceDocumentState {
|
|
|
1734
1771
|
if (settled)
|
|
1735
1772
|
return;
|
|
1736
1773
|
settled = true;
|
|
1737
|
-
clearTimeout(timer);
|
|
1774
|
+
this.timerProvider.clearTimeout(timer);
|
|
1738
1775
|
state.waiters.delete(finish);
|
|
1739
1776
|
resolveActivity();
|
|
1740
1777
|
};
|
|
1741
|
-
const timer = setTimeout(finish, timeoutMs);
|
|
1778
|
+
const timer = this.timerProvider.setTimeout(finish, timeoutMs);
|
|
1742
1779
|
if (typeof timer.unref === "function")
|
|
1743
1780
|
timer.unref();
|
|
1744
1781
|
state.waiters.add(finish);
|
|
@@ -1846,7 +1883,7 @@ class WorkspaceDocumentState {
|
|
|
1846
1883
|
waiters: new Set
|
|
1847
1884
|
};
|
|
1848
1885
|
this.openDocuments.set(path, state);
|
|
1849
|
-
this.openByUri.set(state.uri, state);
|
|
1886
|
+
this.openByUri.set(normalizeDocumentUri(state.uri), state);
|
|
1850
1887
|
this.notifyWaiters(state);
|
|
1851
1888
|
await this.sendNotification("textDocument/didOpen", {
|
|
1852
1889
|
textDocument: { uri: state.uri, languageId: state.languageId, version: state.version, text }
|
|
@@ -1871,7 +1908,7 @@ class WorkspaceDocumentState {
|
|
|
1871
1908
|
}
|
|
1872
1909
|
async closeDocument(state) {
|
|
1873
1910
|
this.openDocuments.delete(state.path);
|
|
1874
|
-
this.openByUri.delete(state.uri);
|
|
1911
|
+
this.openByUri.delete(normalizeDocumentUri(state.uri));
|
|
1875
1912
|
this.clearDiagnostics(state.uri);
|
|
1876
1913
|
this.notifyWaiters(state);
|
|
1877
1914
|
await this.sendNotification("textDocument/didClose", { textDocument: { uri: state.uri } });
|
|
@@ -2958,6 +2995,7 @@ class LspClient extends LspClientConnection {
|
|
|
2958
2995
|
this.diagnosticPullErrors = [];
|
|
2959
2996
|
this.diagnosticsFreshnessTimeoutMs = options.diagnosticsFreshnessTimeoutMs ?? DIAGNOSTICS_FRESHNESS_TIMEOUT_MS;
|
|
2960
2997
|
this.documents = new WorkspaceDocumentState((method, params) => this.sendNotification(method, params), (uri) => this.diagnosticsStore.delete(uri), {
|
|
2998
|
+
timerProvider: this.timerProvider,
|
|
2961
2999
|
versionlessPublishQuiescenceMs: options.versionlessPublishQuiescenceMs ?? VERSIONLESS_PUBLISH_QUIESCENCE_MS
|
|
2962
3000
|
});
|
|
2963
3001
|
this.workspaceMutations = new WorkspaceMutationController(root, this.documents);
|
|
@@ -3061,7 +3099,7 @@ class LspClient extends LspClientConnection {
|
|
|
3061
3099
|
const absPath = this.resolveWorkspacePath(filePath);
|
|
3062
3100
|
const uri = pathToFileURL3(absPath).href;
|
|
3063
3101
|
await this.openFile(absPath);
|
|
3064
|
-
const deadlineAt =
|
|
3102
|
+
const deadlineAt = this.timerProvider.now() + this.diagnosticsFreshnessTimeoutMs;
|
|
3065
3103
|
for (;; ) {
|
|
3066
3104
|
signal?.throwIfAborted();
|
|
3067
3105
|
const snapshot = this.documents.captureDiagnosticSnapshot(absPath);
|
|
@@ -3074,7 +3112,7 @@ class LspClient extends LspClientConnection {
|
|
|
3074
3112
|
if (!pushFallbackOnly) {
|
|
3075
3113
|
const cached = this.documents.getPullCache(snapshot);
|
|
3076
3114
|
try {
|
|
3077
|
-
const remainingMs2 = deadlineAt -
|
|
3115
|
+
const remainingMs2 = deadlineAt - this.timerProvider.now();
|
|
3078
3116
|
if (remainingMs2 <= 0)
|
|
3079
3117
|
return this.freshnessTimeout(absPath);
|
|
3080
3118
|
const result = await this.sendRequest("textDocument/diagnostic", {
|
|
@@ -3109,7 +3147,7 @@ class LspClient extends LspClientConnection {
|
|
|
3109
3147
|
}
|
|
3110
3148
|
if (!pushFallbackOnly)
|
|
3111
3149
|
continue;
|
|
3112
|
-
const remainingMs = deadlineAt -
|
|
3150
|
+
const remainingMs = deadlineAt - this.timerProvider.now();
|
|
3113
3151
|
if (remainingMs <= 0) {
|
|
3114
3152
|
if (!this.isDiagnosticPullSupported() && snapshot.publishGeneration === 0) {
|
|
3115
3153
|
const cached = this.documents.getPullCache(snapshot);
|
|
@@ -3269,6 +3307,8 @@ function awaitWithSignal(promise, signal) {
|
|
|
3269
3307
|
class LspManager {
|
|
3270
3308
|
constructor(options = {}) {
|
|
3271
3309
|
this.clients = new Map;
|
|
3310
|
+
this.pendingStops = new Map;
|
|
3311
|
+
this.respawnBudgets = new Map;
|
|
3272
3312
|
this.reaperHandle = null;
|
|
3273
3313
|
this.signalDisposer = null;
|
|
3274
3314
|
this.disposed = false;
|
|
@@ -3294,17 +3334,52 @@ class LspManager {
|
|
|
3294
3334
|
getKey(root, serverId) {
|
|
3295
3335
|
return `${root}::${serverId}`;
|
|
3296
3336
|
}
|
|
3337
|
+
tombstoneStop(key, client) {
|
|
3338
|
+
const stop = stopClientBestEffort(client);
|
|
3339
|
+
this.pendingStops.set(key, stop);
|
|
3340
|
+
stop.finally(() => {
|
|
3341
|
+
if (this.pendingStops.get(key) === stop) {
|
|
3342
|
+
this.pendingStops.delete(key);
|
|
3343
|
+
}
|
|
3344
|
+
});
|
|
3345
|
+
return stop;
|
|
3346
|
+
}
|
|
3347
|
+
recordDeadGeneration(key) {
|
|
3348
|
+
let budget = this.respawnBudgets.get(key);
|
|
3349
|
+
if (budget === undefined) {
|
|
3350
|
+
budget = { deadGenerations: 0, exhaustedAt: null };
|
|
3351
|
+
this.respawnBudgets.set(key, budget);
|
|
3352
|
+
}
|
|
3353
|
+
budget.deadGenerations += 1;
|
|
3354
|
+
}
|
|
3355
|
+
markHealthyGeneration(key) {
|
|
3356
|
+
this.respawnBudgets.delete(key);
|
|
3357
|
+
}
|
|
3358
|
+
ensureRespawnAllowed(key, root, serverId) {
|
|
3359
|
+
const budget = this.respawnBudgets.get(key);
|
|
3360
|
+
if (budget === undefined || budget.deadGenerations < CLIENT_RESPAWN_RETRY_LIMIT)
|
|
3361
|
+
return;
|
|
3362
|
+
if (budget.exhaustedAt === null) {
|
|
3363
|
+
budget.exhaustedAt = this.now();
|
|
3364
|
+
throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
|
|
3365
|
+
}
|
|
3366
|
+
if (this.now() - budget.exhaustedAt < CLIENT_RESPAWN_COOLDOWN_MS) {
|
|
3367
|
+
throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
|
|
3368
|
+
}
|
|
3369
|
+
budget.deadGenerations = 0;
|
|
3370
|
+
budget.exhaustedAt = null;
|
|
3371
|
+
}
|
|
3297
3372
|
reapStale() {
|
|
3298
3373
|
const t = this.now();
|
|
3299
3374
|
for (const [key, managed] of this.clients) {
|
|
3300
3375
|
if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
|
|
3301
|
-
stopClientBestEffort(managed.client);
|
|
3302
3376
|
this.clients.delete(key);
|
|
3377
|
+
this.tombstoneStop(key, managed.client);
|
|
3303
3378
|
continue;
|
|
3304
3379
|
}
|
|
3305
3380
|
if (!managed.isInitializing && managed.refCount === 0 && managed.pendingWaiters === 0 && t - managed.lastUsedAt > this.idleTimeoutMs) {
|
|
3306
|
-
stopClientBestEffort(managed.client);
|
|
3307
3381
|
this.clients.delete(key);
|
|
3382
|
+
this.tombstoneStop(key, managed.client);
|
|
3308
3383
|
}
|
|
3309
3384
|
}
|
|
3310
3385
|
}
|
|
@@ -3314,7 +3389,7 @@ class LspManager {
|
|
|
3314
3389
|
if (!victim)
|
|
3315
3390
|
return;
|
|
3316
3391
|
this.clients.delete(victim.key);
|
|
3317
|
-
|
|
3392
|
+
this.tombstoneStop(victim.key, victim.managed.client);
|
|
3318
3393
|
}
|
|
3319
3394
|
}
|
|
3320
3395
|
leastRecentlyUsedIdleClient() {
|
|
@@ -3331,7 +3406,7 @@ class LspManager {
|
|
|
3331
3406
|
async tryDeleteIfOrphaned(key, managed) {
|
|
3332
3407
|
if (managed.refCount === 0 && managed.pendingWaiters === 0 && !managed.isInitializing && this.clients.get(key) === managed) {
|
|
3333
3408
|
this.clients.delete(key);
|
|
3334
|
-
await
|
|
3409
|
+
await this.tombstoneStop(key, managed.client);
|
|
3335
3410
|
}
|
|
3336
3411
|
}
|
|
3337
3412
|
async getClient(root, server2, signal) {
|
|
@@ -3340,12 +3415,22 @@ class LspManager {
|
|
|
3340
3415
|
}
|
|
3341
3416
|
signal?.throwIfAborted();
|
|
3342
3417
|
const key = this.getKey(root, server2.id);
|
|
3418
|
+
for (;; ) {
|
|
3419
|
+
const pendingStop = this.pendingStops.get(key);
|
|
3420
|
+
if (pendingStop === undefined)
|
|
3421
|
+
break;
|
|
3422
|
+
await awaitWithSignal(pendingStop, signal);
|
|
3423
|
+
signal?.throwIfAborted();
|
|
3424
|
+
}
|
|
3425
|
+
if (this.disposed) {
|
|
3426
|
+
throw new Error("LspManager has been disposed");
|
|
3427
|
+
}
|
|
3343
3428
|
let managed = this.clients.get(key);
|
|
3344
3429
|
if (managed) {
|
|
3345
3430
|
const t = this.now();
|
|
3346
3431
|
if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
|
|
3347
|
-
await stopClientBestEffort(managed.client);
|
|
3348
3432
|
this.clients.delete(key);
|
|
3433
|
+
await this.tombstoneStop(key, managed.client);
|
|
3349
3434
|
managed = undefined;
|
|
3350
3435
|
}
|
|
3351
3436
|
}
|
|
@@ -3366,15 +3451,20 @@ class LspManager {
|
|
|
3366
3451
|
signal.throwIfAborted();
|
|
3367
3452
|
}
|
|
3368
3453
|
if (!managed.client.isAlive()) {
|
|
3369
|
-
|
|
3370
|
-
this.clients.
|
|
3454
|
+
this.recordDeadGeneration(key);
|
|
3455
|
+
if (this.clients.get(key) === managed) {
|
|
3456
|
+
this.clients.delete(key);
|
|
3457
|
+
}
|
|
3458
|
+
await this.tombstoneStop(key, managed.client);
|
|
3371
3459
|
return this.getClient(root, server2, signal);
|
|
3372
3460
|
}
|
|
3461
|
+
this.markHealthyGeneration(key);
|
|
3373
3462
|
managed.refCount++;
|
|
3374
3463
|
managed.lastUsedAt = this.now();
|
|
3375
3464
|
return managed.client;
|
|
3376
3465
|
}
|
|
3377
3466
|
this.evictForAdmission();
|
|
3467
|
+
this.ensureRespawnAllowed(key, root, server2.id);
|
|
3378
3468
|
const client = this.clientFactory(root, server2);
|
|
3379
3469
|
const initStartedAt = this.now();
|
|
3380
3470
|
const initPromise = (async () => {
|
|
@@ -3398,7 +3488,7 @@ class LspManager {
|
|
|
3398
3488
|
if (this.clients.get(key) === newManaged) {
|
|
3399
3489
|
this.clients.delete(key);
|
|
3400
3490
|
}
|
|
3401
|
-
await
|
|
3491
|
+
await this.tombstoneStop(key, client);
|
|
3402
3492
|
throw err;
|
|
3403
3493
|
}
|
|
3404
3494
|
newManaged.pendingWaiters--;
|
|
@@ -3409,6 +3499,15 @@ class LspManager {
|
|
|
3409
3499
|
await this.tryDeleteIfOrphaned(key, newManaged);
|
|
3410
3500
|
signal.throwIfAborted();
|
|
3411
3501
|
}
|
|
3502
|
+
if (!client.isAlive()) {
|
|
3503
|
+
this.recordDeadGeneration(key);
|
|
3504
|
+
if (this.clients.get(key) === newManaged) {
|
|
3505
|
+
this.clients.delete(key);
|
|
3506
|
+
}
|
|
3507
|
+
await this.tombstoneStop(key, client);
|
|
3508
|
+
return this.getClient(root, server2, signal);
|
|
3509
|
+
}
|
|
3510
|
+
this.markHealthyGeneration(key);
|
|
3412
3511
|
newManaged.refCount++;
|
|
3413
3512
|
newManaged.lastUsedAt = this.now();
|
|
3414
3513
|
return client;
|
|
@@ -3429,15 +3528,20 @@ class LspManager {
|
|
|
3429
3528
|
if (client && managed.client !== client)
|
|
3430
3529
|
return;
|
|
3431
3530
|
this.clients.delete(key);
|
|
3432
|
-
|
|
3531
|
+
this.tombstoneStop(key, managed.client);
|
|
3433
3532
|
}
|
|
3434
3533
|
warmupClient(root, server2) {
|
|
3435
3534
|
if (this.disposed)
|
|
3436
3535
|
return;
|
|
3437
3536
|
const key = this.getKey(root, server2.id);
|
|
3438
|
-
if (this.clients.has(key))
|
|
3537
|
+
if (this.clients.has(key) || this.pendingStops.has(key))
|
|
3439
3538
|
return;
|
|
3440
3539
|
this.evictForAdmission();
|
|
3540
|
+
try {
|
|
3541
|
+
this.ensureRespawnAllowed(key, root, server2.id);
|
|
3542
|
+
} catch {
|
|
3543
|
+
return;
|
|
3544
|
+
}
|
|
3441
3545
|
const client = this.clientFactory(root, server2);
|
|
3442
3546
|
const initStartedAt = this.now();
|
|
3443
3547
|
const initPromise = (async () => {
|
|
@@ -3463,7 +3567,7 @@ class LspManager {
|
|
|
3463
3567
|
if (this.clients.get(key) === managed) {
|
|
3464
3568
|
this.clients.delete(key);
|
|
3465
3569
|
}
|
|
3466
|
-
|
|
3570
|
+
this.tombstoneStop(key, client);
|
|
3467
3571
|
});
|
|
3468
3572
|
}
|
|
3469
3573
|
isServerInitializing(root, serverId) {
|
|
@@ -3507,8 +3611,11 @@ class LspManager {
|
|
|
3507
3611
|
for (const managed of this.clients.values()) {
|
|
3508
3612
|
stopPromises.push(stopClientBestEffort(managed.client));
|
|
3509
3613
|
}
|
|
3614
|
+
const tombstonedStops = [...this.pendingStops.values()];
|
|
3510
3615
|
this.clients.clear();
|
|
3511
|
-
|
|
3616
|
+
this.respawnBudgets.clear();
|
|
3617
|
+
await Promise.allSettled([...stopPromises, ...tombstonedStops]);
|
|
3618
|
+
this.pendingStops.clear();
|
|
3512
3619
|
}
|
|
3513
3620
|
}
|
|
3514
3621
|
var _defaultInstance = null;
|
|
@@ -3531,7 +3638,16 @@ import { existsSync as existsSync6, realpathSync as realpathSync4 } from "node:f
|
|
|
3531
3638
|
import { dirname as dirname5, join as join3 } from "node:path";
|
|
3532
3639
|
|
|
3533
3640
|
// ../lsp-core/src/lsp/workspace-markers.ts
|
|
3534
|
-
var
|
|
3641
|
+
var GIT_WORKSPACE_MARKER = ".git";
|
|
3642
|
+
var PROJECT_WORKSPACE_MARKERS = [
|
|
3643
|
+
"package.json",
|
|
3644
|
+
"pyproject.toml",
|
|
3645
|
+
"Cargo.toml",
|
|
3646
|
+
"go.mod",
|
|
3647
|
+
"pom.xml",
|
|
3648
|
+
"build.gradle"
|
|
3649
|
+
];
|
|
3650
|
+
var WORKSPACE_MARKERS = [GIT_WORKSPACE_MARKER, ...PROJECT_WORKSPACE_MARKERS];
|
|
3535
3651
|
|
|
3536
3652
|
// ../lsp-core/src/lsp/outside-context-workspace.ts
|
|
3537
3653
|
function findWorkspaceRootOutsideContext(directory) {
|
|
@@ -4220,20 +4336,25 @@ function findWorkspaceRoot(filePath) {
|
|
|
4220
4336
|
if (!isPathInside(cwd, abs))
|
|
4221
4337
|
return findWorkspaceRootOutsideContext(dir);
|
|
4222
4338
|
const fallbackRoot = nearestExistingDirectoryInsideContext(dir, cwd) ?? cwd;
|
|
4339
|
+
let nearestPackageRoot;
|
|
4223
4340
|
while (isPathInside(cwd, dir)) {
|
|
4224
4341
|
const canonicalDir = existingDirectoryInsideContext(dir, cwd);
|
|
4225
4342
|
if (canonicalDir !== undefined) {
|
|
4226
|
-
|
|
4227
|
-
|
|
4228
|
-
|
|
4229
|
-
|
|
4343
|
+
if (existsSync10(join5(dir, GIT_WORKSPACE_MARKER))) {
|
|
4344
|
+
return canonicalDir;
|
|
4345
|
+
}
|
|
4346
|
+
if (nearestPackageRoot === undefined && hasProjectWorkspaceMarker(dir)) {
|
|
4347
|
+
nearestPackageRoot = canonicalDir;
|
|
4230
4348
|
}
|
|
4231
4349
|
}
|
|
4232
4350
|
if (dir === cwd)
|
|
4233
4351
|
break;
|
|
4234
4352
|
dir = dirname8(dir);
|
|
4235
4353
|
}
|
|
4236
|
-
return fallbackRoot;
|
|
4354
|
+
return nearestPackageRoot ?? fallbackRoot;
|
|
4355
|
+
}
|
|
4356
|
+
function hasProjectWorkspaceMarker(directory) {
|
|
4357
|
+
return PROJECT_WORKSPACE_MARKERS.some((marker) => existsSync10(join5(directory, marker)));
|
|
4237
4358
|
}
|
|
4238
4359
|
function resolveReadablePathInsideContext(filePath) {
|
|
4239
4360
|
const cwd = contextCwd();
|