oh-my-opencode 5.0.0-beta.5 → 5.0.0-beta.51
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/.agents/command/publish.md +44 -16
- package/.agents/skills/codex-qa/scripts/lsp-e2e.sh +1 -3
- package/.agents/skills/opencode-qa/scripts/lsp-e2e.sh +1 -1
- package/.agents/skills/pre-publish-review/SKILL.md +9 -12
- package/.agents/skills/publish/SKILL.md +44 -16
- package/.agents/skills/senpi-qa/SKILL.md +80 -0
- package/.agents/skills/senpi-qa/scripts/resolve-evidence-dir.mjs +65 -0
- package/.agents/skills/senpi-qa/scripts/resolve-evidence-dir.test.mjs +171 -0
- package/.agents/skills/tech-debt-audit/SKILL.md +6 -76
- package/.agents/skills/work-with-pr/SKILL.md +37 -23
- package/.opencode/command/publish.md +44 -16
- package/.opencode/skills/pre-publish-review/SKILL.md +9 -12
- package/.opencode/skills/work-with-pr/SKILL.md +37 -23
- package/README.ja.md +58 -46
- package/README.ko.md +60 -48
- package/README.md +58 -58
- package/README.ru.md +55 -46
- package/README.zh-cn.md +54 -46
- package/THIRD-PARTY-NOTICES.md +27 -99
- package/dist/agents/atlas/agent.d.ts +0 -1
- package/dist/agents/gpt-prompt-identity.d.ts +1 -1
- package/dist/agents/sisyphus/grok-4.d.ts +20 -0
- package/dist/agents/sisyphus/index.d.ts +2 -0
- package/dist/agents/sisyphus-agent-config.d.ts +6 -0
- package/dist/agents/sisyphus-agent-factory.d.ts +1 -1
- package/dist/agents/sisyphus-runtime-prompt-reconciler.d.ts +15 -4
- package/dist/agents/types.d.ts +4 -2
- package/dist/cli/config-manager/parse-opencode-config-file.d.ts +2 -1
- package/dist/cli/doctor/checks/system-plugin.d.ts +4 -3
- package/dist/cli/fallback-lane-policy.d.ts +1 -0
- package/dist/cli/index.js +51551 -59608
- package/dist/cli/install-codex/install-codex-test-fixtures.d.ts +1 -1
- package/dist/cli/run/on-complete-hook.d.ts +2 -0
- package/dist/cli/runtime-commands.d.ts +1 -1
- package/dist/cli/worktree-sweep/classify.d.ts +16 -0
- package/dist/cli/worktree-sweep/format.d.ts +8 -0
- package/dist/cli/worktree-sweep/git.d.ts +19 -0
- package/dist/cli/worktree-sweep/index.d.ts +7 -0
- package/dist/cli/worktree-sweep/options.d.ts +2 -0
- package/dist/cli/worktree-sweep/parse-worktree-list.d.ts +8 -0
- package/dist/cli/worktree-sweep/sweep.d.ts +2 -0
- package/dist/cli/worktree-sweep/types.d.ts +65 -0
- package/dist/cli/worktree-sweep/worktree-sweep.d.ts +2 -0
- package/dist/cli-node/index.js +51569 -59603
- package/dist/config/index.d.ts +1 -1
- package/dist/config/schema/background-task.d.ts +1 -0
- package/dist/config/schema/commands.d.ts +1 -1
- package/dist/config/schema/hooks.d.ts +1 -2
- package/dist/config/schema/oh-my-opencode-config.d.ts +5 -11
- package/dist/config/schema/ulw-execute.d.ts +5 -0
- package/dist/config/schema.d.ts +0 -1
- package/dist/config/validate.d.ts +2 -0
- package/dist/create-hooks.d.ts +3 -2
- package/dist/features/background-agent/compaction-aware-message-resolver.d.ts +1 -0
- package/dist/features/background-agent/constants.d.ts +0 -7
- package/dist/features/background-agent/error-classifier.d.ts +1 -0
- 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/btw-side/btw-command-draft.d.ts +7 -0
- package/dist/features/btw-side/context-injector.d.ts +15 -0
- package/dist/features/btw-side/index.d.ts +8 -0
- package/dist/features/btw-side/metadata.d.ts +15 -0
- package/dist/features/btw-side/parent-context-budget.d.ts +9 -0
- package/dist/features/btw-side/server-session-registry.d.ts +8 -0
- package/dist/features/btw-side/tui-adoption-cache.d.ts +13 -0
- package/dist/features/btw-side/tui-adoption-guard.d.ts +5 -0
- package/dist/features/btw-side/tui-controller-types.d.ts +68 -0
- package/dist/features/btw-side/tui-controller.d.ts +19 -0
- package/dist/features/btw-side/tui-escape-return.d.ts +12 -0
- package/dist/features/btw-side/tui-keymap.d.ts +17 -0
- package/dist/features/btw-side/tui-parent-validator.d.ts +6 -0
- package/dist/features/btw-side/tui-picker-options.d.ts +20 -0
- package/dist/features/btw-side/tui-picker.d.ts +9 -0
- package/dist/features/btw-side/tui-prompt-queue.d.ts +8 -0
- package/dist/features/btw-side/tui-session-bridge.d.ts +11 -0
- package/dist/features/btw-side/tui-session-catalog.d.ts +35 -0
- package/dist/features/btw-side/tui-side-removal.d.ts +11 -0
- package/dist/features/btw-side/tui-side-start.d.ts +9 -0
- package/dist/features/btw-side/tui-wiring.d.ts +8 -0
- package/dist/features/builtin-commands/templates/ulw-execute.d.ts +1 -0
- package/dist/features/builtin-commands/types.d.ts +1 -1
- package/dist/features/monitor/manager-internals.d.ts +1 -1
- package/dist/features/monitor/output-injector-types.d.ts +1 -1
- package/dist/features/opengateway-provider/index.d.ts +13 -0
- package/dist/features/task-toast-manager/manager.d.ts +0 -24
- package/dist/features/team-mode/tools/messaging-fallback-wake.d.ts +17 -0
- package/dist/features/team-mode/tools/messaging-live-delivery-recipient.d.ts +3 -0
- package/dist/features/team-mode/tools/messaging-runtime.d.ts +7 -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/atlas/atlas-hook.d.ts +1 -0
- package/dist/hooks/atlas/atlas-lifecycle-store.d.ts +50 -0
- package/dist/hooks/atlas/event-handler.d.ts +1 -0
- package/dist/hooks/atlas/final-wave-approval-gate.test-support.d.ts +50 -0
- package/dist/hooks/atlas/system-reminder-templates.d.ts +0 -1
- package/dist/hooks/atlas/tool-execute-before.d.ts +3 -0
- package/dist/hooks/atlas/types.d.ts +1 -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/compaction-context-injector/validated-model.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/index.d.ts +1 -2
- 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/hooks/prometheus-md-only/agent-resolution.d.ts +2 -2
- package/dist/hooks/runtime-fallback/chat-message-handler.d.ts +2 -0
- package/dist/hooks/runtime-fallback/retry-model-payload.d.ts +1 -0
- package/dist/hooks/runtime-fallback/runtime-model-settings.d.ts +6 -0
- package/dist/hooks/runtime-fallback/session-status-handler.d.ts +1 -1
- package/dist/hooks/runtime-fallback/types.d.ts +3 -1
- package/dist/hooks/sisyphus-junior-notepad/constants.d.ts +1 -1
- package/dist/hooks/todo-continuation-enforcer/types.d.ts +1 -0
- package/dist/hooks/{start-work → ulw-execute}/context-info-builder.d.ts +1 -1
- package/dist/hooks/{start-work → ulw-execute}/index.d.ts +1 -1
- package/dist/hooks/ulw-execute/ulw-execute-hook.d.ts +23 -0
- package/dist/index.js +28955 -25346
- package/dist/mcp/index.d.ts +0 -4
- package/dist/mcp/types.d.ts +0 -1
- package/dist/oh-my-opencode.schema.json +21 -47
- package/dist/plugin/chat-message/types.d.ts +3 -3
- package/dist/plugin/chat-message/ulw-execute-message.d.ts +5 -0
- package/dist/plugin/event-session-lifecycle.d.ts +1 -0
- package/dist/plugin/hooks/create-core-hooks.d.ts +2 -2
- package/dist/plugin/hooks/create-session-hooks.d.ts +2 -3
- package/dist/plugin/hooks/create-transform-hooks.d.ts +2 -0
- package/dist/plugin/messages-transform.d.ts +1 -0
- package/dist/plugin-dispose.d.ts +3 -0
- package/dist/shared/agent-tool-restrictions.d.ts +0 -1
- package/dist/shared/compaction-agent-config-checkpoint.d.ts +1 -0
- package/dist/shared/index.d.ts +2 -0
- package/dist/shared/legacy-plugin-warning.d.ts +2 -1
- package/dist/shared/normalize-sdk-response.d.ts +1 -0
- package/dist/shared/omo-process-sweep.d.ts +2 -4
- package/dist/shared/plugin-entry-migrator.d.ts +4 -3
- package/dist/shared/plugin-entry-shape.d.ts +6 -0
- package/dist/shared/runtime-fallback-retry-marker.d.ts +16 -0
- package/dist/shared/shell-env.d.ts +1 -1
- package/dist/skills/ast-grep/AGENTS.md +51 -0
- package/dist/skills/ast-grep/SKILL.md +1 -1
- package/dist/skills/coding-agent-sessions/AGENTS.md +62 -0
- package/dist/skills/coding-agent-sessions/SKILL.md +3 -2
- package/dist/skills/coding-agent-sessions/references/all-platforms.md +1 -1
- package/dist/skills/coding-agent-sessions/references/senpi.md +4 -4
- package/dist/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +1 -1
- package/dist/skills/data-scientist/SKILL.md +99 -239
- package/dist/skills/data-scientist/references/execution-surfaces.md +91 -0
- package/dist/skills/data-scientist/references/placement.md +74 -0
- package/dist/skills/data-scientist/references/polars-lane.md +95 -0
- package/dist/skills/data-scientist/references/uv-setup.md +1 -1
- package/dist/skills/data-scientist/references/visualization.md +64 -0
- package/dist/skills/data-scientist/scripts/ensure-js-deps.sh +28 -0
- package/dist/skills/data-scientist/scripts/ensure-py-deps.sh +37 -0
- package/dist/skills/debugging/SKILL.md +3 -1
- package/dist/skills/debugging/references/methodology/00-setup.md +12 -0
- package/dist/skills/debugging/references/methodology/02-investigate.md +21 -0
- package/dist/skills/debugging/references/runtimes/go.md +15 -1
- package/dist/skills/debugging/references/runtimes/native-binary.md +38 -0
- package/dist/skills/debugging/references/runtimes/node.md +25 -0
- package/dist/skills/debugging/references/runtimes/python.md +13 -0
- package/dist/skills/debugging/references/runtimes/rust.md +41 -0
- package/dist/skills/debugging/references/scripts/dap.mjs +267 -0
- package/dist/skills/debugging/references/scripts/dap.test.ts +86 -0
- package/dist/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
- package/dist/skills/debugging/references/tools/dap.md +103 -0
- package/dist/skills/debugging/references/tools/frida.md +193 -0
- package/dist/skills/frontend/SKILL.md +12 -8
- package/dist/skills/frontend/references/design/_INDEX.md +1 -0
- package/dist/skills/frontend/references/design/print-paged-media.md +76 -0
- package/dist/skills/frontend/references/design/stylegallery.md +80 -0
- package/dist/skills/frontend/references/designpowers/README.md +1 -1
- package/dist/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
- package/dist/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
- package/dist/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
- package/dist/skills/frontend/references/designpowers/orchestration.md +1 -1
- package/dist/skills/frontend/references/designpowers/routing.md +5 -5
- package/dist/skills/git-master/SKILL.md +1 -1
- package/dist/skills/init-deep/SKILL.md +14 -14
- package/dist/skills/lsp-setup/SKILL.md +1 -1
- package/dist/skills/programming/SKILL.md +1 -1
- package/dist/skills/refactor/SKILL.md +1 -1
- package/dist/skills/remove-ai-slops/SKILL.md +1 -1
- package/dist/skills/review-work/SKILL.md +100 -418
- package/dist/skills/ultimate-browsing/ATTRIBUTION.md +38 -11
- package/dist/skills/ultimate-browsing/SKILL.md +26 -9
- package/dist/skills/ultimate-browsing/engine/AGENTS.md +110 -0
- package/dist/skills/ultimate-browsing/engine/templates/package.json +1 -1
- package/dist/skills/ultimate-browsing/references/chrome-stealth.md +23 -18
- package/dist/skills/ultimate-browsing/references/insane-search/README.md +9 -2
- package/dist/skills/{start-work → ulw-execute}/SKILL.md +17 -16
- package/dist/skills/ulw-plan/SKILL.md +7 -8
- package/dist/skills/ulw-plan/references/full-workflow.md +31 -7
- package/dist/skills/ulw-plan/references/intent-clear.md +2 -1
- package/dist/skills/ulw-plan/references/intent-unclear.md +5 -5
- package/dist/skills/ulw-research/SKILL.md +8 -3
- package/dist/skills/visual-qa/AGENTS.md +58 -0
- package/dist/skills/visual-qa/SKILL.md +4 -3
- package/dist/tools/delegate-task/builtin-categories.d.ts +3 -1
- package/dist/tools/delegate-task/builtin-category-definition.d.ts +2 -1
- package/dist/tools/delegate-task/constants.d.ts +2 -2
- package/dist/tools/delegate-task/openai-categories.d.ts +7 -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/tool-description.d.ts +3 -1
- package/dist/tools/delegate-task/types.d.ts +4 -0
- package/dist/tools/session-manager/directory-filter.d.ts +2 -0
- package/dist/tui.d.ts +12 -0
- package/dist/tui.js +37066 -46704
- package/package.json +47 -41
- package/packages/git-bash-mcp/dist/cli.js +6 -1
- package/packages/git-bash-mcp/package.json +1 -1
- package/packages/lsp-core/src/index.ts +1 -0
- package/packages/lsp-core/src/lsp/client-diagnostics-concurrency.integration.test.ts +44 -0
- package/packages/lsp-core/src/lsp/client-diagnostics-freshness.integration.test.ts +57 -48
- package/packages/lsp-core/src/lsp/client-diagnostics-pull-timeout.test.ts +64 -0
- package/packages/lsp-core/src/lsp/client-wrapper-outside-cwd.test.ts +78 -0
- package/packages/lsp-core/src/lsp/client-wrapper.test.ts +163 -13
- package/packages/lsp-core/src/lsp/client-wrapper.ts +110 -23
- package/packages/lsp-core/src/lsp/client.ts +32 -3
- package/packages/lsp-core/src/lsp/connection.ts +16 -0
- package/packages/lsp-core/src/lsp/constants.ts +6 -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/format-document.test.ts +143 -0
- package/packages/lsp-core/src/lsp/format-document.ts +90 -0
- package/packages/lsp-core/src/lsp/json-rpc-connection.ts +11 -6
- package/packages/lsp-core/src/lsp/manager-lifecycle.test.ts +262 -0
- package/packages/lsp-core/src/lsp/manager-max-clients.test.ts +151 -0
- package/packages/lsp-core/src/lsp/manager.ts +138 -12
- package/packages/lsp-core/src/lsp/outside-context-workspace.ts +33 -0
- package/packages/lsp-core/src/lsp/server-definitions.ts +29 -0
- package/packages/lsp-core/src/lsp/server-installation.test.ts +376 -0
- package/packages/lsp-core/src/lsp/server-installation.ts +200 -27
- package/packages/lsp-core/src/lsp/server-resolution-local-binary.test.ts +170 -0
- package/packages/lsp-core/src/lsp/server-resolution.ts +18 -5
- 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 +16 -2
- package/packages/lsp-core/src/lsp/types.ts +8 -0
- package/packages/lsp-core/src/lsp/workspace-apply-edit-test-support.ts +29 -1
- 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-edit-adversarial.test.ts +20 -1
- package/packages/lsp-core/src/lsp/workspace-markers.ts +18 -0
- package/packages/lsp-core/src/mcp.ts +3 -0
- package/packages/lsp-core/src/request-context.test.ts +29 -0
- package/packages/lsp-core/src/request-context.ts +1 -1
- package/packages/lsp-core/src/tool-surface.test.ts +13 -1
- package/packages/lsp-core/src/tools/definitions.ts +14 -0
- package/packages/lsp-core/src/tools/diagnostics.ts +3 -3
- package/packages/lsp-core/src/tools/format.test.ts +56 -0
- package/packages/lsp-core/src/tools/format.ts +56 -0
- package/packages/lsp-core/src/tools/index.ts +1 -0
- package/packages/lsp-core/src/tools/navigation.ts +4 -2
- package/packages/lsp-core/src/tools/parameters.test.ts +51 -0
- package/packages/lsp-core/src/tools/rename.ts +4 -2
- package/packages/lsp-core/src/tools/symbols.ts +1 -1
- package/packages/lsp-core/src/tools/types.ts +10 -0
- package/packages/lsp-daemon/dist/cli.js +961 -483
- package/packages/lsp-daemon/dist/client.d.ts +10 -0
- package/packages/lsp-daemon/dist/client.js +976 -495
- package/packages/lsp-daemon/dist/daemon-client.d.ts +1 -0
- package/packages/lsp-daemon/dist/daemon-client.js +3 -0
- package/packages/lsp-daemon/dist/ensure-daemon.d.ts +6 -1
- package/packages/lsp-daemon/dist/ensure-daemon.js +10 -2
- package/packages/lsp-daemon/dist/index.js +881 -405
- package/packages/lsp-daemon/dist/proxy.js +3 -0
- package/packages/lsp-daemon/dist/version-reap.js +1 -1
- package/packages/lsp-daemon/package.json +1 -1
- package/packages/lsp-tools-mcp/dist/cli.js +820 -345
- package/packages/lsp-tools-mcp/dist/lsp/manager.js +272 -138
- package/packages/lsp-tools-mcp/dist/mcp.js +845 -372
- package/packages/lsp-tools-mcp/dist/request-context.js +12 -13
- package/packages/lsp-tools-mcp/dist/tools.js +775 -306
- package/packages/lsp-tools-mcp/package.json +1 -1
- package/packages/omo-codex/THIRD-PARTY-NOTICES.md +4 -21
- package/packages/omo-codex/plugin/.codex-plugin/plugin.json +4 -6
- package/packages/omo-codex/plugin/.mcp.json +0 -6
- package/packages/omo-codex/plugin/AGENTS.md +47 -0
- package/packages/omo-codex/plugin/README.md +6 -2
- package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +197 -148
- 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/bootstrap/src/hook.ts +1 -0
- package/packages/omo-codex/plugin/components/comment-checker/AGENTS.md +9 -0
- package/packages/omo-codex/plugin/components/comment-checker/biome.json +2 -2
- package/packages/omo-codex/plugin/components/comment-checker/dist/cli.js +2 -1
- package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/package.json +5 -5
- package/packages/omo-codex/plugin/components/comment-checker/src/apply-patch.ts +2 -8
- package/packages/omo-codex/plugin/components/comment-checker/src/core.ts +1 -2
- package/packages/omo-codex/plugin/components/comment-checker/src/request-extractor.ts +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/src/runner.ts +1 -0
- package/packages/omo-codex/plugin/components/git-bash/AGENTS.md +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 +3 -4
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/AGENTS.md +2 -2
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/biome.json +2 -2
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/directive.md +2 -0
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/cli.js +36 -29
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/codex-hook.js +32 -26
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/types.d.ts +3 -0
- 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 +5 -5
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/src/codex-hook.ts +32 -28
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/src/types.ts +3 -0
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/test/cli.test.ts +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/test/codex-hook.test.ts +137 -28
- package/packages/omo-codex/plugin/components/lcx/skills/lcx-doctor/SKILL.md +4 -2
- package/packages/omo-codex/plugin/components/lsp/AGENTS.md +30 -15
- package/packages/omo-codex/plugin/components/lsp/biome.json +2 -2
- package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +4 -4
- package/packages/omo-codex/plugin/components/lsp/dist/cli.js +999 -544
- package/packages/omo-codex/plugin/components/lsp/dist/daemon-cli-path.js +1 -1
- package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/lsp/package.json +5 -5
- package/packages/omo-codex/plugin/components/lsp/src/cli.ts +1 -1
- package/packages/omo-codex/plugin/components/lsp/src/codex-hook.ts +1 -1
- package/packages/omo-codex/plugin/components/lsp/src/daemon-cli-path.ts +1 -5
- package/packages/omo-codex/plugin/components/lsp/test/codex-hook-unavailable.test.ts +6 -7
- package/packages/omo-codex/plugin/components/lsp/test/codex-hook.test.ts +1 -2
- package/packages/omo-codex/plugin/components/lsp/test/package-smoke.test.ts +11 -1
- package/packages/omo-codex/plugin/components/rules/AGENTS.md +12 -0
- package/packages/omo-codex/plugin/components/rules/README.md +2 -0
- package/packages/omo-codex/plugin/components/rules/biome.json +2 -2
- package/packages/omo-codex/plugin/components/rules/bundled-rules/hephaestus/gpt-6.md +123 -0
- package/packages/omo-codex/plugin/components/rules/dist/cli.js +91 -68
- package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
- package/packages/omo-codex/plugin/components/rules/package.json +7 -7
- package/packages/omo-codex/plugin/components/rules/src/config.ts +1 -2
- package/packages/omo-codex/plugin/components/rules/src/persistent-cache.ts +1 -2
- package/packages/omo-codex/plugin/components/rules/src/post-compact-budget.ts +15 -5
- package/packages/omo-codex/plugin/components/rules/src/rules-engine-factory.ts +1 -4
- package/packages/omo-codex/plugin/components/rules/src/static-injection.ts +4 -9
- package/packages/omo-codex/plugin/components/rules/test/bundled-rules-priority.test.ts +11 -16
- package/packages/omo-codex/plugin/components/rules/test/bundled-rules.test.ts +17 -25
- package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-budget.test.ts +9 -7
- package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-context.test.ts +0 -6
- package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-dedup.test.ts +6 -4
- package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-directive.test.ts +12 -9
- package/packages/omo-codex/plugin/components/rules/test/codex-hook.test.ts +28 -37
- package/packages/omo-codex/plugin/components/rules/test/dynamic-target-fingerprints.test.ts +1 -2
- package/packages/omo-codex/plugin/components/rules/test/engine.test.ts +7 -4
- package/packages/omo-codex/plugin/components/rules/test/finder.test.ts +2 -3
- package/packages/omo-codex/plugin/components/rules/test/formatter.test.ts +39 -72
- package/packages/omo-codex/plugin/components/rules/test/hephaestus-model-variant.test.ts +38 -3
- package/packages/omo-codex/plugin/components/rules/test/hook-output.test.ts +2 -3
- package/packages/omo-codex/plugin/components/rules/test/matcher.test.ts +2 -3
- package/packages/omo-codex/plugin/components/rules/test/package-smoke.test.ts +1 -1
- package/packages/omo-codex/plugin/components/rules/test/parser.test.ts +1 -2
- package/packages/omo-codex/plugin/components/rules/test/post-compact-budget.test.ts +29 -6
- package/packages/omo-codex/plugin/components/rules/test/rules-engine-consumption.test.ts +3 -6
- package/packages/omo-codex/plugin/components/rules/test/scanner.test.ts +1 -2
- package/packages/omo-codex/plugin/components/rules/test/sources.test.ts +2 -5
- package/packages/omo-codex/plugin/components/rules/test/windows-git-bash-bundled-rule.test.ts +2 -17
- package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/package.json +5 -5
- package/packages/omo-codex/plugin/components/teammode/test/thread-title-hook.test.ts +4 -10
- package/packages/omo-codex/plugin/components/telemetry/AGENTS.md +8 -0
- package/packages/omo-codex/plugin/components/telemetry/biome.json +2 -2
- package/packages/omo-codex/plugin/components/telemetry/dist/cli.js +2435 -700
- package/packages/omo-codex/plugin/components/telemetry/dist/posthog.js +2439 -705
- package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/package.json +5 -5
- package/packages/omo-codex/plugin/components/telemetry/src/codex-hook.ts +1 -4
- package/packages/omo-codex/plugin/components/telemetry/src/posthog.ts +4 -14
- package/packages/omo-codex/plugin/components/telemetry/src/product-identity.ts +1 -1
- package/packages/omo-codex/plugin/components/telemetry/test/diagnostics.test.ts +2 -5
- package/packages/omo-codex/plugin/components/ultrawork/AGENTS.md +10 -4
- package/packages/omo-codex/plugin/components/ultrawork/README.md +2 -0
- package/packages/omo-codex/plugin/components/ultrawork/agents/explorer.toml +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-clone-fidelity-reviewer.toml +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-code-reviewer.toml +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-gate-reviewer.toml +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-qa-executor.toml +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-high.toml +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-low.toml +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-medium.toml +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/agents/librarian.toml +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/agents/metis.toml +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/agents/momus.toml +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/agents/plan.toml +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/biome.json +2 -2
- package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +490 -4
- package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/package.json +5 -6
- package/packages/omo-codex/plugin/components/ultrawork/scripts/sync-directive.mjs +30 -14
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +6 -7
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +31 -7
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-clear.md +2 -1
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-unclear.md +5 -5
- 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/codex-hook-trigger-policy.test.ts +9 -1
- package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook.test.ts +0 -136
- 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/ultrawork/test/skill-pointer.test.ts +0 -2
- package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/AGENTS.md +4 -4
- package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/NOTICE +1 -1
- package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/README.md +6 -6
- package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/biome.json +2 -2
- package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/directive.md +10 -10
- package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/dist/cli.js +16 -16
- package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +16 -0
- package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/package.json +12 -12
- package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/boulder-reader.ts +1 -1
- package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/cli.ts +1 -1
- package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/codex-hook.ts +4 -4
- package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/directive.ts +1 -1
- package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/index.ts +1 -1
- package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/types.ts +1 -1
- package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/boulder-reader.test.ts +3 -3
- package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/cli.test.ts +4 -11
- package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/codex-hook.test.ts +24 -22
- package/packages/omo-codex/plugin/components/ulw-loop/AGENTS.md +19 -0
- package/packages/omo-codex/plugin/components/ulw-loop/CHANGELOG.md +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/README.md +12 -1
- package/packages/omo-codex/plugin/components/ulw-loop/biome.json +2 -2
- package/packages/omo-codex/plugin/components/ulw-loop/directive.md +26 -13
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-codex-validation.d.ts +12 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-codex-validation.js +45 -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 +15 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-reconciliation.js +15 -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 +40 -39
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-commands.js +21 -8
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.d.ts +2 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.js +12 -1
- 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 +1270 -429
- 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 +28 -8
- 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 +15 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/constants.d.ts +1 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/constants.js +1 -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/paths.d.ts +1 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/paths.js +13 -4
- package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.d.ts +1 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.js +34 -4
- package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-missing-recovery.d.ts +14 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-missing-recovery.js +29 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-aggregate.d.ts +7 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-aggregate.js +9 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-artifacts.d.ts +12 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-artifacts.js +104 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-fields.d.ts +13 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-fields.js +65 -9
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-verdicts.js +5 -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 +72 -117
- 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.d.ts +6 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-guard.js +195 -29
- package/packages/omo-codex/plugin/components/ulw-loop/dist/state-lock.d.ts +9 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/state-lock.js +227 -0
- 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/stop-resume-hook.js +20 -6
- package/packages/omo-codex/plugin/components/ulw-loop/dist/surface.d.ts +19 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/surface.js +75 -0
- package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +17 -4
- package/packages/omo-codex/plugin/components/ulw-loop/package.json +6 -6
- package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md +6 -4
- package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/define-goal.md +108 -0
- package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +32 -8
- package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-codex-validation.ts +81 -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 +31 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-template.ts +128 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint.ts +38 -71
- package/packages/omo-codex/plugin/components/ulw-loop/src/cli-commands.ts +24 -8
- package/packages/omo-codex/plugin/components/ulw-loop/src/cli-output.ts +14 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/cli-subcommands.ts +2 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/cli.ts +8 -6
- package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-instruction.ts +35 -7
- package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-snapshot.ts +26 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/codex-hook.ts +3 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/constants.ts +1 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/domain-types.ts +19 -9
- package/packages/omo-codex/plugin/components/ulw-loop/src/paths.ts +25 -4
- package/packages/omo-codex/plugin/components/ulw-loop/src/plan-io.ts +39 -4
- package/packages/omo-codex/plugin/components/ulw-loop/src/plan-missing-recovery.ts +38 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-aggregate.ts +11 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-artifacts.ts +123 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-fields.ts +71 -15
- package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-verdicts.ts +6 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate.ts +92 -136
- 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 +205 -28
- package/packages/omo-codex/plugin/components/ulw-loop/src/state-lock.ts +239 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/status-next-actions.ts +36 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/stop-resume-hook.ts +19 -6
- package/packages/omo-codex/plugin/components/ulw-loop/src/surface.ts +107 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-continuation.test.ts +0 -1
- package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-final.test.ts +132 -1
- package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-template.test.ts +147 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/cli-checkpoint-continuation.test.ts +4 -2
- package/packages/omo-codex/plugin/components/ulw-loop/test/cli-checkpoint.test.ts +4 -2
- package/packages/omo-codex/plugin/components/ulw-loop/test/cli-commands.test.ts +2 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/cli-complete-goals.test.ts +3 -1
- package/packages/omo-codex/plugin/components/ulw-loop/test/cli-create-goals.test.ts +35 -8
- package/packages/omo-codex/plugin/components/ulw-loop/test/cli-entrypoint.test.ts +38 -4
- package/packages/omo-codex/plugin/components/ulw-loop/test/cli-json-errors.test.ts +2 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/cli-scope-required.test.ts +144 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/cli-status-next-actions.test.ts +185 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/cli-steering-batch.test.ts +8 -3
- package/packages/omo-codex/plugin/components/ulw-loop/test/cli-validation-batch.test.ts +6 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-instruction.test.ts +37 -2
- package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-snapshot.test.ts +18 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/codex-hook.test.ts +0 -3
- package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/cli-session.ts +4 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/quality-gate-builder.ts +9 -4
- package/packages/omo-codex/plugin/components/ulw-loop/test/guided-recovery.test.ts +105 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts +5 -37
- package/packages/omo-codex/plugin/components/ulw-loop/test/paths.test.ts +9 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/plan-io-cross-process.test.ts +106 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/plan-io.test.ts +36 -2
- package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-aggregate-basics.test.ts +258 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-cap-and-dedupe.test.ts +22 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-fields-messages.test.ts +98 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-lazycodex-surface.test.ts +93 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-poisoning-cascades.test.ts +97 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-roles.test.ts +51 -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-single-report.test.ts +241 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate.test.ts +58 -3
- package/packages/omo-codex/plugin/components/ulw-loop/test/spawn-guard.test.ts +444 -7
- package/packages/omo-codex/plugin/components/ulw-loop/test/state-lock.test.ts +218 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/steering.test.ts +8 -5
- package/packages/omo-codex/plugin/components/ulw-loop/test/stop-resume-hook.test.ts +1 -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 +13 -8
- package/packages/omo-codex/plugin/components/ulw-loop/vitest.config.ts +1 -0
- 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-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/post-tool-use-recording-spawn-admission.json +18 -0
- 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-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 +17 -0
- package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.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/model-catalog.json +16 -7
- package/packages/omo-codex/plugin/package-lock.json +676 -524
- package/packages/omo-codex/plugin/package.json +2 -3
- package/packages/omo-codex/plugin/scripts/AGENTS.md +39 -0
- package/packages/omo-codex/plugin/scripts/auto-update-plan.mjs +1 -2
- package/packages/omo-codex/plugin/scripts/auto-update.mjs +0 -9
- package/packages/omo-codex/plugin/scripts/canonical-ultrawork-directive.mjs +17 -0
- package/packages/omo-codex/plugin/scripts/hook-status-message.mjs +0 -1
- package/packages/omo-codex/plugin/scripts/migrate-codex-config/catalog.mjs +16 -7
- package/packages/omo-codex/plugin/scripts/migrate-codex-config/multi-agent-v2-guard.mjs +8 -4
- package/packages/omo-codex/plugin/scripts/migrate-codex-config/subagent-limit-guard.mjs +19 -90
- package/packages/omo-codex/plugin/scripts/migrate-codex-config/toml-section-editor.mjs +1 -1
- package/packages/omo-codex/plugin/scripts/sync-skills.mjs +94 -55
- package/packages/omo-codex/plugin/shared/package.json +3 -4
- package/packages/omo-codex/plugin/shared/src/config-loader.ts +2 -102
- package/packages/omo-codex/plugin/shared/src/config-migration.ts +0 -1
- package/packages/omo-codex/plugin/shared/test/config-loader.test.ts +41 -130
- package/packages/omo-codex/plugin/skills/ast-grep/AGENTS.md +51 -0
- package/packages/omo-codex/plugin/skills/ast-grep/SKILL.md +1 -1
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/AGENTS.md +62 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/SKILL.md +3 -2
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/all-platforms.md +1 -1
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/senpi.md +4 -4
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +1 -1
- package/packages/omo-codex/plugin/skills/data-scientist/SKILL.md +99 -239
- package/packages/omo-codex/plugin/skills/data-scientist/references/execution-surfaces.md +91 -0
- package/packages/omo-codex/plugin/skills/data-scientist/references/placement.md +74 -0
- package/packages/omo-codex/plugin/skills/data-scientist/references/polars-lane.md +95 -0
- package/packages/omo-codex/plugin/skills/data-scientist/references/uv-setup.md +1 -1
- package/packages/omo-codex/plugin/skills/data-scientist/references/visualization.md +64 -0
- package/packages/omo-codex/plugin/skills/data-scientist/scripts/ensure-js-deps.sh +28 -0
- package/packages/omo-codex/plugin/skills/data-scientist/scripts/ensure-py-deps.sh +37 -0
- package/packages/omo-codex/plugin/skills/debugging/SKILL.md +3 -1
- package/packages/omo-codex/plugin/skills/debugging/references/methodology/00-setup.md +12 -0
- package/packages/omo-codex/plugin/skills/debugging/references/methodology/02-investigate.md +21 -0
- package/packages/omo-codex/plugin/skills/debugging/references/runtimes/go.md +15 -1
- package/packages/omo-codex/plugin/skills/debugging/references/runtimes/native-binary.md +38 -0
- package/packages/omo-codex/plugin/skills/debugging/references/runtimes/node.md +25 -0
- package/packages/omo-codex/plugin/skills/debugging/references/runtimes/python.md +13 -0
- package/packages/omo-codex/plugin/skills/debugging/references/runtimes/rust.md +41 -0
- package/packages/omo-codex/plugin/skills/debugging/references/scripts/dap.mjs +267 -0
- package/packages/omo-codex/plugin/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
- package/packages/omo-codex/plugin/skills/debugging/references/tools/dap.md +103 -0
- package/packages/omo-codex/plugin/skills/debugging/references/tools/frida.md +193 -0
- package/packages/omo-codex/plugin/skills/frontend/SKILL.md +12 -8
- package/packages/omo-codex/plugin/skills/frontend/references/design/_INDEX.md +1 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/print-paged-media.md +76 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/stylegallery.md +80 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/README.md +1 -1
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/orchestration.md +1 -1
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/routing.md +5 -5
- package/packages/omo-codex/plugin/skills/git-master/SKILL.md +1 -1
- package/packages/omo-codex/plugin/skills/init-deep/SKILL.md +18 -16
- package/packages/omo-codex/plugin/skills/lcx-doctor/SKILL.md +4 -2
- package/packages/omo-codex/plugin/skills/lsp-setup/SKILL.md +1 -1
- package/packages/omo-codex/plugin/skills/programming/SKILL.md +1 -1
- package/packages/omo-codex/plugin/skills/refactor/SKILL.md +5 -3
- package/packages/omo-codex/plugin/skills/remove-ai-slops/SKILL.md +5 -3
- package/packages/omo-codex/plugin/skills/review-work/SKILL.md +114 -422
- package/packages/omo-codex/plugin/skills/ultimate-browsing/ATTRIBUTION.md +38 -11
- package/packages/omo-codex/plugin/skills/ultimate-browsing/SKILL.md +26 -9
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/AGENTS.md +110 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/templates/package.json +1 -1
- package/packages/omo-codex/plugin/skills/ultimate-browsing/references/chrome-stealth.md +23 -18
- package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/README.md +9 -2
- package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +26 -13
- package/packages/omo-codex/plugin/skills/{start-work → ulw-execute}/SKILL.md +26 -28
- package/packages/omo-codex/plugin/skills/ulw-execute/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +30 -4
- package/packages/omo-codex/plugin/skills/ulw-loop/references/define-goal.md +108 -0
- package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +32 -8
- package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +6 -7
- package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +31 -7
- package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-clear.md +2 -1
- package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-unclear.md +5 -5
- package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +12 -5
- package/packages/omo-codex/plugin/skills/visual-qa/AGENTS.md +58 -0
- package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +8 -5
- package/packages/omo-codex/plugin/test/AGENTS.md +47 -0
- package/packages/omo-codex/plugin/test/aggregate-agents.test.mjs +19 -173
- package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +16 -51
- package/packages/omo-codex/plugin/test/aggregate-manifest.test.mjs +2 -3
- package/packages/omo-codex/plugin/test/aggregate-mcp.test.mjs +2 -7
- package/packages/omo-codex/plugin/test/aggregate-model-catalog.test.mjs +14 -4
- package/packages/omo-codex/plugin/test/aggregate-plugin-fixture.mjs +175 -13
- package/packages/omo-codex/plugin/test/aggregate.test.mjs +78 -2
- package/packages/omo-codex/plugin/test/auto-update-release-notes.test.mjs +19 -33
- package/packages/omo-codex/plugin/test/auto-update.test.mjs +4 -29
- package/packages/omo-codex/plugin/test/bootstrap-setup.test.mjs +0 -31
- package/packages/omo-codex/plugin/test/canonical-ultrawork-directive.test.mjs +53 -0
- package/packages/omo-codex/plugin/test/component-bin-names.test.mjs +2 -2
- package/packages/omo-codex/plugin/test/component-bundled-cli.test.mjs +1 -51
- package/packages/omo-codex/plugin/test/component-hook-contract-cases.mjs +88 -2
- package/packages/omo-codex/plugin/test/hook-status-message.test.mjs +5 -6
- package/packages/omo-codex/plugin/test/lcx-contribute-bug-fix-template.test.mjs +21 -27
- package/packages/omo-codex/plugin/test/mcp-research-servers.test.mjs +1 -3
- package/packages/omo-codex/plugin/test/migrate-codex-config.test.mjs +35 -35
- package/packages/omo-codex/plugin/test/multi-agent-v2-regression.test.mjs +1 -1
- package/packages/omo-codex/plugin/test/scaffold-plan.test.mjs +0 -36
- package/packages/omo-codex/plugin/test/subagent-limit-migration.test.mjs +107 -15
- package/packages/omo-codex/plugin/test/sync-skills-codex-compatibility.test.mjs +168 -0
- package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +54 -24
- package/packages/omo-codex/plugin/test/sync-skills.test.mjs +18 -119
- package/packages/omo-codex/plugin/test/teammode-archive-ambiguity.test.mjs +0 -40
- package/packages/omo-codex/plugin/test/teammode-communication.test.mjs +6 -62
- package/packages/omo-codex/plugin/test/teammode-thread-links.test.mjs +3 -36
- package/packages/omo-codex/plugin/test/teammode-transport.test.mjs +0 -44
- package/packages/omo-codex/plugin/test/teammode-worktree.test.mjs +2 -6
- package/packages/omo-codex/plugin/test/ultrawork-skill-pointer.test.mjs +5 -5
- package/packages/omo-codex/plugin/test/ulw-plan-review-state-contract.test.mjs +0 -3
- package/packages/omo-codex/scripts/AGENTS.md +36 -0
- package/packages/omo-codex/scripts/check-model-catalog-parity.mjs +42 -0
- package/packages/omo-codex/scripts/install-cache-copy.test.mjs +27 -1
- package/packages/omo-codex/scripts/install-config-autonomous-features.test.mjs +1 -1
- package/packages/omo-codex/scripts/install-config-autonomous.test.mjs +2 -1
- package/packages/omo-codex/scripts/install-config-git-bash.test.mjs +0 -23
- package/packages/omo-codex/scripts/install-config-reasoning.test.mjs +5 -5
- package/packages/omo-codex/scripts/install-config.test.mjs +15 -17
- package/packages/omo-codex/scripts/install-dist/install-local.mjs +3035 -1395
- package/packages/omo-codex/scripts/install-generated-bundle.test.mjs +3 -4
- package/packages/omo-codex/scripts/install-git-bash-mcp-env.test.mjs +1 -25
- package/packages/omo-codex/scripts/install-lazycodex-version-stamp.test.mjs +7 -2
- package/packages/omo-codex/scripts/install-mcp-runtime.test.mjs +0 -36
- package/packages/omo-codex/scripts/install-packaged-local.test.mjs +1 -6
- package/packages/{omo-codex/plugin/components/ultrawork/skills/ultrawork/SKILL.md → prompts-core/prompts/ultrawork/codex.md} +26 -20
- package/packages/shared-skills/package.json +7 -1
- package/packages/shared-skills/skill-source-filter.d.ts +16 -0
- package/packages/shared-skills/skill-source-filter.mjs +44 -0
- package/packages/shared-skills/skills/ast-grep/AGENTS.md +51 -0
- package/packages/shared-skills/skills/ast-grep/SKILL.md +1 -1
- package/packages/shared-skills/skills/coding-agent-sessions/AGENTS.md +62 -0
- package/packages/shared-skills/skills/coding-agent-sessions/SKILL.md +3 -2
- package/packages/shared-skills/skills/coding-agent-sessions/references/all-platforms.md +1 -1
- package/packages/shared-skills/skills/coding-agent-sessions/references/senpi.md +4 -4
- package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +1 -1
- package/packages/shared-skills/skills/data-scientist/SKILL.md +99 -239
- package/packages/shared-skills/skills/data-scientist/references/execution-surfaces.md +91 -0
- package/packages/shared-skills/skills/data-scientist/references/placement.md +74 -0
- package/packages/shared-skills/skills/data-scientist/references/polars-lane.md +95 -0
- package/packages/shared-skills/skills/data-scientist/references/uv-setup.md +1 -1
- package/packages/shared-skills/skills/data-scientist/references/visualization.md +64 -0
- package/packages/shared-skills/skills/data-scientist/scripts/ensure-js-deps.sh +28 -0
- package/packages/shared-skills/skills/data-scientist/scripts/ensure-py-deps.sh +37 -0
- package/packages/shared-skills/skills/debugging/SKILL.md +3 -1
- package/packages/shared-skills/skills/debugging/references/methodology/00-setup.md +12 -0
- package/packages/shared-skills/skills/debugging/references/methodology/02-investigate.md +21 -0
- package/packages/shared-skills/skills/debugging/references/runtimes/go.md +15 -1
- package/packages/shared-skills/skills/debugging/references/runtimes/native-binary.md +38 -0
- package/packages/shared-skills/skills/debugging/references/runtimes/node.md +25 -0
- package/packages/shared-skills/skills/debugging/references/runtimes/python.md +13 -0
- package/packages/shared-skills/skills/debugging/references/runtimes/rust.md +41 -0
- package/packages/shared-skills/skills/debugging/references/scripts/dap.mjs +267 -0
- package/packages/shared-skills/skills/debugging/references/scripts/dap.test.ts +86 -0
- package/packages/shared-skills/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
- package/packages/shared-skills/skills/debugging/references/tools/dap.md +103 -0
- package/packages/shared-skills/skills/debugging/references/tools/frida.md +193 -0
- package/packages/shared-skills/skills/frontend/SKILL.md +12 -8
- package/packages/shared-skills/skills/frontend/references/design/_INDEX.md +1 -0
- package/packages/shared-skills/skills/frontend/references/design/print-paged-media.md +76 -0
- package/packages/shared-skills/skills/frontend/references/design/stylegallery.md +80 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/README.md +1 -1
- package/packages/shared-skills/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
- package/packages/shared-skills/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
- package/packages/shared-skills/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
- package/packages/shared-skills/skills/frontend/references/designpowers/orchestration.md +1 -1
- package/packages/shared-skills/skills/frontend/references/designpowers/routing.md +5 -5
- package/packages/shared-skills/skills/git-master/SKILL.md +1 -1
- package/packages/shared-skills/skills/init-deep/SKILL.md +14 -14
- package/packages/shared-skills/skills/lsp-setup/SKILL.md +1 -1
- package/packages/shared-skills/skills/programming/SKILL.md +1 -1
- package/packages/shared-skills/skills/refactor/SKILL.md +1 -1
- package/packages/shared-skills/skills/remove-ai-slops/SKILL.md +1 -1
- package/packages/shared-skills/skills/review-work/SKILL.md +100 -418
- package/packages/shared-skills/skills/ultimate-browsing/ATTRIBUTION.md +38 -11
- package/packages/shared-skills/skills/ultimate-browsing/SKILL.md +26 -9
- package/packages/shared-skills/skills/ultimate-browsing/engine/AGENTS.md +110 -0
- package/packages/shared-skills/skills/ultimate-browsing/engine/templates/package.json +1 -1
- package/packages/shared-skills/skills/ultimate-browsing/references/chrome-stealth.md +23 -18
- package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/README.md +9 -2
- package/packages/shared-skills/skills/{start-work → ulw-execute}/SKILL.md +17 -16
- package/packages/shared-skills/skills/ulw-plan/SKILL.md +7 -8
- package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +31 -7
- package/packages/shared-skills/skills/ulw-plan/references/intent-clear.md +2 -1
- package/packages/shared-skills/skills/ulw-plan/references/intent-unclear.md +5 -5
- package/packages/shared-skills/skills/ulw-research/SKILL.md +8 -3
- package/packages/shared-skills/skills/visual-qa/AGENTS.md +58 -0
- package/packages/shared-skills/skills/visual-qa/SKILL.md +4 -3
- package/postinstall.mjs +2 -0
- package/script/qa/web-terminal-visual-qa.mjs +2 -0
- package/script/qa/xterm-live-terminal.mjs +18 -2
- package/dist/config/schema/codegraph.d.ts +0 -12
- package/dist/config/schema/start-work.d.ts +0 -5
- package/dist/features/builtin-commands/templates/start-work.d.ts +0 -1
- 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/codegraph-bootstrap/command-runner.d.ts +0 -17
- package/dist/hooks/codegraph-bootstrap/hook.d.ts +0 -35
- package/dist/hooks/codegraph-bootstrap/index.d.ts +0 -1
- package/dist/hooks/codegraph-bootstrap/project-root.d.ts +0 -1
- package/dist/hooks/codegraph-bootstrap/status.d.ts +0 -11
- 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/hooks/start-work/start-work-hook.d.ts +0 -23
- package/dist/mcp/codegraph.d.ts +0 -16
- package/dist/plugin/chat-message/start-work-message.d.ts +0 -5
- 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/skills/data-scientist/references/common-scenarios.md +0 -176
- package/dist/skills/data-scientist/references/execution-templates.md +0 -197
- package/dist/skills/data-scientist/references/integration-patterns.md +0 -153
- package/dist/skills/data-scientist/references/performance-benchmarks.md +0 -37
- package/dist/tools/call-omo-agent/background-agent-executor.d.ts +0 -5
- package/dist/tools/call-omo-agent/message-storage-directory.d.ts +0 -1
- package/dist/tools/delegate-task/anthropic-categories.d.ts +0 -2
- 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/codegraph/AGENTS.md +0 -58
- package/packages/omo-codex/plugin/components/codegraph/NODE-RUNTIME-LICENSES.md +0 -2951
- package/packages/omo-codex/plugin/components/codegraph/NOTICE +0 -16
- package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +0 -12136
- package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +0 -9734
- package/packages/omo-codex/plugin/components/codegraph/package.json +0 -33
- package/packages/omo-codex/plugin/components/codegraph/src/cache-gc.ts +0 -29
- package/packages/omo-codex/plugin/components/codegraph/src/cli.ts +0 -79
- package/packages/omo-codex/plugin/components/codegraph/src/hook-input.ts +0 -33
- package/packages/omo-codex/plugin/components/codegraph/src/hook-sweep.ts +0 -25
- package/packages/omo-codex/plugin/components/codegraph/src/hook-types.ts +0 -131
- package/packages/omo-codex/plugin/components/codegraph/src/hook.ts +0 -258
- package/packages/omo-codex/plugin/components/codegraph/src/mcp-bridge.ts +0 -309
- package/packages/omo-codex/plugin/components/codegraph/src/mcp-unavailable.ts +0 -80
- package/packages/omo-codex/plugin/components/codegraph/src/post-tool-use-hook.ts +0 -34
- package/packages/omo-codex/plugin/components/codegraph/src/serve-invocation.ts +0 -29
- package/packages/omo-codex/plugin/components/codegraph/src/serve.ts +0 -263
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-command.ts +0 -106
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-cooldown.ts +0 -145
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-hook-runtime.ts +0 -21
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-lock.ts +0 -139
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-outcome.ts +0 -15
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-paths.ts +0 -32
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-project.ts +0 -109
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker-result.ts +0 -148
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker.ts +0 -175
- package/packages/omo-codex/plugin/components/codegraph/src/sweep-cli.ts +0 -81
- package/packages/omo-codex/plugin/components/codegraph/test/cache-gc.test.ts +0 -34
- package/packages/omo-codex/plugin/components/codegraph/test/hook-exclusion.test.ts +0 -112
- package/packages/omo-codex/plugin/components/codegraph/test/hook-registration.test.ts +0 -26
- package/packages/omo-codex/plugin/components/codegraph/test/hook-session-start-guard.test.ts +0 -160
- package/packages/omo-codex/plugin/components/codegraph/test/hook-store-upgrade.test.ts +0 -50
- package/packages/omo-codex/plugin/components/codegraph/test/hook-sweep.test.ts +0 -29
- package/packages/omo-codex/plugin/components/codegraph/test/hook.test.ts +0 -320
- package/packages/omo-codex/plugin/components/codegraph/test/mcp-bridge-fixtures.ts +0 -172
- package/packages/omo-codex/plugin/components/codegraph/test/package-runtime.test.ts +0 -91
- package/packages/omo-codex/plugin/components/codegraph/test/provisioned-node-guard.test.ts +0 -100
- package/packages/omo-codex/plugin/components/codegraph/test/serve-built-wrapper.test.ts +0 -76
- package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge-lifecycle.test.ts +0 -133
- package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge.test.ts +0 -245
- package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-facade.test.ts +0 -69
- package/packages/omo-codex/plugin/components/codegraph/test/serve-node-support.test.ts +0 -43
- package/packages/omo-codex/plugin/components/codegraph/test/serve-provision.test.ts +0 -147
- package/packages/omo-codex/plugin/components/codegraph/test/serve-unavailable.test.ts +0 -175
- package/packages/omo-codex/plugin/components/codegraph/test/serve.test.ts +0 -385
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-node-support.test.ts +0 -206
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-project.test.ts +0 -58
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-state.test.ts +0 -104
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-trust-boundary.test.ts +0 -65
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-availability.test.ts +0 -106
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-cooldown.test.ts +0 -116
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-flow.test.ts +0 -258
- package/packages/omo-codex/plugin/components/codegraph/test/sweep-cli.test.ts +0 -56
- package/packages/omo-codex/plugin/components/codegraph/tsconfig.build.json +0 -13
- package/packages/omo-codex/plugin/components/codegraph/tsconfig.json +0 -25
- package/packages/omo-codex/plugin/components/start-work-continuation/LICENSE +0 -21
- package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +0 -28
- package/packages/omo-codex/plugin/components/ultrawork/directive.md +0 -471
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +0 -18
- package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +0 -17
- package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +0 -17
- package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +0 -17
- package/packages/omo-codex/plugin/scripts/migrate-omo-sot/editor.mjs +0 -125
- package/packages/omo-codex/plugin/scripts/migrate-omo-sot/jsonc.mjs +0 -43
- package/packages/omo-codex/plugin/scripts/migrate-omo-sot/scaffold.mjs +0 -29
- package/packages/omo-codex/plugin/scripts/migrate-omo-sot.mjs +0 -121
- package/packages/omo-codex/plugin/skills/data-scientist/references/common-scenarios.md +0 -176
- package/packages/omo-codex/plugin/skills/data-scientist/references/execution-templates.md +0 -197
- package/packages/omo-codex/plugin/skills/data-scientist/references/integration-patterns.md +0 -153
- package/packages/omo-codex/plugin/skills/data-scientist/references/performance-benchmarks.md +0 -37
- package/packages/omo-codex/plugin/skills/start-work/agents/openai.yaml +0 -2
- package/packages/omo-codex/plugin/test/aggregate-skills.test.mjs +0 -92
- package/packages/omo-codex/plugin/test/component-codegraph-mcp-smoke.test.mjs +0 -76
- package/packages/omo-codex/plugin/test/migrate-omo-sot.test.mjs +0 -179
- package/packages/omo-codex/plugin/test/sync-skills-orchestration.test.mjs +0 -314
- package/packages/omo-codex/plugin/test/ulw-plan-scope-contract.test.mjs +0 -24
- package/packages/shared-skills/skills/data-scientist/references/common-scenarios.md +0 -176
- package/packages/shared-skills/skills/data-scientist/references/execution-templates.md +0 -197
- package/packages/shared-skills/skills/data-scientist/references/integration-patterns.md +0 -153
- package/packages/shared-skills/skills/data-scientist/references/performance-benchmarks.md +0 -37
- /package/dist/hooks/{start-work → ulw-execute}/context-info-formatters.d.ts +0 -0
- /package/dist/hooks/{start-work → ulw-execute}/explicit-plan-context.d.ts +0 -0
- /package/dist/hooks/{start-work → ulw-execute}/notepad-scaffold.d.ts +0 -0
- /package/dist/hooks/{start-work → ulw-execute}/parse-user-request.d.ts +0 -0
- /package/dist/hooks/{start-work → ulw-execute}/plan-discovery-context.d.ts +0 -0
- /package/dist/hooks/{start-work → ulw-execute}/plan-selection.d.ts +0 -0
- /package/dist/hooks/{start-work → ulw-execute}/session-plan-affinity.d.ts +0 -0
- /package/dist/hooks/{start-work → ulw-execute}/work-initializer.d.ts +0 -0
- /package/dist/hooks/{start-work → ulw-execute}/worktree-block.d.ts +0 -0
- /package/dist/hooks/{start-work → ulw-execute}/worktree-detector.d.ts +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/.gitattributes +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/CHANGELOG.md +0 -0
- /package/packages/omo-codex/plugin/components/{codegraph → ulw-execute-continuation}/LICENSE +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/plan-checklist.ts +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-completed.json +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-mixed-platforms.json +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-single-codex-work.json +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-all-done.md +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-scaffold.md +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-with-nested-checkboxes.md +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-with-unchecked.md +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/tsconfig.build.json +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/tsconfig.json +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/vitest.config.ts +0 -0
|
@@ -175,6 +175,7 @@ async function runJsonRpcStdioServer(config) {
|
|
|
175
175
|
const idleTimer = createIdleTimer(idleTimeoutMs, log, () => {
|
|
176
176
|
isClosed = true;
|
|
177
177
|
config.onIdleTimeout?.();
|
|
178
|
+
config.input.destroy();
|
|
178
179
|
});
|
|
179
180
|
const watchdog = createParentWatchdog(config.parentWatchdog, (parentPid, pollIntervalMs) => {
|
|
180
181
|
isClosed = true;
|
|
@@ -271,7 +272,11 @@ function createParentWatchdog(config, onDeadParent) {
|
|
|
271
272
|
const probeAlive = config.probeAlive ?? isProcessAlive;
|
|
272
273
|
let fired = false;
|
|
273
274
|
const timer = setInterval(() => {
|
|
274
|
-
if (fired
|
|
275
|
+
if (fired)
|
|
276
|
+
return;
|
|
277
|
+
const alive = probeAlive(parentPid);
|
|
278
|
+
config.onPoll?.(alive);
|
|
279
|
+
if (alive)
|
|
275
280
|
return;
|
|
276
281
|
fired = true;
|
|
277
282
|
onDeadParent(parentPid, pollIntervalMs);
|
|
@@ -306,8 +311,8 @@ function createIdleTimer(idleTimeoutMs, log, onTimeout) {
|
|
|
306
311
|
};
|
|
307
312
|
}
|
|
308
313
|
// ../lsp-core/src/lsp/client-wrapper.ts
|
|
309
|
-
import { existsSync as
|
|
310
|
-
import { dirname as
|
|
314
|
+
import { existsSync as existsSync10, realpathSync as realpathSync5, statSync as statSync3 } from "node:fs";
|
|
315
|
+
import { basename as basename3, dirname as dirname8, join as join5, resolve as resolve8 } from "node:path";
|
|
311
316
|
|
|
312
317
|
// ../lsp-core/src/request-context.ts
|
|
313
318
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
@@ -316,18 +321,17 @@ import { homedir } from "node:os";
|
|
|
316
321
|
import { basename, delimiter, dirname, isAbsolute, join, relative, resolve } from "node:path";
|
|
317
322
|
|
|
318
323
|
class LspRequestContextParseError extends Error {
|
|
319
|
-
code;
|
|
320
|
-
name = "LspRequestContextParseError";
|
|
321
324
|
constructor(code, message) {
|
|
322
325
|
super(message);
|
|
323
326
|
this.code = code;
|
|
327
|
+
this.name = "LspRequestContextParseError";
|
|
324
328
|
}
|
|
325
329
|
}
|
|
326
330
|
|
|
327
331
|
class LspRequestContextUnavailableError extends Error {
|
|
328
|
-
name = "LspRequestContextUnavailableError";
|
|
329
332
|
constructor() {
|
|
330
333
|
super("LSP request context is required. Standalone MCP startup must install one with runWithRequestContext(createStandaloneMcpRequestContext()).");
|
|
334
|
+
this.name = "LspRequestContextUnavailableError";
|
|
331
335
|
}
|
|
332
336
|
}
|
|
333
337
|
var storage = new AsyncLocalStorage;
|
|
@@ -357,7 +361,7 @@ function contextEnv(key) {
|
|
|
357
361
|
}
|
|
358
362
|
function createStandaloneMcpRequestContext(input = {}) {
|
|
359
363
|
const env = input.env ?? process.env;
|
|
360
|
-
const cwd = canonicalCwd(input.cwd ?? process.cwd());
|
|
364
|
+
const cwd = canonicalCwd(input.cwd ?? env["LSP_TOOLS_MCP_CWD"] ?? process.cwd());
|
|
361
365
|
const home = input.homeDir ?? homedir();
|
|
362
366
|
const projectConfigPaths = translateProjectConfigEnv(env["LSP_TOOLS_MCP_PROJECT_CONFIG"], cwd);
|
|
363
367
|
const userConfigPath = translateHomeConfigEnv(env["LSP_TOOLS_MCP_USER_CONFIG"], home, ".codex/lsp-client.json");
|
|
@@ -500,22 +504,15 @@ function effectiveExtension(filePath) {
|
|
|
500
504
|
|
|
501
505
|
// ../lsp-core/src/lsp/errors.ts
|
|
502
506
|
class LspConnectionClosedError extends Error {
|
|
503
|
-
serverId;
|
|
504
|
-
root;
|
|
505
|
-
name = "LspConnectionClosedError";
|
|
506
507
|
constructor(serverId, root, message) {
|
|
507
508
|
super(message ?? `LSP connection closed for ${serverId} at ${root}`);
|
|
508
509
|
this.serverId = serverId;
|
|
509
510
|
this.root = root;
|
|
511
|
+
this.name = "LspConnectionClosedError";
|
|
510
512
|
}
|
|
511
513
|
}
|
|
512
514
|
|
|
513
515
|
class LspProcessExitedError extends Error {
|
|
514
|
-
serverId;
|
|
515
|
-
root;
|
|
516
|
-
exitCode;
|
|
517
|
-
stderrTail;
|
|
518
|
-
name = "LspProcessExitedError";
|
|
519
516
|
constructor(serverId, root, exitCode, stderrTail) {
|
|
520
517
|
const stderrSuffix = stderrTail ? `
|
|
521
518
|
stderr tail: ${stderrTail}` : "";
|
|
@@ -524,46 +521,59 @@ stderr tail: ${stderrTail}` : "";
|
|
|
524
521
|
this.root = root;
|
|
525
522
|
this.exitCode = exitCode;
|
|
526
523
|
this.stderrTail = stderrTail;
|
|
524
|
+
this.name = "LspProcessExitedError";
|
|
527
525
|
}
|
|
528
526
|
}
|
|
529
527
|
|
|
530
528
|
class LspRequestTimeoutError extends Error {
|
|
531
|
-
method;
|
|
532
|
-
stderrTail;
|
|
533
|
-
name = "LspRequestTimeoutError";
|
|
534
529
|
constructor(method, stderrTail) {
|
|
535
530
|
const stderrSuffix = stderrTail ? `
|
|
536
531
|
recent stderr: ${stderrTail}` : "";
|
|
537
532
|
super(`LSP request timeout (method: ${method})${stderrSuffix}`);
|
|
538
533
|
this.method = method;
|
|
539
534
|
this.stderrTail = stderrTail;
|
|
535
|
+
this.name = "LspRequestTimeoutError";
|
|
540
536
|
}
|
|
541
537
|
}
|
|
542
538
|
|
|
543
539
|
class LspInvalidPathError extends Error {
|
|
544
|
-
|
|
540
|
+
constructor() {
|
|
541
|
+
super(...arguments);
|
|
542
|
+
this.name = "LspInvalidPathError";
|
|
543
|
+
}
|
|
545
544
|
}
|
|
546
545
|
|
|
547
546
|
class LspServerLookupError extends Error {
|
|
548
|
-
lookup;
|
|
549
|
-
name = "LspServerLookupError";
|
|
550
547
|
constructor(message, lookup) {
|
|
551
548
|
super(message);
|
|
552
549
|
this.lookup = lookup;
|
|
550
|
+
this.name = "LspServerLookupError";
|
|
553
551
|
}
|
|
554
552
|
}
|
|
555
553
|
|
|
556
554
|
class LspServerInitializingError extends Error {
|
|
557
|
-
originalError;
|
|
558
|
-
name = "LspServerInitializingError";
|
|
559
555
|
constructor(originalError) {
|
|
560
556
|
super(`LSP server is still initializing. Please retry in a few seconds. Original error: ${originalError.message}`);
|
|
561
557
|
this.originalError = originalError;
|
|
558
|
+
this.name = "LspServerInitializingError";
|
|
562
559
|
}
|
|
563
560
|
}
|
|
564
561
|
|
|
565
562
|
class LspProcessSpawnError extends Error {
|
|
566
|
-
|
|
563
|
+
constructor() {
|
|
564
|
+
super(...arguments);
|
|
565
|
+
this.name = "LspProcessSpawnError";
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
class LspClientRespawnBudgetExceededError extends Error {
|
|
570
|
+
constructor(serverId, root, retryLimit) {
|
|
571
|
+
super(`LSP server ${serverId} at ${root} failed to stay alive; respawn budget exhausted ` + `(${retryLimit} consecutive dead generations). Retrying after the cooldown may succeed.`);
|
|
572
|
+
this.serverId = serverId;
|
|
573
|
+
this.root = root;
|
|
574
|
+
this.retryLimit = retryLimit;
|
|
575
|
+
this.name = "LspClientRespawnBudgetExceededError";
|
|
576
|
+
}
|
|
567
577
|
}
|
|
568
578
|
function isLspDeadConnectionError(err) {
|
|
569
579
|
return err instanceof LspConnectionClosedError || err instanceof LspProcessExitedError;
|
|
@@ -586,6 +596,13 @@ import { pathToFileURL as pathToFileURL3 } from "node:url";
|
|
|
586
596
|
// ../lsp-core/src/lsp/connection.ts
|
|
587
597
|
import { pathToFileURL } from "node:url";
|
|
588
598
|
|
|
599
|
+
// ../lsp-core/src/lsp/timer-provider.ts
|
|
600
|
+
var realTimerProvider = {
|
|
601
|
+
now: () => Date.now(),
|
|
602
|
+
setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
|
|
603
|
+
clearTimeout: (handle) => clearTimeout(handle)
|
|
604
|
+
};
|
|
605
|
+
|
|
589
606
|
// ../lsp-core/src/lsp/constants.ts
|
|
590
607
|
var DEFAULT_MAX_REFERENCES = 200;
|
|
591
608
|
var DEFAULT_MAX_SYMBOLS = 200;
|
|
@@ -594,9 +611,12 @@ var DEFAULT_MAX_DIRECTORY_FILES = 50;
|
|
|
594
611
|
var REQUEST_TIMEOUT_MS = 15000;
|
|
595
612
|
var INIT_TIMEOUT_MS = 60000;
|
|
596
613
|
var IDLE_TIMEOUT_MS = 5 * 60000;
|
|
614
|
+
var MAX_RESIDENT_CLIENTS = 6;
|
|
597
615
|
var REAPER_INTERVAL_MS = 60000;
|
|
598
616
|
var STOP_HARD_KILL_TIMEOUT_MS = 5000;
|
|
599
617
|
var STOP_SIGKILL_GRACE_MS = 1000;
|
|
618
|
+
var CLIENT_RESPAWN_RETRY_LIMIT = 2;
|
|
619
|
+
var CLIENT_RESPAWN_COOLDOWN_MS = 60000;
|
|
600
620
|
|
|
601
621
|
// ../lsp-core/src/lsp/json-rpc-connection.ts
|
|
602
622
|
var HEADER_SEPARATOR2 = `\r
|
|
@@ -608,20 +628,31 @@ var METHOD_NOT_FOUND = -32601;
|
|
|
608
628
|
var INTERNAL_ERROR = -32603;
|
|
609
629
|
|
|
610
630
|
class JsonRpcConnection {
|
|
611
|
-
reader;
|
|
612
|
-
writer;
|
|
613
|
-
pendingRequests = new Map;
|
|
614
|
-
notificationHandlers = new Map;
|
|
615
|
-
requestHandlers = new Map;
|
|
616
|
-
closeHandlers = [];
|
|
617
|
-
errorHandlers = [];
|
|
618
|
-
inputBuffer = Buffer.alloc(0);
|
|
619
|
-
nextRequestId = 1;
|
|
620
|
-
listening = false;
|
|
621
|
-
disposed = false;
|
|
622
631
|
constructor(reader, writer) {
|
|
623
632
|
this.reader = reader;
|
|
624
633
|
this.writer = writer;
|
|
634
|
+
this.pendingRequests = new Map;
|
|
635
|
+
this.notificationHandlers = new Map;
|
|
636
|
+
this.requestHandlers = new Map;
|
|
637
|
+
this.closeHandlers = [];
|
|
638
|
+
this.errorHandlers = [];
|
|
639
|
+
this.inputBuffer = Buffer.alloc(0);
|
|
640
|
+
this.nextRequestId = 1;
|
|
641
|
+
this.listening = false;
|
|
642
|
+
this.disposed = false;
|
|
643
|
+
this.handleData = (chunk) => {
|
|
644
|
+
const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
|
|
645
|
+
this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
|
|
646
|
+
this.drainInputBuffer();
|
|
647
|
+
};
|
|
648
|
+
this.handleClose = () => {
|
|
649
|
+
for (const handler of this.closeHandlers) {
|
|
650
|
+
handler();
|
|
651
|
+
}
|
|
652
|
+
};
|
|
653
|
+
this.handleStreamError = (error) => {
|
|
654
|
+
this.emitError(error);
|
|
655
|
+
};
|
|
625
656
|
}
|
|
626
657
|
listen() {
|
|
627
658
|
if (this.listening)
|
|
@@ -656,7 +687,8 @@ class JsonRpcConnection {
|
|
|
656
687
|
let cancelAfterWrite = false;
|
|
657
688
|
let settled = false;
|
|
658
689
|
const writeCancel = () => this.writeMessage({ jsonrpc: "2.0", method: "$/cancelRequest", params: { id } });
|
|
659
|
-
|
|
690
|
+
let rejectAfterCancelWrite;
|
|
691
|
+
const responsePromise = new Promise((resolve, reject) => {
|
|
660
692
|
const cleanup = () => {
|
|
661
693
|
options.signal?.removeEventListener("abort", onAbort);
|
|
662
694
|
};
|
|
@@ -667,22 +699,26 @@ class JsonRpcConnection {
|
|
|
667
699
|
this.pendingRequests.delete(key);
|
|
668
700
|
cleanup();
|
|
669
701
|
const rejectCancelled = () => reject(abortError(options.signal));
|
|
702
|
+
rejectAfterCancelWrite = async () => {
|
|
703
|
+
try {
|
|
704
|
+
await writeCancel();
|
|
705
|
+
} catch (error) {
|
|
706
|
+
this.emitError(toError(error));
|
|
707
|
+
}
|
|
708
|
+
rejectCancelled();
|
|
709
|
+
};
|
|
670
710
|
if (!requestWritten) {
|
|
671
711
|
cancelAfterWrite = true;
|
|
672
|
-
rejectCancelled();
|
|
673
712
|
return;
|
|
674
713
|
}
|
|
675
|
-
|
|
676
|
-
this.emitError(toError(error));
|
|
677
|
-
rejectCancelled();
|
|
678
|
-
});
|
|
714
|
+
rejectAfterCancelWrite();
|
|
679
715
|
};
|
|
680
716
|
const onAbort = () => settleCancel();
|
|
681
717
|
this.pendingRequests.set(key, {
|
|
682
718
|
resolve(result) {
|
|
683
719
|
settled = true;
|
|
684
720
|
cleanup();
|
|
685
|
-
|
|
721
|
+
resolve(result);
|
|
686
722
|
},
|
|
687
723
|
reject(error) {
|
|
688
724
|
settled = true;
|
|
@@ -703,7 +739,7 @@ class JsonRpcConnection {
|
|
|
703
739
|
await this.writeMessage(message);
|
|
704
740
|
requestWritten = true;
|
|
705
741
|
if (cancelAfterWrite)
|
|
706
|
-
await
|
|
742
|
+
await rejectAfterCancelWrite?.();
|
|
707
743
|
} catch (error) {
|
|
708
744
|
if (settled)
|
|
709
745
|
return responsePromise;
|
|
@@ -742,19 +778,6 @@ class JsonRpcConnection {
|
|
|
742
778
|
this.notificationHandlers.clear();
|
|
743
779
|
this.requestHandlers.clear();
|
|
744
780
|
}
|
|
745
|
-
handleData = (chunk) => {
|
|
746
|
-
const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
|
|
747
|
-
this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
|
|
748
|
-
this.drainInputBuffer();
|
|
749
|
-
};
|
|
750
|
-
handleClose = () => {
|
|
751
|
-
for (const handler of this.closeHandlers) {
|
|
752
|
-
handler();
|
|
753
|
-
}
|
|
754
|
-
};
|
|
755
|
-
handleStreamError = (error) => {
|
|
756
|
-
this.emitError(error);
|
|
757
|
-
};
|
|
758
781
|
drainInputBuffer() {
|
|
759
782
|
while (true) {
|
|
760
783
|
const headerEnd = this.inputBuffer.indexOf(HEADER_SEPARATOR2);
|
|
@@ -854,13 +877,13 @@ class JsonRpcConnection {
|
|
|
854
877
|
const payload = `Content-Length: ${Buffer.byteLength(body, "utf8")}\r
|
|
855
878
|
\r
|
|
856
879
|
${body}`;
|
|
857
|
-
return new Promise((
|
|
880
|
+
return new Promise((resolve, reject) => {
|
|
858
881
|
this.writer.write(payload, (error) => {
|
|
859
882
|
if (error) {
|
|
860
883
|
reject(error);
|
|
861
884
|
return;
|
|
862
885
|
}
|
|
863
|
-
|
|
886
|
+
resolve();
|
|
864
887
|
});
|
|
865
888
|
});
|
|
866
889
|
}
|
|
@@ -947,9 +970,9 @@ function validateCwd(cwd) {
|
|
|
947
970
|
}
|
|
948
971
|
}
|
|
949
972
|
function wrap(proc) {
|
|
950
|
-
const exitedPromise = new Promise((
|
|
951
|
-
proc.once("close", (code) =>
|
|
952
|
-
proc.once("error", () =>
|
|
973
|
+
const exitedPromise = new Promise((resolve) => {
|
|
974
|
+
proc.once("close", (code) => resolve(code ?? 0));
|
|
975
|
+
proc.once("error", () => resolve(1));
|
|
953
976
|
});
|
|
954
977
|
if (!proc.stdin || !proc.stdout || !proc.stderr) {
|
|
955
978
|
throw new LspProcessSpawnError("Spawned process is missing one of stdin/stdout/stderr pipes");
|
|
@@ -1102,33 +1125,29 @@ function isPosition(value) {
|
|
|
1102
1125
|
|
|
1103
1126
|
// ../lsp-core/src/lsp/transport.ts
|
|
1104
1127
|
class LspClientNotStartedError extends Error {
|
|
1105
|
-
serverId;
|
|
1106
|
-
root;
|
|
1107
|
-
name = "LspClientNotStartedError";
|
|
1108
1128
|
constructor(serverId, root) {
|
|
1109
1129
|
super("LSP client not started");
|
|
1110
1130
|
this.serverId = serverId;
|
|
1111
1131
|
this.root = root;
|
|
1132
|
+
this.name = "LspClientNotStartedError";
|
|
1112
1133
|
}
|
|
1113
1134
|
}
|
|
1114
1135
|
|
|
1115
1136
|
class LspClientTransport {
|
|
1116
|
-
root
|
|
1117
|
-
server;
|
|
1118
|
-
proc = null;
|
|
1119
|
-
connection = null;
|
|
1120
|
-
stderrBuffer = [];
|
|
1121
|
-
processExited = false;
|
|
1122
|
-
diagnosticsStore = new Map;
|
|
1123
|
-
requestTimeoutMs;
|
|
1124
|
-
initializeTimeoutMs;
|
|
1125
|
-
workspaceApplyEditHandler = null;
|
|
1126
|
-
diagnosticPullSupported = false;
|
|
1127
|
-
constructor(root, server2, timeouts = {}) {
|
|
1137
|
+
constructor(root, server, timeouts = {}) {
|
|
1128
1138
|
this.root = root;
|
|
1129
|
-
this.server =
|
|
1139
|
+
this.server = server;
|
|
1140
|
+
this.proc = null;
|
|
1141
|
+
this.connection = null;
|
|
1142
|
+
this.stderrBuffer = [];
|
|
1143
|
+
this.processExited = false;
|
|
1144
|
+
this.diagnosticsStore = new Map;
|
|
1145
|
+
this.workspaceApplyEditHandler = null;
|
|
1146
|
+
this.diagnosticPullSupported = false;
|
|
1147
|
+
this.documentFormattingSupported = false;
|
|
1130
1148
|
this.requestTimeoutMs = timeouts.requestTimeoutMs ?? REQUEST_TIMEOUT_MS;
|
|
1131
1149
|
this.initializeTimeoutMs = timeouts.initializeTimeoutMs ?? INIT_TIMEOUT_MS;
|
|
1150
|
+
this.timerProvider = timeouts.timerProvider ?? realTimerProvider;
|
|
1132
1151
|
}
|
|
1133
1152
|
pid() {
|
|
1134
1153
|
return this.proc?.pid;
|
|
@@ -1148,6 +1167,12 @@ class LspClientTransport {
|
|
|
1148
1167
|
isDiagnosticPullSupported() {
|
|
1149
1168
|
return this.diagnosticPullSupported;
|
|
1150
1169
|
}
|
|
1170
|
+
setDocumentFormattingSupported(supported) {
|
|
1171
|
+
this.documentFormattingSupported = supported;
|
|
1172
|
+
}
|
|
1173
|
+
isDocumentFormattingSupported() {
|
|
1174
|
+
return this.documentFormattingSupported;
|
|
1175
|
+
}
|
|
1151
1176
|
handlePublishDiagnostics(params) {
|
|
1152
1177
|
this.diagnosticsStore.set(params.uri, [...params.diagnostics]);
|
|
1153
1178
|
}
|
|
@@ -1223,7 +1248,7 @@ class LspClientTransport {
|
|
|
1223
1248
|
const options = args[1];
|
|
1224
1249
|
const timeoutMs = options?.timeoutMs ?? this.requestTimeoutMs;
|
|
1225
1250
|
const timeoutController = new AbortController;
|
|
1226
|
-
const timeoutHandle = setTimeout(() => {
|
|
1251
|
+
const timeoutHandle = this.timerProvider.setTimeout(() => {
|
|
1227
1252
|
const stderrTail = this.stderrBuffer.slice(-5).join(`
|
|
1228
1253
|
`);
|
|
1229
1254
|
timeoutController.abort(new LspRequestTimeoutError(method, stderrTail || undefined));
|
|
@@ -1242,7 +1267,7 @@ class LspClientTransport {
|
|
|
1242
1267
|
}
|
|
1243
1268
|
throw error;
|
|
1244
1269
|
} finally {
|
|
1245
|
-
clearTimeout(timeoutHandle);
|
|
1270
|
+
this.timerProvider.clearTimeout(timeoutHandle);
|
|
1246
1271
|
combinedSignal.dispose();
|
|
1247
1272
|
}
|
|
1248
1273
|
}
|
|
@@ -1293,8 +1318,8 @@ class LspClientTransport {
|
|
|
1293
1318
|
try {
|
|
1294
1319
|
proc.kill();
|
|
1295
1320
|
let timeoutId;
|
|
1296
|
-
const timeoutPromise = new Promise((
|
|
1297
|
-
timeoutId = setTimeout(
|
|
1321
|
+
const timeoutPromise = new Promise((resolve) => {
|
|
1322
|
+
timeoutId = setTimeout(resolve, STOP_HARD_KILL_TIMEOUT_MS);
|
|
1298
1323
|
});
|
|
1299
1324
|
await Promise.race([
|
|
1300
1325
|
proc.exited.then(() => {
|
|
@@ -1310,7 +1335,7 @@ class LspClientTransport {
|
|
|
1310
1335
|
proc.kill("SIGKILL");
|
|
1311
1336
|
await Promise.race([
|
|
1312
1337
|
proc.exited,
|
|
1313
|
-
new Promise((
|
|
1338
|
+
new Promise((resolve) => setTimeout(resolve, STOP_SIGKILL_GRACE_MS))
|
|
1314
1339
|
]);
|
|
1315
1340
|
} catch (error) {
|
|
1316
1341
|
reportBestEffortCleanupError("hard process kill", error instanceof Error ? error : String(error));
|
|
@@ -1361,6 +1386,14 @@ function supportsDiagnosticPull(capabilities) {
|
|
|
1361
1386
|
return false;
|
|
1362
1387
|
return Object.hasOwn(capabilities, "diagnosticProvider");
|
|
1363
1388
|
}
|
|
1389
|
+
function supportsDocumentFormatting(capabilities) {
|
|
1390
|
+
if (capabilities === undefined)
|
|
1391
|
+
return false;
|
|
1392
|
+
const provider = capabilities.documentFormattingProvider;
|
|
1393
|
+
if (provider === undefined || provider === null || provider === false)
|
|
1394
|
+
return false;
|
|
1395
|
+
return provider === true || typeof provider === "object";
|
|
1396
|
+
}
|
|
1364
1397
|
|
|
1365
1398
|
class LspClientConnection extends LspClientTransport {
|
|
1366
1399
|
async initialize() {
|
|
@@ -1377,6 +1410,7 @@ class LspClientConnection extends LspClientTransport {
|
|
|
1377
1410
|
references: {},
|
|
1378
1411
|
documentSymbol: { hierarchicalDocumentSymbolSupport: true },
|
|
1379
1412
|
publishDiagnostics: {},
|
|
1413
|
+
formatting: { dynamicRegistration: false },
|
|
1380
1414
|
rename: {
|
|
1381
1415
|
prepareSupport: true,
|
|
1382
1416
|
prepareSupportDefaultBehavior: 1
|
|
@@ -1418,6 +1452,7 @@ class LspClientConnection extends LspClientTransport {
|
|
|
1418
1452
|
initializationOptions: this.server.initialization
|
|
1419
1453
|
}, { timeoutMs: this.initializeTimeoutMs });
|
|
1420
1454
|
this.setDiagnosticPullSupported(supportsDiagnosticPull(result?.capabilities));
|
|
1455
|
+
this.setDocumentFormattingSupported(supportsDocumentFormatting(result?.capabilities));
|
|
1421
1456
|
await this.sendNotification("initialized", {});
|
|
1422
1457
|
await this.sendNotification("workspace/didChangeConfiguration", {
|
|
1423
1458
|
settings: { json: { validate: { enable: true } } }
|
|
@@ -1613,6 +1648,17 @@ function canonicalPath(filePath) {
|
|
|
1613
1648
|
return absolute;
|
|
1614
1649
|
}
|
|
1615
1650
|
}
|
|
1651
|
+
function normalizeDocumentUri(uri) {
|
|
1652
|
+
let decoded = uri;
|
|
1653
|
+
try {
|
|
1654
|
+
decoded = decodeURIComponent(uri);
|
|
1655
|
+
} catch {
|
|
1656
|
+
decoded = uri;
|
|
1657
|
+
}
|
|
1658
|
+
if (process.platform !== "win32")
|
|
1659
|
+
return decoded;
|
|
1660
|
+
return decoded.replace(/^(file:\/\/\/)([a-z]):/, (_match, prefix, drive) => `${prefix}${drive.toUpperCase()}:`);
|
|
1661
|
+
}
|
|
1616
1662
|
function isSameOrDescendant(candidate, parent) {
|
|
1617
1663
|
const suffix = relative2(parent, candidate);
|
|
1618
1664
|
return suffix === "" || !suffix.startsWith("..") && suffix !== "..";
|
|
@@ -1623,17 +1669,18 @@ function movedPath(candidate, oldPath, newPath) {
|
|
|
1623
1669
|
}
|
|
1624
1670
|
|
|
1625
1671
|
class WorkspaceDocumentState {
|
|
1626
|
-
sendNotification;
|
|
1627
|
-
clearDiagnostics;
|
|
1628
|
-
openDocuments = new Map;
|
|
1629
|
-
openByUri = new Map;
|
|
1630
|
-
openPromises = new Map;
|
|
1631
|
-
now;
|
|
1632
|
-
versionlessPublishQuiescenceMs;
|
|
1633
1672
|
constructor(sendNotification, clearDiagnostics, options = {}) {
|
|
1634
1673
|
this.sendNotification = sendNotification;
|
|
1635
1674
|
this.clearDiagnostics = clearDiagnostics;
|
|
1636
|
-
this.
|
|
1675
|
+
this.openDocuments = new Map;
|
|
1676
|
+
this.openByUri = new Map;
|
|
1677
|
+
this.openPromises = new Map;
|
|
1678
|
+
this.timerProvider = options.timerProvider ?? {
|
|
1679
|
+
now: options.now ?? (() => Date.now()),
|
|
1680
|
+
setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
|
|
1681
|
+
clearTimeout: (handle) => clearTimeout(handle)
|
|
1682
|
+
};
|
|
1683
|
+
this.now = () => this.timerProvider.now();
|
|
1637
1684
|
this.versionlessPublishQuiescenceMs = options.versionlessPublishQuiescenceMs ?? DEFAULT_VERSIONLESS_PUBLISH_QUIESCENCE_MS;
|
|
1638
1685
|
}
|
|
1639
1686
|
async openFile(filePath) {
|
|
@@ -1655,7 +1702,7 @@ class WorkspaceDocumentState {
|
|
|
1655
1702
|
return this.openDocuments.get(canonicalPath(filePath))?.version;
|
|
1656
1703
|
}
|
|
1657
1704
|
getStoredDiagnostics(uri) {
|
|
1658
|
-
const state = this.openByUri.get(uri);
|
|
1705
|
+
const state = this.openByUri.get(normalizeDocumentUri(uri));
|
|
1659
1706
|
if (!state)
|
|
1660
1707
|
return [];
|
|
1661
1708
|
return state.lastPublish?.diagnostics ?? state.pullCache?.diagnostics ?? [];
|
|
@@ -1677,13 +1724,13 @@ class WorkspaceDocumentState {
|
|
|
1677
1724
|
return state !== undefined && state.uri === snapshot.uri && state.version === snapshot.version && state.generation === snapshot.documentGeneration;
|
|
1678
1725
|
}
|
|
1679
1726
|
getPullCache(snapshot) {
|
|
1680
|
-
const state = this.openByUri.get(snapshot.uri);
|
|
1727
|
+
const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
|
|
1681
1728
|
if (!state?.pullCache || state.pullCache.documentVersion !== snapshot.version)
|
|
1682
1729
|
return null;
|
|
1683
1730
|
return state.pullCache;
|
|
1684
1731
|
}
|
|
1685
1732
|
recordPullDiagnostics(snapshot, report) {
|
|
1686
|
-
const state = this.openByUri.get(snapshot.uri);
|
|
1733
|
+
const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
|
|
1687
1734
|
if (!state)
|
|
1688
1735
|
return;
|
|
1689
1736
|
state.pullCache = {
|
|
@@ -1693,7 +1740,7 @@ class WorkspaceDocumentState {
|
|
|
1693
1740
|
};
|
|
1694
1741
|
}
|
|
1695
1742
|
recordPublishedDiagnostics(params) {
|
|
1696
|
-
const state = this.openByUri.get(params.uri);
|
|
1743
|
+
const state = this.openByUri.get(normalizeDocumentUri(params.uri));
|
|
1697
1744
|
if (!state)
|
|
1698
1745
|
return;
|
|
1699
1746
|
state.publishGeneration += 1;
|
|
@@ -1707,7 +1754,7 @@ class WorkspaceDocumentState {
|
|
|
1707
1754
|
this.notifyWaiters(state);
|
|
1708
1755
|
}
|
|
1709
1756
|
resolvePushDiagnostics(snapshot) {
|
|
1710
|
-
const state = this.openByUri.get(snapshot.uri);
|
|
1757
|
+
const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
|
|
1711
1758
|
if (!state?.lastPublish)
|
|
1712
1759
|
return { status: "missing" };
|
|
1713
1760
|
const publish = state.lastPublish;
|
|
@@ -1721,7 +1768,7 @@ class WorkspaceDocumentState {
|
|
|
1721
1768
|
return waitMs === 0 ? { status: "ready", diagnostics: publish.diagnostics } : { status: "wait", waitMs };
|
|
1722
1769
|
}
|
|
1723
1770
|
waitForDiagnosticsActivity(snapshot, timeoutMs) {
|
|
1724
|
-
const state = this.openByUri.get(snapshot.uri);
|
|
1771
|
+
const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
|
|
1725
1772
|
if (!state || timeoutMs <= 0)
|
|
1726
1773
|
return Promise.resolve();
|
|
1727
1774
|
return new Promise((resolveActivity) => {
|
|
@@ -1730,11 +1777,11 @@ class WorkspaceDocumentState {
|
|
|
1730
1777
|
if (settled)
|
|
1731
1778
|
return;
|
|
1732
1779
|
settled = true;
|
|
1733
|
-
clearTimeout(timer);
|
|
1780
|
+
this.timerProvider.clearTimeout(timer);
|
|
1734
1781
|
state.waiters.delete(finish);
|
|
1735
1782
|
resolveActivity();
|
|
1736
1783
|
};
|
|
1737
|
-
const timer = setTimeout(finish, timeoutMs);
|
|
1784
|
+
const timer = this.timerProvider.setTimeout(finish, timeoutMs);
|
|
1738
1785
|
if (typeof timer.unref === "function")
|
|
1739
1786
|
timer.unref();
|
|
1740
1787
|
state.waiters.add(finish);
|
|
@@ -1842,7 +1889,7 @@ class WorkspaceDocumentState {
|
|
|
1842
1889
|
waiters: new Set
|
|
1843
1890
|
};
|
|
1844
1891
|
this.openDocuments.set(path, state);
|
|
1845
|
-
this.openByUri.set(state.uri, state);
|
|
1892
|
+
this.openByUri.set(normalizeDocumentUri(state.uri), state);
|
|
1846
1893
|
this.notifyWaiters(state);
|
|
1847
1894
|
await this.sendNotification("textDocument/didOpen", {
|
|
1848
1895
|
textDocument: { uri: state.uri, languageId: state.languageId, version: state.version, text }
|
|
@@ -1867,7 +1914,7 @@ class WorkspaceDocumentState {
|
|
|
1867
1914
|
}
|
|
1868
1915
|
async closeDocument(state) {
|
|
1869
1916
|
this.openDocuments.delete(state.path);
|
|
1870
|
-
this.openByUri.delete(state.uri);
|
|
1917
|
+
this.openByUri.delete(normalizeDocumentUri(state.uri));
|
|
1871
1918
|
this.clearDiagnostics(state.uri);
|
|
1872
1919
|
this.notifyWaiters(state);
|
|
1873
1920
|
await this.sendNotification("textDocument/didClose", { textDocument: { uri: state.uri } });
|
|
@@ -1896,13 +1943,11 @@ import { dirname as dirname2, isAbsolute as isAbsolute2, relative as relative3,
|
|
|
1896
1943
|
import { fileURLToPath } from "node:url";
|
|
1897
1944
|
|
|
1898
1945
|
class WorkspaceEditPathError extends Error {
|
|
1899
|
-
path;
|
|
1900
|
-
detail;
|
|
1901
|
-
name = "WorkspaceEditPathError";
|
|
1902
1946
|
constructor(path, detail) {
|
|
1903
1947
|
super(`${detail}: ${path}`);
|
|
1904
1948
|
this.path = path;
|
|
1905
1949
|
this.detail = detail;
|
|
1950
|
+
this.name = "WorkspaceEditPathError";
|
|
1906
1951
|
}
|
|
1907
1952
|
}
|
|
1908
1953
|
function isPathInsideWorkspace(filePath, workspaceRoot) {
|
|
@@ -2194,13 +2239,11 @@ function canonicalFingerprint(operations) {
|
|
|
2194
2239
|
|
|
2195
2240
|
// ../lsp-core/src/lsp/workspace-edit-types.ts
|
|
2196
2241
|
class WorkspaceEditValidationError extends Error {
|
|
2197
|
-
changeIndex;
|
|
2198
|
-
detail;
|
|
2199
|
-
name = "WorkspaceEditValidationError";
|
|
2200
2242
|
constructor(changeIndex, detail) {
|
|
2201
2243
|
super(`change ${changeIndex}: ${detail}`);
|
|
2202
2244
|
this.changeIndex = changeIndex;
|
|
2203
2245
|
this.detail = detail;
|
|
2246
|
+
this.name = "WorkspaceEditValidationError";
|
|
2204
2247
|
}
|
|
2205
2248
|
}
|
|
2206
2249
|
|
|
@@ -2286,14 +2329,14 @@ function parseSinglePathResource(input, kind) {
|
|
|
2286
2329
|
return;
|
|
2287
2330
|
}
|
|
2288
2331
|
if (kind === "create") {
|
|
2289
|
-
const
|
|
2332
|
+
const options = parseOptions(change["options"], ["overwrite", "ignoreIfExists"], changeIndex);
|
|
2290
2333
|
target.operations.push({
|
|
2291
2334
|
kind,
|
|
2292
2335
|
changeIndex,
|
|
2293
2336
|
path: resolvedPath.path,
|
|
2294
2337
|
reportedPath: resolvedPath.requestedPath,
|
|
2295
|
-
overwrite:
|
|
2296
|
-
ignoreIfExists:
|
|
2338
|
+
overwrite: options["overwrite"] ?? false,
|
|
2339
|
+
ignoreIfExists: options["ignoreIfExists"] ?? false,
|
|
2297
2340
|
followedSymbolicLink: resolvedPath.followedSymbolicLink
|
|
2298
2341
|
});
|
|
2299
2342
|
return;
|
|
@@ -2698,10 +2741,9 @@ function simulateDelete(operation, virtual) {
|
|
|
2698
2741
|
import { existsSync as existsSync5, lstatSync as lstatSync3, readdirSync as readdirSync2 } from "node:fs";
|
|
2699
2742
|
import { dirname as dirname4, resolve as resolve5 } from "node:path";
|
|
2700
2743
|
class WorkspaceSnapshotBuilder {
|
|
2701
|
-
workspaceRoot;
|
|
2702
|
-
snapshots = new Map;
|
|
2703
2744
|
constructor(workspaceRoot) {
|
|
2704
2745
|
this.workspaceRoot = workspaceRoot;
|
|
2746
|
+
this.snapshots = new Map;
|
|
2705
2747
|
}
|
|
2706
2748
|
build(operations) {
|
|
2707
2749
|
this.add(this.workspaceRoot, false);
|
|
@@ -2745,8 +2787,10 @@ function snapshotOperations(operations, workspaceRoot) {
|
|
|
2745
2787
|
|
|
2746
2788
|
// ../lsp-core/src/lsp/workspace-edit-plan.ts
|
|
2747
2789
|
class PlanPathIndex {
|
|
2748
|
-
|
|
2749
|
-
|
|
2790
|
+
constructor() {
|
|
2791
|
+
this.firstChangeByPath = new Map;
|
|
2792
|
+
this.reportedPathByCanonical = new Map;
|
|
2793
|
+
}
|
|
2750
2794
|
build(operations) {
|
|
2751
2795
|
for (const operation of operations) {
|
|
2752
2796
|
switch (operation.kind) {
|
|
@@ -2762,11 +2806,11 @@ class PlanPathIndex {
|
|
|
2762
2806
|
}
|
|
2763
2807
|
}
|
|
2764
2808
|
}
|
|
2765
|
-
add(path,
|
|
2809
|
+
add(path, reportedPath, changeIndex) {
|
|
2766
2810
|
if (!this.firstChangeByPath.has(path))
|
|
2767
2811
|
this.firstChangeByPath.set(path, changeIndex);
|
|
2768
2812
|
if (!this.reportedPathByCanonical.has(path))
|
|
2769
|
-
this.reportedPathByCanonical.set(path,
|
|
2813
|
+
this.reportedPathByCanonical.set(path, reportedPath);
|
|
2770
2814
|
}
|
|
2771
2815
|
}
|
|
2772
2816
|
function fingerprintWorkspaceEdit(edit, workspaceRoot) {
|
|
@@ -2835,14 +2879,11 @@ function isRecord4(value) {
|
|
|
2835
2879
|
}
|
|
2836
2880
|
|
|
2837
2881
|
class WorkspaceMutationController {
|
|
2838
|
-
workspaceRoot;
|
|
2839
|
-
documents;
|
|
2840
|
-
activeLease = null;
|
|
2841
|
-
nextLeaseId = 1;
|
|
2842
|
-
io;
|
|
2843
2882
|
constructor(workspaceRoot, documents) {
|
|
2844
2883
|
this.workspaceRoot = workspaceRoot;
|
|
2845
2884
|
this.documents = documents;
|
|
2885
|
+
this.activeLease = null;
|
|
2886
|
+
this.nextLeaseId = 1;
|
|
2846
2887
|
}
|
|
2847
2888
|
setIo(io) {
|
|
2848
2889
|
this.io = io;
|
|
@@ -2881,15 +2922,15 @@ class WorkspaceMutationController {
|
|
|
2881
2922
|
};
|
|
2882
2923
|
}
|
|
2883
2924
|
lease.phase = "applying";
|
|
2884
|
-
lease.applyCompletion = new Promise((
|
|
2885
|
-
lease.resolveApply =
|
|
2925
|
+
lease.applyCompletion = new Promise((resolve) => {
|
|
2926
|
+
lease.resolveApply = resolve;
|
|
2886
2927
|
});
|
|
2887
2928
|
const edit = isRecord4(params) ? params["edit"] : undefined;
|
|
2888
|
-
const
|
|
2889
|
-
lease.serverApply =
|
|
2929
|
+
const record = edit === undefined ? { fingerprint: null, result: failure("workspace/applyEdit params.edit is required", 0) } : await this.applyEdit(edit, lease);
|
|
2930
|
+
lease.serverApply = record;
|
|
2890
2931
|
lease.phase = "settled";
|
|
2891
2932
|
lease.resolveApply?.();
|
|
2892
|
-
return responseFor(
|
|
2933
|
+
return responseFor(record.result);
|
|
2893
2934
|
}
|
|
2894
2935
|
async reconcileRename(leaseToken, edit) {
|
|
2895
2936
|
const lease = this.requireActiveLease(leaseToken);
|
|
@@ -2905,16 +2946,16 @@ class WorkspaceMutationController {
|
|
|
2905
2946
|
const applied = await this.applyEdit(edit, lease);
|
|
2906
2947
|
return { edit, apply: applied.result };
|
|
2907
2948
|
}
|
|
2908
|
-
reconcileServerApply(
|
|
2949
|
+
reconcileServerApply(record, edit) {
|
|
2909
2950
|
if (!edit)
|
|
2910
|
-
return { edit, apply:
|
|
2951
|
+
return { edit, apply: record.result };
|
|
2911
2952
|
const fingerprint = fingerprintWorkspaceEdit(edit, this.workspaceRoot);
|
|
2912
|
-
if (fingerprint.success &&
|
|
2913
|
-
return { edit, apply:
|
|
2953
|
+
if (fingerprint.success && record.fingerprint !== null && fingerprint.fingerprint === record.fingerprint) {
|
|
2954
|
+
return { edit, apply: record.result };
|
|
2914
2955
|
}
|
|
2915
2956
|
return {
|
|
2916
2957
|
edit,
|
|
2917
|
-
apply: failure("rename result conflicts with server-applied workspace edit", 0,
|
|
2958
|
+
apply: failure("rename result conflicts with server-applied workspace edit", 0, record.result)
|
|
2918
2959
|
};
|
|
2919
2960
|
}
|
|
2920
2961
|
async applyEdit(edit, lease) {
|
|
@@ -2955,14 +2996,12 @@ var DIAGNOSTICS_FRESHNESS_TIMEOUT_MS = 3000;
|
|
|
2955
2996
|
var VERSIONLESS_PUBLISH_QUIESCENCE_MS = 250;
|
|
2956
2997
|
|
|
2957
2998
|
class LspClient extends LspClientConnection {
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
diagnosticsFreshnessTimeoutMs;
|
|
2962
|
-
constructor(root, server2, options = {}) {
|
|
2963
|
-
super(root, server2, options);
|
|
2999
|
+
constructor(root, server, options = {}) {
|
|
3000
|
+
super(root, server, options);
|
|
3001
|
+
this.diagnosticPullErrors = [];
|
|
2964
3002
|
this.diagnosticsFreshnessTimeoutMs = options.diagnosticsFreshnessTimeoutMs ?? DIAGNOSTICS_FRESHNESS_TIMEOUT_MS;
|
|
2965
3003
|
this.documents = new WorkspaceDocumentState((method, params) => this.sendNotification(method, params), (uri) => this.diagnosticsStore.delete(uri), {
|
|
3004
|
+
timerProvider: this.timerProvider,
|
|
2966
3005
|
versionlessPublishQuiescenceMs: options.versionlessPublishQuiescenceMs ?? VERSIONLESS_PUBLISH_QUIESCENCE_MS
|
|
2967
3006
|
});
|
|
2968
3007
|
this.workspaceMutations = new WorkspaceMutationController(root, this.documents);
|
|
@@ -3015,6 +3054,18 @@ class LspClient extends LspClientConnection {
|
|
|
3015
3054
|
textDocument: { uri: pathToFileURL3(absPath).href }
|
|
3016
3055
|
}, options);
|
|
3017
3056
|
}
|
|
3057
|
+
async formatDocument(filePath, options, signal) {
|
|
3058
|
+
if (!this.isDocumentFormattingSupported())
|
|
3059
|
+
return null;
|
|
3060
|
+
const absPath = this.resolveWorkspacePath(filePath);
|
|
3061
|
+
await this.openFile(absPath);
|
|
3062
|
+
const requestOptions = signal === undefined ? {} : { signal };
|
|
3063
|
+
const edits = await this.sendRequest("textDocument/formatting", {
|
|
3064
|
+
textDocument: { uri: pathToFileURL3(absPath).href },
|
|
3065
|
+
options
|
|
3066
|
+
}, requestOptions);
|
|
3067
|
+
return edits ?? [];
|
|
3068
|
+
}
|
|
3018
3069
|
async workspaceSymbols(query, signal) {
|
|
3019
3070
|
const options = signal === undefined ? {} : { signal };
|
|
3020
3071
|
return this.sendRequest("workspace/symbol", { query }, options);
|
|
@@ -3054,7 +3105,7 @@ class LspClient extends LspClientConnection {
|
|
|
3054
3105
|
const absPath = this.resolveWorkspacePath(filePath);
|
|
3055
3106
|
const uri = pathToFileURL3(absPath).href;
|
|
3056
3107
|
await this.openFile(absPath);
|
|
3057
|
-
const deadlineAt =
|
|
3108
|
+
const deadlineAt = this.timerProvider.now() + this.diagnosticsFreshnessTimeoutMs;
|
|
3058
3109
|
for (;; ) {
|
|
3059
3110
|
signal?.throwIfAborted();
|
|
3060
3111
|
const snapshot = this.documents.captureDiagnosticSnapshot(absPath);
|
|
@@ -3067,13 +3118,13 @@ class LspClient extends LspClientConnection {
|
|
|
3067
3118
|
if (!pushFallbackOnly) {
|
|
3068
3119
|
const cached = this.documents.getPullCache(snapshot);
|
|
3069
3120
|
try {
|
|
3070
|
-
const
|
|
3071
|
-
if (
|
|
3121
|
+
const remainingMs = deadlineAt - this.timerProvider.now();
|
|
3122
|
+
if (remainingMs <= 0)
|
|
3072
3123
|
return this.freshnessTimeout(absPath);
|
|
3073
3124
|
const result = await this.sendRequest("textDocument/diagnostic", {
|
|
3074
3125
|
textDocument: { uri },
|
|
3075
3126
|
...cached?.resultId === undefined ? {} : { previousResultId: cached.resultId }
|
|
3076
|
-
}, { timeoutMs:
|
|
3127
|
+
}, { timeoutMs: remainingMs, ...signal === undefined ? {} : { signal } });
|
|
3077
3128
|
if (!this.documents.isCurrentSnapshot(snapshot))
|
|
3078
3129
|
continue;
|
|
3079
3130
|
const report = this.parseDiagnosticPullReport(result);
|
|
@@ -3102,7 +3153,7 @@ class LspClient extends LspClientConnection {
|
|
|
3102
3153
|
}
|
|
3103
3154
|
if (!pushFallbackOnly)
|
|
3104
3155
|
continue;
|
|
3105
|
-
const remainingMs = deadlineAt -
|
|
3156
|
+
const remainingMs = deadlineAt - this.timerProvider.now();
|
|
3106
3157
|
if (remainingMs <= 0) {
|
|
3107
3158
|
if (!this.isDiagnosticPullSupported() && snapshot.publishGeneration === 0) {
|
|
3108
3159
|
const cached = this.documents.getPullCache(snapshot);
|
|
@@ -3154,7 +3205,7 @@ function waitForDiagnosticsActivity(wait, signal) {
|
|
|
3154
3205
|
return wait;
|
|
3155
3206
|
if (signal.aborted)
|
|
3156
3207
|
return Promise.reject(abortError2(signal));
|
|
3157
|
-
return new Promise((
|
|
3208
|
+
return new Promise((resolve, reject) => {
|
|
3158
3209
|
const onAbort = () => {
|
|
3159
3210
|
signal.removeEventListener("abort", onAbort);
|
|
3160
3211
|
reject(abortError2(signal));
|
|
@@ -3162,7 +3213,7 @@ function waitForDiagnosticsActivity(wait, signal) {
|
|
|
3162
3213
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
3163
3214
|
wait.then(() => {
|
|
3164
3215
|
signal.removeEventListener("abort", onAbort);
|
|
3165
|
-
|
|
3216
|
+
resolve();
|
|
3166
3217
|
}, (error) => {
|
|
3167
3218
|
signal.removeEventListener("abort", onAbort);
|
|
3168
3219
|
reject(error);
|
|
@@ -3230,7 +3281,7 @@ async function stopClientBestEffort(client) {
|
|
|
3230
3281
|
function awaitWithSignal(promise, signal) {
|
|
3231
3282
|
if (!signal)
|
|
3232
3283
|
return promise;
|
|
3233
|
-
return new Promise((
|
|
3284
|
+
return new Promise((resolve, reject) => {
|
|
3234
3285
|
let settled = false;
|
|
3235
3286
|
const onAbort = () => {
|
|
3236
3287
|
if (settled)
|
|
@@ -3248,7 +3299,7 @@ function awaitWithSignal(promise, signal) {
|
|
|
3248
3299
|
return;
|
|
3249
3300
|
settled = true;
|
|
3250
3301
|
signal.removeEventListener("abort", onAbort);
|
|
3251
|
-
|
|
3302
|
+
resolve(value);
|
|
3252
3303
|
}, (err) => {
|
|
3253
3304
|
if (settled)
|
|
3254
3305
|
return;
|
|
@@ -3260,20 +3311,18 @@ function awaitWithSignal(promise, signal) {
|
|
|
3260
3311
|
}
|
|
3261
3312
|
|
|
3262
3313
|
class LspManager {
|
|
3263
|
-
clients = new Map;
|
|
3264
|
-
reaperHandle = null;
|
|
3265
|
-
signalDisposer = null;
|
|
3266
|
-
disposed = false;
|
|
3267
|
-
idleTimeoutMs;
|
|
3268
|
-
initTimeoutMs;
|
|
3269
|
-
reaperIntervalMs;
|
|
3270
|
-
clientFactory;
|
|
3271
|
-
now;
|
|
3272
3314
|
constructor(options = {}) {
|
|
3315
|
+
this.clients = new Map;
|
|
3316
|
+
this.pendingStops = new Map;
|
|
3317
|
+
this.respawnBudgets = new Map;
|
|
3318
|
+
this.reaperHandle = null;
|
|
3319
|
+
this.signalDisposer = null;
|
|
3320
|
+
this.disposed = false;
|
|
3273
3321
|
this.idleTimeoutMs = options.idleTimeoutMs ?? IDLE_TIMEOUT_MS;
|
|
3274
3322
|
this.initTimeoutMs = options.initTimeoutMs ?? INIT_TIMEOUT_MS;
|
|
3323
|
+
this.maxResidentClients = options.maxResidentClients ?? MAX_RESIDENT_CLIENTS;
|
|
3275
3324
|
this.reaperIntervalMs = options.reaperIntervalMs ?? REAPER_INTERVAL_MS;
|
|
3276
|
-
this.clientFactory = options.clientFactory ?? ((root,
|
|
3325
|
+
this.clientFactory = options.clientFactory ?? ((root, server) => new LspClient(root, server));
|
|
3277
3326
|
this.now = options.now ?? (() => Date.now());
|
|
3278
3327
|
this.startReaper();
|
|
3279
3328
|
this.signalDisposer = installProcessSignalCleanup(() => this.stopAll());
|
|
@@ -3291,38 +3340,103 @@ class LspManager {
|
|
|
3291
3340
|
getKey(root, serverId) {
|
|
3292
3341
|
return `${root}::${serverId}`;
|
|
3293
3342
|
}
|
|
3343
|
+
tombstoneStop(key, client) {
|
|
3344
|
+
const stop = stopClientBestEffort(client);
|
|
3345
|
+
this.pendingStops.set(key, stop);
|
|
3346
|
+
stop.finally(() => {
|
|
3347
|
+
if (this.pendingStops.get(key) === stop) {
|
|
3348
|
+
this.pendingStops.delete(key);
|
|
3349
|
+
}
|
|
3350
|
+
});
|
|
3351
|
+
return stop;
|
|
3352
|
+
}
|
|
3353
|
+
recordDeadGeneration(key) {
|
|
3354
|
+
let budget = this.respawnBudgets.get(key);
|
|
3355
|
+
if (budget === undefined) {
|
|
3356
|
+
budget = { deadGenerations: 0, exhaustedAt: null };
|
|
3357
|
+
this.respawnBudgets.set(key, budget);
|
|
3358
|
+
}
|
|
3359
|
+
budget.deadGenerations += 1;
|
|
3360
|
+
}
|
|
3361
|
+
markHealthyGeneration(key) {
|
|
3362
|
+
this.respawnBudgets.delete(key);
|
|
3363
|
+
}
|
|
3364
|
+
ensureRespawnAllowed(key, root, serverId) {
|
|
3365
|
+
const budget = this.respawnBudgets.get(key);
|
|
3366
|
+
if (budget === undefined || budget.deadGenerations < CLIENT_RESPAWN_RETRY_LIMIT)
|
|
3367
|
+
return;
|
|
3368
|
+
if (budget.exhaustedAt === null) {
|
|
3369
|
+
budget.exhaustedAt = this.now();
|
|
3370
|
+
throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
|
|
3371
|
+
}
|
|
3372
|
+
if (this.now() - budget.exhaustedAt < CLIENT_RESPAWN_COOLDOWN_MS) {
|
|
3373
|
+
throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
|
|
3374
|
+
}
|
|
3375
|
+
budget.deadGenerations = 0;
|
|
3376
|
+
budget.exhaustedAt = null;
|
|
3377
|
+
}
|
|
3294
3378
|
reapStale() {
|
|
3295
3379
|
const t = this.now();
|
|
3296
3380
|
for (const [key, managed] of this.clients) {
|
|
3297
3381
|
if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
|
|
3298
|
-
stopClientBestEffort(managed.client);
|
|
3299
3382
|
this.clients.delete(key);
|
|
3383
|
+
this.tombstoneStop(key, managed.client);
|
|
3300
3384
|
continue;
|
|
3301
3385
|
}
|
|
3302
3386
|
if (!managed.isInitializing && managed.refCount === 0 && managed.pendingWaiters === 0 && t - managed.lastUsedAt > this.idleTimeoutMs) {
|
|
3303
|
-
stopClientBestEffort(managed.client);
|
|
3304
3387
|
this.clients.delete(key);
|
|
3388
|
+
this.tombstoneStop(key, managed.client);
|
|
3305
3389
|
}
|
|
3306
3390
|
}
|
|
3307
3391
|
}
|
|
3392
|
+
evictForAdmission() {
|
|
3393
|
+
while (this.clients.size >= this.maxResidentClients) {
|
|
3394
|
+
const victim = this.leastRecentlyUsedIdleClient();
|
|
3395
|
+
if (!victim)
|
|
3396
|
+
return;
|
|
3397
|
+
this.clients.delete(victim.key);
|
|
3398
|
+
this.tombstoneStop(victim.key, victim.managed.client);
|
|
3399
|
+
}
|
|
3400
|
+
}
|
|
3401
|
+
leastRecentlyUsedIdleClient() {
|
|
3402
|
+
let candidate = null;
|
|
3403
|
+
for (const [key, managed] of this.clients) {
|
|
3404
|
+
if (managed.refCount > 0 || managed.pendingWaiters > 0 || managed.isInitializing)
|
|
3405
|
+
continue;
|
|
3406
|
+
if (candidate === null || managed.lastUsedAt < candidate.managed.lastUsedAt) {
|
|
3407
|
+
candidate = { key, managed };
|
|
3408
|
+
}
|
|
3409
|
+
}
|
|
3410
|
+
return candidate;
|
|
3411
|
+
}
|
|
3308
3412
|
async tryDeleteIfOrphaned(key, managed) {
|
|
3309
3413
|
if (managed.refCount === 0 && managed.pendingWaiters === 0 && !managed.isInitializing && this.clients.get(key) === managed) {
|
|
3310
3414
|
this.clients.delete(key);
|
|
3311
|
-
await
|
|
3415
|
+
await this.tombstoneStop(key, managed.client);
|
|
3312
3416
|
}
|
|
3313
3417
|
}
|
|
3314
|
-
async getClient(root,
|
|
3418
|
+
async getClient(root, server, signal) {
|
|
3315
3419
|
if (this.disposed) {
|
|
3316
3420
|
throw new Error("LspManager has been disposed");
|
|
3317
3421
|
}
|
|
3318
3422
|
signal?.throwIfAborted();
|
|
3319
|
-
const key = this.getKey(root,
|
|
3423
|
+
const key = this.getKey(root, server.id);
|
|
3424
|
+
for (;; ) {
|
|
3425
|
+
const pendingStop = this.pendingStops.get(key);
|
|
3426
|
+
if (pendingStop === undefined)
|
|
3427
|
+
break;
|
|
3428
|
+
await awaitWithSignal(pendingStop, signal);
|
|
3429
|
+
signal?.throwIfAborted();
|
|
3430
|
+
}
|
|
3431
|
+
if (this.disposed) {
|
|
3432
|
+
throw new Error("LspManager has been disposed");
|
|
3433
|
+
}
|
|
3320
3434
|
let managed = this.clients.get(key);
|
|
3321
3435
|
if (managed) {
|
|
3322
3436
|
const t = this.now();
|
|
3323
3437
|
if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
|
|
3324
|
-
await stopClientBestEffort(managed.client);
|
|
3325
3438
|
this.clients.delete(key);
|
|
3439
|
+
await this.tombstoneStop(key, managed.client);
|
|
3326
3440
|
managed = undefined;
|
|
3327
3441
|
}
|
|
3328
3442
|
}
|
|
@@ -3343,15 +3457,21 @@ class LspManager {
|
|
|
3343
3457
|
signal.throwIfAborted();
|
|
3344
3458
|
}
|
|
3345
3459
|
if (!managed.client.isAlive()) {
|
|
3346
|
-
|
|
3347
|
-
this.clients.
|
|
3348
|
-
|
|
3460
|
+
this.recordDeadGeneration(key);
|
|
3461
|
+
if (this.clients.get(key) === managed) {
|
|
3462
|
+
this.clients.delete(key);
|
|
3463
|
+
}
|
|
3464
|
+
await this.tombstoneStop(key, managed.client);
|
|
3465
|
+
return this.getClient(root, server, signal);
|
|
3349
3466
|
}
|
|
3467
|
+
this.markHealthyGeneration(key);
|
|
3350
3468
|
managed.refCount++;
|
|
3351
3469
|
managed.lastUsedAt = this.now();
|
|
3352
3470
|
return managed.client;
|
|
3353
3471
|
}
|
|
3354
|
-
|
|
3472
|
+
this.evictForAdmission();
|
|
3473
|
+
this.ensureRespawnAllowed(key, root, server.id);
|
|
3474
|
+
const client = this.clientFactory(root, server);
|
|
3355
3475
|
const initStartedAt = this.now();
|
|
3356
3476
|
const initPromise = (async () => {
|
|
3357
3477
|
await client.start();
|
|
@@ -3374,7 +3494,7 @@ class LspManager {
|
|
|
3374
3494
|
if (this.clients.get(key) === newManaged) {
|
|
3375
3495
|
this.clients.delete(key);
|
|
3376
3496
|
}
|
|
3377
|
-
await
|
|
3497
|
+
await this.tombstoneStop(key, client);
|
|
3378
3498
|
throw err;
|
|
3379
3499
|
}
|
|
3380
3500
|
newManaged.pendingWaiters--;
|
|
@@ -3385,6 +3505,15 @@ class LspManager {
|
|
|
3385
3505
|
await this.tryDeleteIfOrphaned(key, newManaged);
|
|
3386
3506
|
signal.throwIfAborted();
|
|
3387
3507
|
}
|
|
3508
|
+
if (!client.isAlive()) {
|
|
3509
|
+
this.recordDeadGeneration(key);
|
|
3510
|
+
if (this.clients.get(key) === newManaged) {
|
|
3511
|
+
this.clients.delete(key);
|
|
3512
|
+
}
|
|
3513
|
+
await this.tombstoneStop(key, client);
|
|
3514
|
+
return this.getClient(root, server, signal);
|
|
3515
|
+
}
|
|
3516
|
+
this.markHealthyGeneration(key);
|
|
3388
3517
|
newManaged.refCount++;
|
|
3389
3518
|
newManaged.lastUsedAt = this.now();
|
|
3390
3519
|
return client;
|
|
@@ -3405,15 +3534,21 @@ class LspManager {
|
|
|
3405
3534
|
if (client && managed.client !== client)
|
|
3406
3535
|
return;
|
|
3407
3536
|
this.clients.delete(key);
|
|
3408
|
-
|
|
3537
|
+
this.tombstoneStop(key, managed.client);
|
|
3409
3538
|
}
|
|
3410
|
-
warmupClient(root,
|
|
3539
|
+
warmupClient(root, server) {
|
|
3411
3540
|
if (this.disposed)
|
|
3412
3541
|
return;
|
|
3413
|
-
const key = this.getKey(root,
|
|
3414
|
-
if (this.clients.has(key))
|
|
3542
|
+
const key = this.getKey(root, server.id);
|
|
3543
|
+
if (this.clients.has(key) || this.pendingStops.has(key))
|
|
3415
3544
|
return;
|
|
3416
|
-
|
|
3545
|
+
this.evictForAdmission();
|
|
3546
|
+
try {
|
|
3547
|
+
this.ensureRespawnAllowed(key, root, server.id);
|
|
3548
|
+
} catch {
|
|
3549
|
+
return;
|
|
3550
|
+
}
|
|
3551
|
+
const client = this.clientFactory(root, server);
|
|
3417
3552
|
const initStartedAt = this.now();
|
|
3418
3553
|
const initPromise = (async () => {
|
|
3419
3554
|
await client.start();
|
|
@@ -3438,7 +3573,7 @@ class LspManager {
|
|
|
3438
3573
|
if (this.clients.get(key) === managed) {
|
|
3439
3574
|
this.clients.delete(key);
|
|
3440
3575
|
}
|
|
3441
|
-
|
|
3576
|
+
this.tombstoneStop(key, client);
|
|
3442
3577
|
});
|
|
3443
3578
|
}
|
|
3444
3579
|
isServerInitializing(root, serverId) {
|
|
@@ -3482,8 +3617,11 @@ class LspManager {
|
|
|
3482
3617
|
for (const managed of this.clients.values()) {
|
|
3483
3618
|
stopPromises.push(stopClientBestEffort(managed.client));
|
|
3484
3619
|
}
|
|
3620
|
+
const tombstonedStops = [...this.pendingStops.values()];
|
|
3485
3621
|
this.clients.clear();
|
|
3486
|
-
|
|
3622
|
+
this.respawnBudgets.clear();
|
|
3623
|
+
await Promise.allSettled([...stopPromises, ...tombstonedStops]);
|
|
3624
|
+
this.pendingStops.clear();
|
|
3487
3625
|
}
|
|
3488
3626
|
}
|
|
3489
3627
|
var _defaultInstance = null;
|
|
@@ -3501,57 +3639,52 @@ async function disposeDefaultLspManager() {
|
|
|
3501
3639
|
}
|
|
3502
3640
|
}
|
|
3503
3641
|
|
|
3504
|
-
// ../lsp-core/src/lsp/
|
|
3505
|
-
import { existsSync as existsSync6,
|
|
3506
|
-
import { dirname as dirname5 } from "node:path";
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
|
|
3512
|
-
|
|
3513
|
-
|
|
3514
|
-
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
|
|
3518
|
-
|
|
3642
|
+
// ../lsp-core/src/lsp/outside-context-workspace.ts
|
|
3643
|
+
import { existsSync as existsSync6, realpathSync as realpathSync4 } from "node:fs";
|
|
3644
|
+
import { dirname as dirname5, join as join3 } from "node:path";
|
|
3645
|
+
|
|
3646
|
+
// ../lsp-core/src/lsp/workspace-markers.ts
|
|
3647
|
+
var GIT_WORKSPACE_MARKER = ".git";
|
|
3648
|
+
var PROJECT_WORKSPACE_MARKERS = [
|
|
3649
|
+
"package.json",
|
|
3650
|
+
"pyproject.toml",
|
|
3651
|
+
"Cargo.toml",
|
|
3652
|
+
"go.mod",
|
|
3653
|
+
"pom.xml",
|
|
3654
|
+
"build.gradle"
|
|
3655
|
+
];
|
|
3656
|
+
var WORKSPACE_MARKERS = [GIT_WORKSPACE_MARKER, ...PROJECT_WORKSPACE_MARKERS];
|
|
3657
|
+
|
|
3658
|
+
// ../lsp-core/src/lsp/outside-context-workspace.ts
|
|
3659
|
+
function findWorkspaceRootOutsideContext(directory) {
|
|
3660
|
+
const marked = nearestMarkedAncestor(directory);
|
|
3661
|
+
if (marked !== undefined)
|
|
3662
|
+
return marked;
|
|
3663
|
+
return realpathSync4(nearestExistingAncestor(directory));
|
|
3664
|
+
}
|
|
3665
|
+
function nearestMarkedAncestor(directory) {
|
|
3666
|
+
let current = directory;
|
|
3667
|
+
for (;; ) {
|
|
3668
|
+
if (existsSync6(current) && WORKSPACE_MARKERS.some((marker) => existsSync6(join3(current, marker)))) {
|
|
3669
|
+
return realpathSync4(current);
|
|
3670
|
+
}
|
|
3671
|
+
const parent = dirname5(current);
|
|
3672
|
+
if (parent === current)
|
|
3673
|
+
return;
|
|
3674
|
+
current = parent;
|
|
3519
3675
|
}
|
|
3520
3676
|
}
|
|
3521
|
-
function
|
|
3522
|
-
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
|
|
3526
|
-
|
|
3527
|
-
|
|
3528
|
-
}
|
|
3529
|
-
|
|
3530
|
-
return value === "declined" || value === "allowed";
|
|
3531
|
-
}
|
|
3532
|
-
function writeInstallDecisions(decisions) {
|
|
3533
|
-
const path = getInstallDecisionsPath();
|
|
3534
|
-
mkdirSync(dirname5(path), { recursive: true });
|
|
3535
|
-
const tmpPath = `${path}.tmp`;
|
|
3536
|
-
writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
|
|
3537
|
-
`, "utf8");
|
|
3538
|
-
renameSync2(tmpPath, path);
|
|
3539
|
-
}
|
|
3540
|
-
function isInstallDecisions(value) {
|
|
3541
|
-
return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
|
|
3542
|
-
}
|
|
3543
|
-
function isInstallDecisionRecord(value) {
|
|
3544
|
-
if (!isRecord5(value))
|
|
3545
|
-
return false;
|
|
3546
|
-
return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
|
|
3547
|
-
}
|
|
3548
|
-
function isRecord5(value) {
|
|
3549
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3677
|
+
function nearestExistingAncestor(directory) {
|
|
3678
|
+
let current = directory;
|
|
3679
|
+
while (!existsSync6(current)) {
|
|
3680
|
+
const parent = dirname5(current);
|
|
3681
|
+
if (parent === current)
|
|
3682
|
+
return current;
|
|
3683
|
+
current = parent;
|
|
3684
|
+
}
|
|
3685
|
+
return current;
|
|
3550
3686
|
}
|
|
3551
3687
|
|
|
3552
|
-
// ../lsp-core/src/lsp/config-loader.ts
|
|
3553
|
-
import { existsSync as existsSync7, readFileSync as readFileSync4 } from "node:fs";
|
|
3554
|
-
|
|
3555
3688
|
// ../lsp-core/src/lsp/server-definitions.ts
|
|
3556
3689
|
var LSP_INSTALL_HINTS = {
|
|
3557
3690
|
typescript: "npm install -g typescript-language-server typescript",
|
|
@@ -3597,6 +3730,26 @@ var LSP_INSTALL_HINTS = {
|
|
|
3597
3730
|
julials: `julia -e 'using Pkg; Pkg.add("LanguageServer")'`,
|
|
3598
3731
|
razor: "Razor runs through the Roslyn language server (cohosting). " + "Install: dotnet tool install -g roslyn-language-server --prerelease (requires v5.8.0+). See https://github.com/dotnet/razor"
|
|
3599
3732
|
};
|
|
3733
|
+
var LSP_LOCAL_INSTALL_HINTS = {
|
|
3734
|
+
typescript: "bun add -d typescript-language-server typescript",
|
|
3735
|
+
vue: "bun add -d @vue/language-server",
|
|
3736
|
+
eslint: "bun add -d vscode-langservers-extracted",
|
|
3737
|
+
oxlint: "bun add -d oxlint",
|
|
3738
|
+
biome: "bun add -d @biomejs/biome",
|
|
3739
|
+
svelte: "bun add -d svelte-language-server",
|
|
3740
|
+
astro: "bun add -d @astrojs/language-server",
|
|
3741
|
+
bash: "bun add -d bash-language-server",
|
|
3742
|
+
"bash-ls": "bun add -d bash-language-server",
|
|
3743
|
+
"yaml-ls": "bun add -d yaml-language-server",
|
|
3744
|
+
php: "bun add -d intelephense",
|
|
3745
|
+
prisma: "bun add -d prisma",
|
|
3746
|
+
dockerfile: "bun add -d dockerfile-language-server-nodejs",
|
|
3747
|
+
pyright: "uv add --dev pyright",
|
|
3748
|
+
basedpyright: "uv add --dev basedpyright",
|
|
3749
|
+
ruff: "uv add --dev ruff",
|
|
3750
|
+
ty: "uv add --dev ty",
|
|
3751
|
+
"ruby-lsp": "bundle add ruby-lsp --group development"
|
|
3752
|
+
};
|
|
3600
3753
|
var BUILTIN_SERVERS = {
|
|
3601
3754
|
typescript: {
|
|
3602
3755
|
command: ["typescript-language-server", "--stdio"],
|
|
@@ -3699,7 +3852,56 @@ var BUILTIN_SERVERS = {
|
|
|
3699
3852
|
}
|
|
3700
3853
|
};
|
|
3701
3854
|
|
|
3855
|
+
// ../lsp-core/src/lsp/server-install-state.ts
|
|
3856
|
+
import { existsSync as existsSync7, mkdirSync, readFileSync as readFileSync3, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
3857
|
+
import { dirname as dirname6 } from "node:path";
|
|
3858
|
+
function getInstallDecisionsPath() {
|
|
3859
|
+
return lspRequestContext().installDecisionsPath;
|
|
3860
|
+
}
|
|
3861
|
+
function loadInstallDecisions() {
|
|
3862
|
+
const path = getInstallDecisionsPath();
|
|
3863
|
+
if (!existsSync7(path))
|
|
3864
|
+
return {};
|
|
3865
|
+
try {
|
|
3866
|
+
const parsed = JSON.parse(readFileSync3(path, "utf8"));
|
|
3867
|
+
return isInstallDecisions(parsed) ? parsed : {};
|
|
3868
|
+
} catch {
|
|
3869
|
+
return {};
|
|
3870
|
+
}
|
|
3871
|
+
}
|
|
3872
|
+
function loadInstallDecision(serverId) {
|
|
3873
|
+
return loadInstallDecisions()[serverId];
|
|
3874
|
+
}
|
|
3875
|
+
function recordInstallDecision(serverId, decision, decidedAt = new Date().toISOString()) {
|
|
3876
|
+
const decisions = loadInstallDecisions();
|
|
3877
|
+
decisions[serverId] = { decision, decidedAt };
|
|
3878
|
+
writeInstallDecisions(decisions);
|
|
3879
|
+
}
|
|
3880
|
+
function isInstallDecision(value) {
|
|
3881
|
+
return value === "declined" || value === "allowed";
|
|
3882
|
+
}
|
|
3883
|
+
function writeInstallDecisions(decisions) {
|
|
3884
|
+
const path = getInstallDecisionsPath();
|
|
3885
|
+
mkdirSync(dirname6(path), { recursive: true });
|
|
3886
|
+
const tmpPath = `${path}.tmp`;
|
|
3887
|
+
writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
|
|
3888
|
+
`, "utf8");
|
|
3889
|
+
renameSync2(tmpPath, path);
|
|
3890
|
+
}
|
|
3891
|
+
function isInstallDecisions(value) {
|
|
3892
|
+
return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
|
|
3893
|
+
}
|
|
3894
|
+
function isInstallDecisionRecord(value) {
|
|
3895
|
+
if (!isRecord5(value))
|
|
3896
|
+
return false;
|
|
3897
|
+
return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
|
|
3898
|
+
}
|
|
3899
|
+
function isRecord5(value) {
|
|
3900
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3901
|
+
}
|
|
3902
|
+
|
|
3702
3903
|
// ../lsp-core/src/lsp/config-loader.ts
|
|
3904
|
+
import { existsSync as existsSync8, readFileSync as readFileSync4 } from "node:fs";
|
|
3703
3905
|
function getProjectConfigPaths() {
|
|
3704
3906
|
return lspRequestContext().projectConfigPaths;
|
|
3705
3907
|
}
|
|
@@ -3707,7 +3909,7 @@ function getUserConfigPath() {
|
|
|
3707
3909
|
return lspRequestContext().userConfigPath;
|
|
3708
3910
|
}
|
|
3709
3911
|
function loadJsonFile(path) {
|
|
3710
|
-
if (!
|
|
3912
|
+
if (!existsSync8(path))
|
|
3711
3913
|
return null;
|
|
3712
3914
|
try {
|
|
3713
3915
|
const parsed = JSON.parse(readFileSync4(path, "utf-8"));
|
|
@@ -3754,10 +3956,10 @@ function getMergedServers() {
|
|
|
3754
3956
|
}
|
|
3755
3957
|
if (seen.has(id))
|
|
3756
3958
|
continue;
|
|
3757
|
-
const
|
|
3758
|
-
if (!
|
|
3959
|
+
const server = createServerFromEntry(id, entry, source);
|
|
3960
|
+
if (!server)
|
|
3759
3961
|
continue;
|
|
3760
|
-
servers.push(
|
|
3962
|
+
servers.push(server);
|
|
3761
3963
|
seen.add(id);
|
|
3762
3964
|
}
|
|
3763
3965
|
}
|
|
@@ -3789,7 +3991,7 @@ function createServerFromEntry(id, entry, source) {
|
|
|
3789
3991
|
if (source === "project") {
|
|
3790
3992
|
if (!builtin)
|
|
3791
3993
|
return null;
|
|
3792
|
-
const
|
|
3994
|
+
const server = createServer({
|
|
3793
3995
|
id,
|
|
3794
3996
|
command: builtin.command,
|
|
3795
3997
|
extensions: entry.extensions ?? builtin.extensions,
|
|
@@ -3797,35 +3999,35 @@ function createServerFromEntry(id, entry, source) {
|
|
|
3797
3999
|
source
|
|
3798
4000
|
});
|
|
3799
4001
|
if (entry.initialization !== undefined) {
|
|
3800
|
-
|
|
4002
|
+
server.initialization = entry.initialization;
|
|
3801
4003
|
}
|
|
3802
|
-
return
|
|
4004
|
+
return server;
|
|
3803
4005
|
}
|
|
3804
4006
|
if (entry.command && entry.extensions) {
|
|
3805
|
-
const
|
|
4007
|
+
const server = createServer({
|
|
3806
4008
|
id,
|
|
3807
4009
|
command: entry.command,
|
|
3808
4010
|
extensions: entry.extensions,
|
|
3809
4011
|
priority: entry.priority ?? 0,
|
|
3810
4012
|
source
|
|
3811
4013
|
});
|
|
3812
|
-
applyOptionalServerFields(
|
|
3813
|
-
return
|
|
4014
|
+
applyOptionalServerFields(server, entry);
|
|
4015
|
+
return server;
|
|
3814
4016
|
}
|
|
3815
4017
|
if (!builtin)
|
|
3816
4018
|
return null;
|
|
3817
|
-
const
|
|
4019
|
+
const server = createServer({
|
|
3818
4020
|
id,
|
|
3819
4021
|
command: entry.command ?? builtin.command,
|
|
3820
4022
|
extensions: entry.extensions ?? builtin.extensions,
|
|
3821
4023
|
priority: entry.priority ?? 0,
|
|
3822
4024
|
source
|
|
3823
4025
|
});
|
|
3824
|
-
applyOptionalServerFields(
|
|
3825
|
-
return
|
|
4026
|
+
applyOptionalServerFields(server, entry);
|
|
4027
|
+
return server;
|
|
3826
4028
|
}
|
|
3827
4029
|
function createServer(input) {
|
|
3828
|
-
const
|
|
4030
|
+
const server = {
|
|
3829
4031
|
id: input.id,
|
|
3830
4032
|
command: input.command,
|
|
3831
4033
|
extensions: input.extensions,
|
|
@@ -3833,19 +4035,19 @@ function createServer(input) {
|
|
|
3833
4035
|
source: input.source
|
|
3834
4036
|
};
|
|
3835
4037
|
if (input.env !== undefined) {
|
|
3836
|
-
|
|
4038
|
+
server.env = input.env;
|
|
3837
4039
|
}
|
|
3838
4040
|
if (input.initialization !== undefined) {
|
|
3839
|
-
|
|
4041
|
+
server.initialization = input.initialization;
|
|
3840
4042
|
}
|
|
3841
|
-
return
|
|
4043
|
+
return server;
|
|
3842
4044
|
}
|
|
3843
|
-
function applyOptionalServerFields(
|
|
4045
|
+
function applyOptionalServerFields(server, entry) {
|
|
3844
4046
|
if (entry.env !== undefined) {
|
|
3845
|
-
|
|
4047
|
+
server.env = entry.env;
|
|
3846
4048
|
}
|
|
3847
4049
|
if (entry.initialization !== undefined) {
|
|
3848
|
-
|
|
4050
|
+
server.initialization = entry.initialization;
|
|
3849
4051
|
}
|
|
3850
4052
|
}
|
|
3851
4053
|
function isConfigJson(value) {
|
|
@@ -3895,64 +4097,165 @@ function getDisabledServerIds() {
|
|
|
3895
4097
|
}
|
|
3896
4098
|
|
|
3897
4099
|
// ../lsp-core/src/lsp/server-installation.ts
|
|
3898
|
-
import { existsSync as
|
|
3899
|
-
import { delimiter as delimiter3, join as
|
|
3900
|
-
|
|
3901
|
-
|
|
3902
|
-
|
|
3903
|
-
|
|
3904
|
-
|
|
3905
|
-
|
|
3906
|
-
|
|
3907
|
-
|
|
3908
|
-
|
|
4100
|
+
import { existsSync as existsSync9 } from "node:fs";
|
|
4101
|
+
import { delimiter as delimiter3, dirname as dirname7, isAbsolute as isAbsolute3, join as join4, resolve as resolve7 } from "node:path";
|
|
4102
|
+
var LOCAL_BIN_RULES = [
|
|
4103
|
+
{
|
|
4104
|
+
markers: ["package.json", "bun.lock", "bun.lockb", "package-lock.json", "yarn.lock", "pnpm-lock.yaml"],
|
|
4105
|
+
binDirs: [join4("node_modules", ".bin")]
|
|
4106
|
+
},
|
|
4107
|
+
{
|
|
4108
|
+
markers: [
|
|
4109
|
+
"pyproject.toml",
|
|
4110
|
+
"ty.toml",
|
|
4111
|
+
"requirements.txt",
|
|
4112
|
+
"setup.py",
|
|
4113
|
+
"setup.cfg",
|
|
4114
|
+
"Pipfile",
|
|
4115
|
+
"pyrightconfig.json",
|
|
4116
|
+
"ruff.toml",
|
|
4117
|
+
".ruff.toml"
|
|
4118
|
+
],
|
|
4119
|
+
binDirs: [
|
|
4120
|
+
join4(".venv", "bin"),
|
|
4121
|
+
join4(".venv", "Scripts"),
|
|
4122
|
+
join4("venv", "bin"),
|
|
4123
|
+
join4("venv", "Scripts"),
|
|
4124
|
+
join4(".env", "bin"),
|
|
4125
|
+
join4(".env", "Scripts")
|
|
4126
|
+
]
|
|
4127
|
+
},
|
|
4128
|
+
{
|
|
4129
|
+
markers: ["Gemfile", "Gemfile.lock"],
|
|
4130
|
+
binDirs: [join4("vendor", "bundle", "bin"), "bin"]
|
|
4131
|
+
},
|
|
4132
|
+
{
|
|
4133
|
+
markers: ["go.mod", "go.sum", "go.work"],
|
|
4134
|
+
binDirs: ["bin"]
|
|
3909
4135
|
}
|
|
3910
|
-
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
|
|
3915
|
-
|
|
3916
|
-
|
|
3917
|
-
|
|
3918
|
-
|
|
4136
|
+
];
|
|
4137
|
+
var resolutionCache = new Map;
|
|
4138
|
+
var probeCount = 0;
|
|
4139
|
+
function probe(path) {
|
|
4140
|
+
probeCount += 1;
|
|
4141
|
+
return existsSync9(path);
|
|
4142
|
+
}
|
|
4143
|
+
function executableSuffixes(platform, pathExt) {
|
|
4144
|
+
if (platform !== "win32")
|
|
4145
|
+
return [""];
|
|
4146
|
+
const configured = pathExt ?? process.env["PATHEXT"] ?? "";
|
|
4147
|
+
const systemExts = configured.split(";").filter((entry) => entry.length > 0).map((entry) => entry.toLowerCase());
|
|
4148
|
+
return [...new Set(["", ...systemExts, ".exe", ".cmd", ".bat", ".ps1"])];
|
|
4149
|
+
}
|
|
4150
|
+
function probeWithSuffixes(directory, command, suffixes) {
|
|
4151
|
+
for (const suffix of suffixes) {
|
|
4152
|
+
const candidate = join4(directory, command + suffix);
|
|
4153
|
+
if (probe(candidate))
|
|
4154
|
+
return candidate;
|
|
4155
|
+
}
|
|
4156
|
+
return null;
|
|
4157
|
+
}
|
|
4158
|
+
function resolveLocal(command, workingDirectory, suffixes, stopAt) {
|
|
4159
|
+
const boundary = stopAt === undefined ? undefined : resolve7(stopAt);
|
|
4160
|
+
let current = resolve7(workingDirectory);
|
|
4161
|
+
while (true) {
|
|
4162
|
+
for (const rule of LOCAL_BIN_RULES) {
|
|
4163
|
+
if (!rule.markers.some((marker) => probe(join4(current, marker))))
|
|
4164
|
+
continue;
|
|
4165
|
+
for (const binDir of rule.binDirs) {
|
|
4166
|
+
const found = probeWithSuffixes(join4(current, binDir), command, suffixes);
|
|
4167
|
+
if (found !== null)
|
|
4168
|
+
return found;
|
|
4169
|
+
}
|
|
3919
4170
|
}
|
|
4171
|
+
if (probe(join4(current, ".git")))
|
|
4172
|
+
return null;
|
|
4173
|
+
if (boundary !== undefined && current === boundary)
|
|
4174
|
+
return null;
|
|
4175
|
+
const parent = dirname7(current);
|
|
4176
|
+
if (parent === current)
|
|
4177
|
+
return null;
|
|
4178
|
+
current = parent;
|
|
3920
4179
|
}
|
|
3921
|
-
|
|
3922
|
-
|
|
4180
|
+
}
|
|
4181
|
+
function resolveFromPath(command, suffixes, platform, pathEnvOverride) {
|
|
4182
|
+
let pathEnv = pathEnvOverride ?? process.env["PATH"] ?? "";
|
|
4183
|
+
if (platform === "win32" && !pathEnv) {
|
|
3923
4184
|
pathEnv = process.env["Path"] ?? "";
|
|
3924
4185
|
}
|
|
3925
|
-
const
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
}
|
|
4186
|
+
for (const entry of pathEnv.split(delimiter3)) {
|
|
4187
|
+
if (entry.length === 0)
|
|
4188
|
+
continue;
|
|
4189
|
+
const found = probeWithSuffixes(entry, command, suffixes);
|
|
4190
|
+
if (found !== null)
|
|
4191
|
+
return found;
|
|
3932
4192
|
}
|
|
3933
|
-
|
|
3934
|
-
|
|
3935
|
-
|
|
4193
|
+
return null;
|
|
4194
|
+
}
|
|
4195
|
+
function resolveServerBinary(command, workingDirectory, options = {}) {
|
|
4196
|
+
if (command.length === 0)
|
|
4197
|
+
return null;
|
|
4198
|
+
const [cmd] = command;
|
|
4199
|
+
if (cmd === undefined || cmd.length === 0)
|
|
4200
|
+
return null;
|
|
4201
|
+
const platform = options.platform ?? process.platform;
|
|
4202
|
+
const suffixes = executableSuffixes(platform, options.pathExt);
|
|
4203
|
+
if (cmd.includes("/") || cmd.includes("\\")) {
|
|
4204
|
+
const explicit = isAbsolute3(cmd) ? cmd : resolve7(workingDirectory ?? process.cwd(), cmd);
|
|
4205
|
+
return probe(explicit) ? explicit : null;
|
|
4206
|
+
}
|
|
4207
|
+
const cacheKey = JSON.stringify([
|
|
4208
|
+
workingDirectory ?? "",
|
|
4209
|
+
cmd,
|
|
4210
|
+
platform,
|
|
4211
|
+
options.stopAt ?? "",
|
|
4212
|
+
options.pathExt ?? "",
|
|
4213
|
+
options.pathEnv ?? process.env["PATH"] ?? ""
|
|
4214
|
+
]);
|
|
4215
|
+
const cached = resolutionCache.get(cacheKey);
|
|
4216
|
+
if (cached !== undefined)
|
|
4217
|
+
return cached;
|
|
4218
|
+
let resolved = null;
|
|
4219
|
+
if (workingDirectory !== undefined && workingDirectory.length > 0) {
|
|
4220
|
+
resolved = resolveLocal(cmd, workingDirectory, suffixes, options.stopAt);
|
|
4221
|
+
}
|
|
4222
|
+
resolved ??= resolveFromPath(cmd, suffixes, platform, options.pathEnv);
|
|
4223
|
+
if (resolved === null && cmd === "node")
|
|
4224
|
+
resolved = cmd;
|
|
4225
|
+
resolutionCache.set(cacheKey, resolved);
|
|
4226
|
+
return resolved;
|
|
4227
|
+
}
|
|
4228
|
+
function isServerInstalled(command, workingDirectory, options = {}) {
|
|
4229
|
+
if (command.length === 0)
|
|
4230
|
+
return false;
|
|
4231
|
+
return resolveServerBinary(command, workingDirectory, options) !== null;
|
|
3936
4232
|
}
|
|
3937
4233
|
|
|
3938
4234
|
// ../lsp-core/src/lsp/server-resolution.ts
|
|
4235
|
+
function withResolvedCommand(command, binaryPath) {
|
|
4236
|
+
return [binaryPath, ...command.slice(1)];
|
|
4237
|
+
}
|
|
3939
4238
|
function findServerForExtension(ext) {
|
|
3940
4239
|
const servers = getMergedServers();
|
|
3941
|
-
|
|
3942
|
-
|
|
4240
|
+
const workingDirectory = contextCwd();
|
|
4241
|
+
for (const server of servers) {
|
|
4242
|
+
if (!server.extensions.includes(ext))
|
|
4243
|
+
continue;
|
|
4244
|
+
const binaryPath = resolveServerBinary(server.command, workingDirectory);
|
|
4245
|
+
if (binaryPath !== null) {
|
|
3943
4246
|
const resolvedServer = {
|
|
3944
|
-
id:
|
|
3945
|
-
command:
|
|
3946
|
-
extensions:
|
|
3947
|
-
priority:
|
|
4247
|
+
id: server.id,
|
|
4248
|
+
command: withResolvedCommand(server.command, binaryPath),
|
|
4249
|
+
extensions: server.extensions,
|
|
4250
|
+
priority: server.priority
|
|
3948
4251
|
};
|
|
3949
|
-
if (
|
|
4252
|
+
if (server.env !== undefined) {
|
|
3950
4253
|
return {
|
|
3951
4254
|
status: "found",
|
|
3952
4255
|
server: {
|
|
3953
4256
|
...resolvedServer,
|
|
3954
|
-
env:
|
|
3955
|
-
...
|
|
4257
|
+
env: server.env,
|
|
4258
|
+
...server.initialization === undefined ? {} : { initialization: server.initialization }
|
|
3956
4259
|
}
|
|
3957
4260
|
};
|
|
3958
4261
|
}
|
|
@@ -3960,20 +4263,20 @@ function findServerForExtension(ext) {
|
|
|
3960
4263
|
status: "found",
|
|
3961
4264
|
server: {
|
|
3962
4265
|
...resolvedServer,
|
|
3963
|
-
...
|
|
4266
|
+
...server.initialization === undefined ? {} : { initialization: server.initialization }
|
|
3964
4267
|
}
|
|
3965
4268
|
};
|
|
3966
4269
|
}
|
|
3967
4270
|
}
|
|
3968
|
-
for (const
|
|
3969
|
-
if (
|
|
3970
|
-
const installHint = LSP_INSTALL_HINTS[
|
|
4271
|
+
for (const server of servers) {
|
|
4272
|
+
if (server.extensions.includes(ext)) {
|
|
4273
|
+
const installHint = LSP_INSTALL_HINTS[server.id] ?? `Install '${server.command[0]}' and ensure it's in your PATH`;
|
|
3971
4274
|
return {
|
|
3972
4275
|
status: "not_installed",
|
|
3973
4276
|
server: {
|
|
3974
|
-
id:
|
|
3975
|
-
command:
|
|
3976
|
-
extensions:
|
|
4277
|
+
id: server.id,
|
|
4278
|
+
command: server.command,
|
|
4279
|
+
extensions: server.extensions
|
|
3977
4280
|
},
|
|
3978
4281
|
installHint
|
|
3979
4282
|
};
|
|
@@ -3989,20 +4292,21 @@ function findServerForExtension(ext) {
|
|
|
3989
4292
|
function getAllServers() {
|
|
3990
4293
|
const servers = getMergedServers();
|
|
3991
4294
|
const disabled = getDisabledServerIds();
|
|
4295
|
+
const workingDirectory = contextCwd();
|
|
3992
4296
|
const result = [];
|
|
3993
4297
|
const seen = new Set;
|
|
3994
|
-
for (const
|
|
3995
|
-
if (seen.has(
|
|
4298
|
+
for (const server of servers) {
|
|
4299
|
+
if (seen.has(server.id))
|
|
3996
4300
|
continue;
|
|
3997
4301
|
result.push({
|
|
3998
|
-
id:
|
|
3999
|
-
installed: isServerInstalled(
|
|
4000
|
-
extensions:
|
|
4302
|
+
id: server.id,
|
|
4303
|
+
installed: isServerInstalled(server.command, workingDirectory),
|
|
4304
|
+
extensions: server.extensions,
|
|
4001
4305
|
disabled: false,
|
|
4002
|
-
source:
|
|
4003
|
-
priority:
|
|
4306
|
+
source: server.source,
|
|
4307
|
+
priority: server.priority
|
|
4004
4308
|
});
|
|
4005
|
-
seen.add(
|
|
4309
|
+
seen.add(server.id);
|
|
4006
4310
|
}
|
|
4007
4311
|
for (const id of disabled) {
|
|
4008
4312
|
if (seen.has(id))
|
|
@@ -4010,7 +4314,7 @@ function getAllServers() {
|
|
|
4010
4314
|
const builtin = BUILTIN_SERVERS[id];
|
|
4011
4315
|
result.push({
|
|
4012
4316
|
id,
|
|
4013
|
-
installed: builtin ? isServerInstalled(builtin.command) : false,
|
|
4317
|
+
installed: builtin ? isServerInstalled(builtin.command, workingDirectory) : false,
|
|
4014
4318
|
extensions: builtin?.extensions ?? [],
|
|
4015
4319
|
disabled: true,
|
|
4016
4320
|
source: "disabled",
|
|
@@ -4021,7 +4325,6 @@ function getAllServers() {
|
|
|
4021
4325
|
}
|
|
4022
4326
|
|
|
4023
4327
|
// ../lsp-core/src/lsp/client-wrapper.ts
|
|
4024
|
-
var WORKSPACE_MARKERS = [".git", "package.json", "pyproject.toml", "Cargo.toml", "go.mod", "pom.xml", "build.gradle"];
|
|
4025
4328
|
function isDirectoryPath(filePath) {
|
|
4026
4329
|
try {
|
|
4027
4330
|
return statSync3(filePath).isDirectory();
|
|
@@ -4030,32 +4333,90 @@ function isDirectoryPath(filePath) {
|
|
|
4030
4333
|
}
|
|
4031
4334
|
}
|
|
4032
4335
|
function findWorkspaceRoot(filePath) {
|
|
4033
|
-
const
|
|
4336
|
+
const cwd = contextCwd();
|
|
4337
|
+
const abs = resolveReadablePathInsideContext(filePath);
|
|
4034
4338
|
let dir = abs;
|
|
4035
4339
|
if (!isDirectoryPath(dir)) {
|
|
4036
|
-
dir =
|
|
4037
|
-
}
|
|
4038
|
-
|
|
4039
|
-
|
|
4040
|
-
|
|
4041
|
-
|
|
4042
|
-
|
|
4340
|
+
dir = dirname8(dir);
|
|
4341
|
+
}
|
|
4342
|
+
if (!isPathInside(cwd, abs))
|
|
4343
|
+
return findWorkspaceRootOutsideContext(dir);
|
|
4344
|
+
const fallbackRoot = nearestExistingDirectoryInsideContext(dir, cwd) ?? cwd;
|
|
4345
|
+
let nearestPackageRoot;
|
|
4346
|
+
while (isPathInside(cwd, dir)) {
|
|
4347
|
+
const canonicalDir = existingDirectoryInsideContext(dir, cwd);
|
|
4348
|
+
if (canonicalDir !== undefined) {
|
|
4349
|
+
if (existsSync10(join5(dir, GIT_WORKSPACE_MARKER))) {
|
|
4350
|
+
return canonicalDir;
|
|
4351
|
+
}
|
|
4352
|
+
if (nearestPackageRoot === undefined && hasProjectWorkspaceMarker(dir)) {
|
|
4353
|
+
nearestPackageRoot = canonicalDir;
|
|
4043
4354
|
}
|
|
4044
4355
|
}
|
|
4045
|
-
|
|
4046
|
-
|
|
4356
|
+
if (dir === cwd)
|
|
4357
|
+
break;
|
|
4358
|
+
dir = dirname8(dir);
|
|
4047
4359
|
}
|
|
4048
|
-
return
|
|
4360
|
+
return nearestPackageRoot ?? fallbackRoot;
|
|
4361
|
+
}
|
|
4362
|
+
function hasProjectWorkspaceMarker(directory) {
|
|
4363
|
+
return PROJECT_WORKSPACE_MARKERS.some((marker) => existsSync10(join5(directory, marker)));
|
|
4364
|
+
}
|
|
4365
|
+
function resolveReadablePathInsideContext(filePath) {
|
|
4366
|
+
const cwd = contextCwd();
|
|
4367
|
+
const abs = resolve8(cwd, filePath);
|
|
4368
|
+
if (isPathInside(cwd, abs))
|
|
4369
|
+
return abs;
|
|
4370
|
+
const rebased = rebaseThroughCanonicalAncestor(abs, cwd);
|
|
4371
|
+
if (rebased !== undefined)
|
|
4372
|
+
return rebased;
|
|
4373
|
+
return canonicalizeExistingOrNearestAncestor(abs);
|
|
4049
4374
|
}
|
|
4050
4375
|
function resolvePathInsideContext(filePath) {
|
|
4051
4376
|
const cwd = contextCwd();
|
|
4052
|
-
const abs =
|
|
4377
|
+
const abs = resolveReadablePathInsideContext(filePath);
|
|
4053
4378
|
const canonical = canonicalizeExistingOrNearestAncestor(abs);
|
|
4054
4379
|
if (!isPathInside(cwd, canonical)) {
|
|
4055
4380
|
throw new LspInvalidPathError(`LSP file path must be inside request cwd: ${filePath}`);
|
|
4056
4381
|
}
|
|
4057
4382
|
return canonical;
|
|
4058
4383
|
}
|
|
4384
|
+
function rebaseThroughCanonicalAncestor(path, cwd) {
|
|
4385
|
+
let current = path;
|
|
4386
|
+
const suffix = [];
|
|
4387
|
+
while (true) {
|
|
4388
|
+
if (existsSync10(current)) {
|
|
4389
|
+
const canonical = realpathSync5(current);
|
|
4390
|
+
if (isPathInside(cwd, canonical))
|
|
4391
|
+
return suffix.length === 0 ? canonical : join5(canonical, ...suffix);
|
|
4392
|
+
}
|
|
4393
|
+
const parent = dirname8(current);
|
|
4394
|
+
if (parent === current)
|
|
4395
|
+
return;
|
|
4396
|
+
suffix.unshift(basename3(current));
|
|
4397
|
+
current = parent;
|
|
4398
|
+
}
|
|
4399
|
+
}
|
|
4400
|
+
function existingDirectoryInsideContext(directory, cwd) {
|
|
4401
|
+
if (!existsSync10(directory))
|
|
4402
|
+
return;
|
|
4403
|
+
const canonical = realpathSync5(directory);
|
|
4404
|
+
if (!statSync3(canonical).isDirectory())
|
|
4405
|
+
return;
|
|
4406
|
+
return isPathInside(cwd, canonical) ? canonical : undefined;
|
|
4407
|
+
}
|
|
4408
|
+
function nearestExistingDirectoryInsideContext(directory, cwd) {
|
|
4409
|
+
let current = directory;
|
|
4410
|
+
while (isPathInside(cwd, current)) {
|
|
4411
|
+
const canonical = existingDirectoryInsideContext(current, cwd);
|
|
4412
|
+
if (canonical !== undefined)
|
|
4413
|
+
return canonical;
|
|
4414
|
+
if (current === cwd)
|
|
4415
|
+
return;
|
|
4416
|
+
current = dirname8(current);
|
|
4417
|
+
}
|
|
4418
|
+
return;
|
|
4419
|
+
}
|
|
4059
4420
|
function formatServerLookupError(result) {
|
|
4060
4421
|
if (result.status === "not_installed") {
|
|
4061
4422
|
return formatNotInstalled(result);
|
|
@@ -4079,33 +4440,46 @@ function formatServerLookupError(result) {
|
|
|
4079
4440
|
].join(`
|
|
4080
4441
|
`);
|
|
4081
4442
|
}
|
|
4443
|
+
function formatInstallOptions(serverId, installHint) {
|
|
4444
|
+
const localHint = LSP_LOCAL_INSTALL_HINTS[serverId];
|
|
4445
|
+
if (localHint === undefined) {
|
|
4446
|
+
return ["To install, run:", ` ${installHint}`];
|
|
4447
|
+
}
|
|
4448
|
+
return [
|
|
4449
|
+
"To install in THIS repository (preferred — no global install needed):",
|
|
4450
|
+
` ${localHint}`,
|
|
4451
|
+
"",
|
|
4452
|
+
"Or install it globally:",
|
|
4453
|
+
` ${installHint}`
|
|
4454
|
+
];
|
|
4455
|
+
}
|
|
4082
4456
|
function formatNotInstalled(result) {
|
|
4083
|
-
const { server
|
|
4084
|
-
const extensions =
|
|
4085
|
-
const decision = loadInstallDecision(
|
|
4457
|
+
const { server, installHint } = result;
|
|
4458
|
+
const extensions = server.extensions.join(", ");
|
|
4459
|
+
const decision = loadInstallDecision(server.id)?.decision;
|
|
4086
4460
|
const context = lspRequestContext();
|
|
4087
4461
|
if (decision === "declined") {
|
|
4088
|
-
return `LSP server '${
|
|
4462
|
+
return `LSP server '${server.id}' (${extensions}) is NOT INSTALLED; user previously declined installation — proceed without LSP.`;
|
|
4089
4463
|
}
|
|
4090
4464
|
const header = [
|
|
4091
|
-
`LSP server '${
|
|
4465
|
+
`LSP server '${server.id}' for ${extensions} is NOT INSTALLED.`,
|
|
4092
4466
|
"",
|
|
4093
|
-
`Command not found: ${
|
|
4467
|
+
`Command not found: ${server.command[0]}`,
|
|
4094
4468
|
""
|
|
4095
4469
|
];
|
|
4470
|
+
const installOptions = formatInstallOptions(server.id, installHint);
|
|
4096
4471
|
if (decision === "allowed") {
|
|
4097
4472
|
return [
|
|
4098
4473
|
...header,
|
|
4099
4474
|
"The user has pre-authorized LSP installation. Run the install command, then retry this tool:",
|
|
4100
|
-
|
|
4475
|
+
...installOptions.slice(1)
|
|
4101
4476
|
].join(`
|
|
4102
4477
|
`);
|
|
4103
4478
|
}
|
|
4104
4479
|
if (!context.capabilities.installDecisionTool) {
|
|
4105
4480
|
return [
|
|
4106
4481
|
...header,
|
|
4107
|
-
|
|
4108
|
-
` ${installHint}`,
|
|
4482
|
+
...installOptions,
|
|
4109
4483
|
"",
|
|
4110
4484
|
"ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
|
|
4111
4485
|
"Install-decision recording is unavailable in this harness; proceed without LSP if the user declines."
|
|
@@ -4114,19 +4488,18 @@ function formatNotInstalled(result) {
|
|
|
4114
4488
|
}
|
|
4115
4489
|
return [
|
|
4116
4490
|
...header,
|
|
4117
|
-
|
|
4118
|
-
` ${installHint}`,
|
|
4491
|
+
...installOptions,
|
|
4119
4492
|
"",
|
|
4120
4493
|
"ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
|
|
4121
4494
|
"- If the user agrees: run the install command above, then retry this tool.",
|
|
4122
4495
|
"- If the user declines, OR has NOT explicitly asked for LSP installation:",
|
|
4123
|
-
` call lsp_install_decision { server_id: "${
|
|
4496
|
+
` call lsp_install_decision { server_id: "${server.id}", decision: "declined" },`,
|
|
4124
4497
|
` which writes to ${context.installDecisionsPath},`,
|
|
4125
4498
|
" then ignore this message and proceed WITHOUT LSP."
|
|
4126
4499
|
].join(`
|
|
4127
4500
|
`);
|
|
4128
4501
|
}
|
|
4129
|
-
var
|
|
4502
|
+
var READ_ONLY_TOOLS = new Set([
|
|
4130
4503
|
"diagnostics",
|
|
4131
4504
|
"definition",
|
|
4132
4505
|
"references",
|
|
@@ -4135,7 +4508,7 @@ var READ_ONLY_RETRY_TOOLS = new Set([
|
|
|
4135
4508
|
"prepareRename"
|
|
4136
4509
|
]);
|
|
4137
4510
|
async function withLspClient(filePath, fn, toolName, options = {}) {
|
|
4138
|
-
const absPath = resolvePathInsideContext(filePath);
|
|
4511
|
+
const absPath = READ_ONLY_TOOLS.has(toolName) ? resolveReadablePathInsideContext(filePath) : resolvePathInsideContext(filePath);
|
|
4139
4512
|
if (isDirectoryPath(absPath)) {
|
|
4140
4513
|
throw new LspInvalidPathError("Directory paths are not supported by this LSP tool. " + "Use lsp.diagnostics with a directory path for directory diagnostics.");
|
|
4141
4514
|
}
|
|
@@ -4144,34 +4517,34 @@ async function withLspClient(filePath, fn, toolName, options = {}) {
|
|
|
4144
4517
|
if (result.status !== "found") {
|
|
4145
4518
|
throw new LspServerLookupError(formatServerLookupError(result), result);
|
|
4146
4519
|
}
|
|
4147
|
-
const
|
|
4520
|
+
const server = result.server;
|
|
4148
4521
|
const root = findWorkspaceRoot(absPath);
|
|
4149
4522
|
const manager = options.manager ?? getLspManager();
|
|
4150
4523
|
const acquireAndCall = async (allowRetry) => {
|
|
4151
|
-
const client = await manager.getClient(root,
|
|
4524
|
+
const client = await manager.getClient(root, server, options.signal);
|
|
4152
4525
|
try {
|
|
4153
|
-
return await fn(client, root);
|
|
4526
|
+
return await fn(client, root, absPath);
|
|
4154
4527
|
} catch (err) {
|
|
4155
|
-
if (allowRetry &&
|
|
4156
|
-
manager.invalidateClient(root,
|
|
4528
|
+
if (allowRetry && READ_ONLY_TOOLS.has(toolName) && isLspDeadConnectionError(err)) {
|
|
4529
|
+
manager.invalidateClient(root, server.id, client);
|
|
4157
4530
|
return acquireAndCall(false);
|
|
4158
4531
|
}
|
|
4159
4532
|
if (err instanceof LspRequestTimeoutError) {
|
|
4160
|
-
if (manager.isServerInitializing(root,
|
|
4533
|
+
if (manager.isServerInitializing(root, server.id)) {
|
|
4161
4534
|
throw new LspServerInitializingError(err);
|
|
4162
4535
|
}
|
|
4163
4536
|
}
|
|
4164
4537
|
throw err;
|
|
4165
4538
|
} finally {
|
|
4166
|
-
manager.releaseClient(root,
|
|
4539
|
+
manager.releaseClient(root, server.id);
|
|
4167
4540
|
}
|
|
4168
4541
|
};
|
|
4169
4542
|
return acquireAndCall(true);
|
|
4170
4543
|
}
|
|
4171
4544
|
|
|
4172
4545
|
// ../lsp-core/src/lsp/directory-diagnostics.ts
|
|
4173
|
-
import { existsSync as
|
|
4174
|
-
import { join as
|
|
4546
|
+
import { existsSync as existsSync11, lstatSync as lstatSync4, readdirSync as readdirSync3 } from "node:fs";
|
|
4547
|
+
import { join as join6, resolve as resolve9 } from "node:path";
|
|
4175
4548
|
|
|
4176
4549
|
// ../lsp-core/src/lsp/formatters.ts
|
|
4177
4550
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
@@ -4186,10 +4559,10 @@ function uriToPath(uri) {
|
|
|
4186
4559
|
}
|
|
4187
4560
|
function formatLocation(loc) {
|
|
4188
4561
|
if ("targetUri" in loc) {
|
|
4189
|
-
const
|
|
4190
|
-
const
|
|
4191
|
-
const
|
|
4192
|
-
return `${
|
|
4562
|
+
const uri = uriToPath(loc.targetUri);
|
|
4563
|
+
const line = loc.targetRange.start.line + 1;
|
|
4564
|
+
const char = loc.targetRange.start.character;
|
|
4565
|
+
return `${uri}:${line}:${char}`;
|
|
4193
4566
|
}
|
|
4194
4567
|
const uri = uriToPath(loc.uri);
|
|
4195
4568
|
const line = loc.range.start.line + 1;
|
|
@@ -4301,7 +4674,7 @@ function collectFilesWithExtension(dir, extension, maxFiles) {
|
|
|
4301
4674
|
for (const entry of entries) {
|
|
4302
4675
|
if (files.length >= maxFiles)
|
|
4303
4676
|
return;
|
|
4304
|
-
const fullPath =
|
|
4677
|
+
const fullPath = join6(currentDir, entry);
|
|
4305
4678
|
let stat;
|
|
4306
4679
|
try {
|
|
4307
4680
|
stat = lstatSync4(fullPath);
|
|
@@ -4326,15 +4699,15 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
|
|
|
4326
4699
|
if (!extension.startsWith(".")) {
|
|
4327
4700
|
throw new LspInvalidPathError(`Extension must start with a dot (e.g., ".ts", not "${extension}"). Use ".${extension}" instead.`);
|
|
4328
4701
|
}
|
|
4329
|
-
const absDir =
|
|
4330
|
-
if (!
|
|
4702
|
+
const absDir = resolve9(options.workspaceRoot ?? contextCwd(), directory);
|
|
4703
|
+
if (!existsSync11(absDir)) {
|
|
4331
4704
|
throw new LspInvalidPathError(`Directory does not exist: ${absDir}`);
|
|
4332
4705
|
}
|
|
4333
4706
|
const serverResult = options.server === undefined ? findServerForExtension(extension) : { status: "found", server: options.server };
|
|
4334
4707
|
if (serverResult.status !== "found") {
|
|
4335
4708
|
throw new LspServerLookupError(formatServerLookupError(serverResult));
|
|
4336
4709
|
}
|
|
4337
|
-
const
|
|
4710
|
+
const server = serverResult.server;
|
|
4338
4711
|
const allFiles = (options.listFiles ?? collectFilesWithExtension)(absDir, extension, maxFiles + 1);
|
|
4339
4712
|
const wasCapped = allFiles.length > maxFiles;
|
|
4340
4713
|
const filesToProcess = allFiles.slice(0, maxFiles);
|
|
@@ -4354,7 +4727,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
|
|
|
4354
4727
|
const fileErrors = [];
|
|
4355
4728
|
const maxConcurrency = Math.max(1, options.maxConcurrency ?? DIRECTORY_DIAGNOSTICS_MAX_CONCURRENCY);
|
|
4356
4729
|
options.signal?.throwIfAborted();
|
|
4357
|
-
const client = await manager.getClient(root,
|
|
4730
|
+
const client = await manager.getClient(root, server, options.signal);
|
|
4358
4731
|
try {
|
|
4359
4732
|
let nextIndex = 0;
|
|
4360
4733
|
const workers = Array.from({ length: Math.min(maxConcurrency, filesToProcess.length) }, async () => {
|
|
@@ -4382,7 +4755,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
|
|
|
4382
4755
|
});
|
|
4383
4756
|
await Promise.all(workers);
|
|
4384
4757
|
} finally {
|
|
4385
|
-
manager.releaseClient(root,
|
|
4758
|
+
manager.releaseClient(root, server.id);
|
|
4386
4759
|
}
|
|
4387
4760
|
const displayDiagnostics = allDiagnostics.slice(0, DEFAULT_MAX_DIAGNOSTICS);
|
|
4388
4761
|
const wasDiagCapped = allDiagnostics.length > DEFAULT_MAX_DIAGNOSTICS;
|
|
@@ -4414,7 +4787,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
|
|
|
4414
4787
|
|
|
4415
4788
|
// ../lsp-core/src/lsp/infer-extension.ts
|
|
4416
4789
|
import { lstatSync as lstatSync5, readdirSync as readdirSync4 } from "node:fs";
|
|
4417
|
-
import { join as
|
|
4790
|
+
import { join as join7 } from "node:path";
|
|
4418
4791
|
var SKIP_DIRECTORIES2 = new Set(["node_modules", ".git", "dist", "build", ".next", "out"]);
|
|
4419
4792
|
var MAX_SCAN_ENTRIES = 500;
|
|
4420
4793
|
function inferExtensionFromDirectory(directory) {
|
|
@@ -4432,7 +4805,7 @@ function inferExtensionFromDirectory(directory) {
|
|
|
4432
4805
|
for (const entry of entries) {
|
|
4433
4806
|
if (scanned >= MAX_SCAN_ENTRIES)
|
|
4434
4807
|
return;
|
|
4435
|
-
const fullPath =
|
|
4808
|
+
const fullPath = join7(dir, entry);
|
|
4436
4809
|
let stat;
|
|
4437
4810
|
try {
|
|
4438
4811
|
stat = lstatSync5(fullPath);
|
|
@@ -4591,8 +4964,8 @@ function clientOptions(signal) {
|
|
|
4591
4964
|
}
|
|
4592
4965
|
|
|
4593
4966
|
// ../lsp-core/src/tools/result.ts
|
|
4594
|
-
function text(
|
|
4595
|
-
return { content: [{ type: "text", text
|
|
4967
|
+
function text(text, details, isError = false) {
|
|
4968
|
+
return { content: [{ type: "text", text }], details, isError };
|
|
4596
4969
|
}
|
|
4597
4970
|
|
|
4598
4971
|
// ../lsp-core/src/tools/diagnostics.ts
|
|
@@ -4607,12 +4980,12 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
4607
4980
|
const filePath = requireString(params, "filePath");
|
|
4608
4981
|
const severity = severityFilter(params);
|
|
4609
4982
|
try {
|
|
4610
|
-
const absPath =
|
|
4983
|
+
const absPath = resolveReadablePathInsideContext(filePath);
|
|
4611
4984
|
if (isDirectoryPath(absPath)) {
|
|
4612
4985
|
const extension = inferExtensionFromDirectory(absPath);
|
|
4613
4986
|
if (!extension) {
|
|
4614
4987
|
const message = `No supported source files found in directory: ${absPath}`;
|
|
4615
|
-
const
|
|
4988
|
+
const details = {
|
|
4616
4989
|
filePath,
|
|
4617
4990
|
severity,
|
|
4618
4991
|
mode: "directory",
|
|
@@ -4622,24 +4995,24 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
4622
4995
|
error: message,
|
|
4623
4996
|
errorKind: "no_files"
|
|
4624
4997
|
};
|
|
4625
|
-
return text(message,
|
|
4998
|
+
return text(message, details);
|
|
4626
4999
|
}
|
|
4627
|
-
const
|
|
4628
|
-
const
|
|
5000
|
+
const output = await aggregateDiagnosticsForDirectory(absPath, extension, severity, undefined, signal === undefined ? {} : { signal });
|
|
5001
|
+
const details = {
|
|
4629
5002
|
filePath,
|
|
4630
5003
|
severity,
|
|
4631
5004
|
mode: "directory",
|
|
4632
5005
|
diagnostics: [],
|
|
4633
|
-
totalDiagnostics:
|
|
5006
|
+
totalDiagnostics: output.totalDiagnostics,
|
|
4634
5007
|
truncated: false,
|
|
4635
|
-
fileFailures: [...
|
|
5008
|
+
fileFailures: [...output.fileFailures]
|
|
4636
5009
|
};
|
|
4637
|
-
return text(
|
|
5010
|
+
return text(output.output, details);
|
|
4638
5011
|
}
|
|
4639
|
-
const result = await withLspClient(filePath, async (client) => client.diagnostics(
|
|
5012
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.diagnostics(resolvedFilePath, signal), "diagnostics", clientOptions(signal));
|
|
4640
5013
|
if (result.transientError) {
|
|
4641
5014
|
const message = result.transientError.message;
|
|
4642
|
-
const
|
|
5015
|
+
const details = {
|
|
4643
5016
|
filePath,
|
|
4644
5017
|
severity,
|
|
4645
5018
|
mode: "file",
|
|
@@ -4649,7 +5022,7 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
4649
5022
|
error: message,
|
|
4650
5023
|
errorKind: result.transientError.kind
|
|
4651
5024
|
};
|
|
4652
|
-
return text(message,
|
|
5025
|
+
return text(message, details, true);
|
|
4653
5026
|
}
|
|
4654
5027
|
const diagnostics = filterDiagnosticsBySeverity(asDiagnosticArray(result), severity);
|
|
4655
5028
|
const total = diagnostics.length;
|
|
@@ -4683,6 +5056,96 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
4683
5056
|
throw error;
|
|
4684
5057
|
}
|
|
4685
5058
|
}
|
|
5059
|
+
// ../lsp-core/src/lsp/format-document.ts
|
|
5060
|
+
import { readFileSync as readFileSync5, renameSync as renameSync3, unlinkSync, writeFileSync as writeFileSync3 } from "node:fs";
|
|
5061
|
+
var DEFAULT_FORMATTING_OPTIONS = {
|
|
5062
|
+
tabSize: 4,
|
|
5063
|
+
insertSpaces: false,
|
|
5064
|
+
trimTrailingWhitespace: true,
|
|
5065
|
+
insertFinalNewline: true,
|
|
5066
|
+
trimFinalNewlines: true
|
|
5067
|
+
};
|
|
5068
|
+
var UNCHANGED = { status: "unchanged", linesAdded: 0, linesRemoved: 0 };
|
|
5069
|
+
async function formatDocumentWithClient(client, filePath, options = {}) {
|
|
5070
|
+
const edits = await client.formatDocument(filePath, options.formattingOptions ?? DEFAULT_FORMATTING_OPTIONS, options.signal);
|
|
5071
|
+
if (edits === null)
|
|
5072
|
+
return { status: "unavailable", reason: "capability_not_advertised" };
|
|
5073
|
+
if (edits.length === 0)
|
|
5074
|
+
return UNCHANGED;
|
|
5075
|
+
const before = readFileSync5(filePath, "utf-8");
|
|
5076
|
+
const normalized = normalizeTextEdits(before, edits, 0);
|
|
5077
|
+
if (normalized.text === before)
|
|
5078
|
+
return UNCHANGED;
|
|
5079
|
+
writeAtomically(filePath, normalized.text);
|
|
5080
|
+
await client.openFile(filePath);
|
|
5081
|
+
return {
|
|
5082
|
+
status: "formatted",
|
|
5083
|
+
...lineDelta(normalized.edits)
|
|
5084
|
+
};
|
|
5085
|
+
}
|
|
5086
|
+
function lineDelta(edits) {
|
|
5087
|
+
let linesAdded = 0;
|
|
5088
|
+
let linesRemoved = 0;
|
|
5089
|
+
for (const edit of edits) {
|
|
5090
|
+
linesRemoved += edit.range.end.line - edit.range.start.line + 1;
|
|
5091
|
+
linesAdded += edit.newText.split(`
|
|
5092
|
+
`).length;
|
|
5093
|
+
}
|
|
5094
|
+
return { linesAdded, linesRemoved };
|
|
5095
|
+
}
|
|
5096
|
+
function writeAtomically(filePath, content) {
|
|
5097
|
+
const tempPath = `${filePath}.omo-format.tmp`;
|
|
5098
|
+
writeFileSync3(tempPath, content, "utf-8");
|
|
5099
|
+
try {
|
|
5100
|
+
renameSync3(tempPath, filePath);
|
|
5101
|
+
} catch (error) {
|
|
5102
|
+
try {
|
|
5103
|
+
unlinkSync(tempPath);
|
|
5104
|
+
} catch {}
|
|
5105
|
+
throw error;
|
|
5106
|
+
}
|
|
5107
|
+
}
|
|
5108
|
+
|
|
5109
|
+
// ../lsp-core/src/tools/format.ts
|
|
5110
|
+
async function executeLspFormat(params, signal) {
|
|
5111
|
+
const filePath = requireString(params, "filePath");
|
|
5112
|
+
try {
|
|
5113
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => formatDocumentWithClient(client, resolvedFilePath, signal === undefined ? {} : { signal }), "format", clientOptions(signal));
|
|
5114
|
+
return text(describeResult(filePath, result), formatDetails(filePath, result));
|
|
5115
|
+
} catch (error) {
|
|
5116
|
+
const missingDependency = missingDependencyResult(error, {
|
|
5117
|
+
filePath,
|
|
5118
|
+
status: "unavailable",
|
|
5119
|
+
reason: "server_unavailable",
|
|
5120
|
+
linesAdded: 0,
|
|
5121
|
+
linesRemoved: 0
|
|
5122
|
+
});
|
|
5123
|
+
if (missingDependency)
|
|
5124
|
+
return missingDependency;
|
|
5125
|
+
throw error;
|
|
5126
|
+
}
|
|
5127
|
+
}
|
|
5128
|
+
function formatDetails(filePath, result) {
|
|
5129
|
+
if (result.status === "unavailable") {
|
|
5130
|
+
return { filePath, status: "unavailable", reason: result.reason, linesAdded: 0, linesRemoved: 0 };
|
|
5131
|
+
}
|
|
5132
|
+
return {
|
|
5133
|
+
filePath,
|
|
5134
|
+
status: result.status,
|
|
5135
|
+
linesAdded: result.linesAdded,
|
|
5136
|
+
linesRemoved: result.linesRemoved
|
|
5137
|
+
};
|
|
5138
|
+
}
|
|
5139
|
+
function describeResult(filePath, result) {
|
|
5140
|
+
if (result.status === "unavailable") {
|
|
5141
|
+
return `Formatting unavailable for ${filePath}: the language server does not advertise documentFormattingProvider.`;
|
|
5142
|
+
}
|
|
5143
|
+
if (result.status === "unchanged") {
|
|
5144
|
+
return `Already formatted: ${filePath}`;
|
|
5145
|
+
}
|
|
5146
|
+
return `Formatted ${filePath} (+${result.linesAdded}/-${result.linesRemoved} lines)`;
|
|
5147
|
+
}
|
|
5148
|
+
|
|
4686
5149
|
// ../lsp-core/src/tools/install-decision.ts
|
|
4687
5150
|
async function executeLspInstallDecision(params) {
|
|
4688
5151
|
const serverId = requireString(params, "server_id");
|
|
@@ -4690,7 +5153,7 @@ async function executeLspInstallDecision(params) {
|
|
|
4690
5153
|
if (!isInstallDecision(decision)) {
|
|
4691
5154
|
return text(`Invalid decision '${String(decision)}'. Expected "declined" or "allowed".`, { serverId, errorKind: "invalid_decision" }, true);
|
|
4692
5155
|
}
|
|
4693
|
-
const serverIds = [...new Set(getMergedServers().map((
|
|
5156
|
+
const serverIds = [...new Set(getMergedServers().map((server) => server.id))];
|
|
4694
5157
|
if (!serverIds.includes(serverId)) {
|
|
4695
5158
|
const preview = serverIds.slice(0, 20).join(", ");
|
|
4696
5159
|
return text(`Unknown LSP server '${serverId}'. Known servers: ${preview}${serverIds.length > 20 ? "..." : ""}`, { serverId, errorKind: "unknown_server" }, true);
|
|
@@ -4711,7 +5174,7 @@ async function executeLspGotoDefinition(params, signal) {
|
|
|
4711
5174
|
const line = requireNumber(params, "line");
|
|
4712
5175
|
const character = requireNumber(params, "character");
|
|
4713
5176
|
try {
|
|
4714
|
-
const result = await withLspClient(filePath, async (client) => client.definition(
|
|
5177
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.definition(resolvedFilePath, line, character, signal), "definition", clientOptions(signal));
|
|
4715
5178
|
const locations = !result ? [] : Array.isArray(result) ? result : [result];
|
|
4716
5179
|
const details = { filePath, line, character, locations };
|
|
4717
5180
|
if (locations.length === 0)
|
|
@@ -4736,7 +5199,7 @@ async function executeLspFindReferences(params, signal) {
|
|
|
4736
5199
|
const character = requireNumber(params, "character");
|
|
4737
5200
|
const includeDeclaration = optionalBoolean(params, "includeDeclaration") ?? true;
|
|
4738
5201
|
try {
|
|
4739
|
-
const result = await withLspClient(filePath, async (client) => client.references(
|
|
5202
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.references(resolvedFilePath, line, character, includeDeclaration, signal), "references", clientOptions(signal));
|
|
4740
5203
|
const references = Array.isArray(result) ? result : [];
|
|
4741
5204
|
const total = references.length;
|
|
4742
5205
|
const truncated = total > DEFAULT_MAX_REFERENCES;
|
|
@@ -4778,7 +5241,7 @@ async function executeLspPrepareRename(params, signal) {
|
|
|
4778
5241
|
const line = requireNumber(params, "line");
|
|
4779
5242
|
const character = requireNumber(params, "character");
|
|
4780
5243
|
try {
|
|
4781
|
-
const result = await withLspClient(filePath, async (client) => client.prepareRename(
|
|
5244
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.prepareRename(resolvedFilePath, line, character, signal), "prepareRename", clientOptions(signal));
|
|
4782
5245
|
const details = { filePath, line, character, result };
|
|
4783
5246
|
return text(formatPrepareRenameResult(result), details);
|
|
4784
5247
|
} catch (error) {
|
|
@@ -4799,7 +5262,7 @@ async function executeLspRename(params, signal) {
|
|
|
4799
5262
|
const character = requireNumber(params, "character");
|
|
4800
5263
|
const newName = requireString(params, "newName");
|
|
4801
5264
|
try {
|
|
4802
|
-
const result = await withLspClient(filePath, async (client) => client.rename(
|
|
5265
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.rename(resolvedFilePath, line, character, newName, signal), "rename", clientOptions(signal));
|
|
4803
5266
|
const details = { filePath, line, character, newName, apply: result.apply, edit: result.edit };
|
|
4804
5267
|
return text(formatApplyResult(result.apply), details, !result.apply.success);
|
|
4805
5268
|
} catch (error) {
|
|
@@ -4830,10 +5293,10 @@ function objectSchema(properties, required = []) {
|
|
|
4830
5293
|
async function executeLspStatus() {
|
|
4831
5294
|
const servers = getAllServers();
|
|
4832
5295
|
const snapshots = getLspManager().getSnapshot();
|
|
4833
|
-
const installed = servers.filter((
|
|
4834
|
-
const configuredLines = servers.map((
|
|
4835
|
-
const state =
|
|
4836
|
-
return `- ${
|
|
5296
|
+
const installed = servers.filter((server) => server.installed && !server.disabled);
|
|
5297
|
+
const configuredLines = servers.map((server) => {
|
|
5298
|
+
const state = server.disabled ? "disabled" : server.installed ? "installed" : "missing";
|
|
5299
|
+
return `- ${server.id}: ${state}; source=${server.source}; extensions=${server.extensions.join(", ")}`;
|
|
4837
5300
|
});
|
|
4838
5301
|
const activeLines = snapshots.map((snapshot) => {
|
|
4839
5302
|
const state = snapshot.alive ? snapshot.isInitializing ? "initializing" : "alive" : "dead";
|
|
@@ -4876,10 +5339,10 @@ async function executeLspSymbols(params, signal) {
|
|
|
4876
5339
|
errorKind: "missing_query"
|
|
4877
5340
|
});
|
|
4878
5341
|
}
|
|
4879
|
-
const
|
|
4880
|
-
return formatSymbolsResult(filePath, scope,
|
|
5342
|
+
const symbols = await withLspClient(filePath, async (client) => client.workspaceSymbols(query, signal), "workspaceSymbols", clientOptions(signal));
|
|
5343
|
+
return formatSymbolsResult(filePath, scope, symbols, limit, query);
|
|
4881
5344
|
}
|
|
4882
|
-
const symbols = await withLspClient(filePath, async (client) => client.documentSymbols(
|
|
5345
|
+
const symbols = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.documentSymbols(resolvedFilePath, signal), "documentSymbols", clientOptions(signal));
|
|
4883
5346
|
return formatSymbolsResult(filePath, scope, symbols, limit);
|
|
4884
5347
|
} catch (error) {
|
|
4885
5348
|
const query = optionalString(params, "query");
|
|
@@ -5015,6 +5478,16 @@ var LSP_MCP_TOOLS = [
|
|
|
5015
5478
|
}, ["filePath", "line", "character", "newName"]),
|
|
5016
5479
|
execute: executeLspRename
|
|
5017
5480
|
},
|
|
5481
|
+
{
|
|
5482
|
+
name: "format",
|
|
5483
|
+
aliases: ["lsp_format"],
|
|
5484
|
+
title: "LSP Format",
|
|
5485
|
+
description: "Format a source file with its language server and write the returned edits to disk.",
|
|
5486
|
+
inputSchema: objectSchema({
|
|
5487
|
+
filePath: { type: "string", description: "Source file path to format." }
|
|
5488
|
+
}, ["filePath"]),
|
|
5489
|
+
execute: executeLspFormat
|
|
5490
|
+
},
|
|
5018
5491
|
{
|
|
5019
5492
|
name: "install_decision",
|
|
5020
5493
|
aliases: ["lsp_install_decision"],
|
|
@@ -5122,6 +5595,6 @@ function requestedProtocolVersion(params) {
|
|
|
5122
5595
|
return params["protocolVersion"];
|
|
5123
5596
|
}
|
|
5124
5597
|
export {
|
|
5125
|
-
|
|
5126
|
-
|
|
5598
|
+
handleLspMcpRequest,
|
|
5599
|
+
runMcpStdioServer
|
|
5127
5600
|
};
|