oh-my-opencode 5.0.0-beta.6 → 5.0.0-beta.60
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 +59 -23
- 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 +59 -23
- 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 +59 -23
- package/.opencode/skills/pre-publish-review/SKILL.md +9 -12
- package/.opencode/skills/work-with-pr/SKILL.md +37 -23
- package/README.ja.md +65 -60
- package/README.ko.md +66 -61
- package/README.md +65 -72
- package/README.ru.md +62 -60
- package/README.zh-cn.md +61 -60
- 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/index.d.ts +2 -0
- package/dist/cli/doctor/checks/latest-version.d.ts +11 -0
- package/dist/cli/doctor/checks/system-plugin.d.ts +4 -3
- package/dist/cli/doctor/framework/constants.d.ts +5 -0
- package/dist/cli/doctor/framework/types.d.ts +2 -0
- package/dist/cli/fallback-lane-policy.d.ts +1 -0
- package/dist/cli/index.js +51738 -59690
- 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 +50900 -58829
- 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 +9 -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/background-agent/types.d.ts +4 -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/claude-tasks/storage.d.ts +7 -2
- package/dist/features/hook-message-injector/index.d.ts +1 -0
- package/dist/features/hook-message-injector/sdk-message-lookup.d.ts +1 -0
- package/dist/features/monitor/manager-internals.d.ts +1 -1
- package/dist/features/monitor/output-injector-types.d.ts +1 -1
- package/dist/features/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 +9 -0
- package/dist/hooks/keyword-detector/ultrawork/index.d.ts +2 -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/hooks/unstable-agent-babysitter/task-message-analyzer.d.ts +1 -0
- package/dist/index.js +29256 -25391
- 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 +6 -4
- 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/stop-continuation.d.ts +3 -0
- package/dist/plugin/system-transform.d.ts +5 -1
- 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 +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/ATTRIBUTION.md +10 -0
- package/dist/skills/frontend/SKILL.md +15 -8
- package/dist/skills/frontend/references/design/README.md +10 -2
- package/dist/skills/frontend/references/design/_INDEX.md +2 -0
- package/dist/skills/frontend/references/design/ambience-skill.md +145 -0
- package/dist/skills/frontend/references/design/interaction-skill.md +2 -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 +4 -4
- package/dist/skills/remove-ai-slops/SKILL.md +1 -1
- package/dist/skills/review-work/SKILL.md +101 -419
- 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 +20 -19
- 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-plan/scripts/scaffold-plan.mjs +1 -1
- 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 +37048 -46599
- 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 +103 -6
- package/packages/lsp-core/src/lsp/client-wrapper.ts +50 -16
- 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-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/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/parameters.test.ts +51 -0
- package/packages/lsp-core/src/tools/types.ts +10 -0
- package/packages/lsp-daemon/dist/cli.js +902 -479
- package/packages/lsp-daemon/dist/client.d.ts +10 -0
- package/packages/lsp-daemon/dist/client.js +920 -493
- 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 +824 -402
- package/packages/lsp-daemon/dist/ownership.js +2 -2
- 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 +762 -341
- package/packages/lsp-tools-mcp/dist/lsp/manager.js +272 -138
- package/packages/lsp-tools-mcp/dist/mcp.js +787 -368
- package/packages/lsp-tools-mcp/dist/request-context.js +12 -13
- package/packages/lsp-tools-mcp/dist/tools.js +717 -302
- 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/dist/cli.js +1 -1
- package/packages/omo-codex/plugin/components/git-bash/dist/codex-hook.js +2 -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/git-bash/src/codex-hook.ts +2 -1
- package/packages/omo-codex/plugin/components/git-bash/test/codex-hook.test.ts +6 -7
- 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 +941 -540
- 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 +2407 -684
- package/packages/omo-codex/plugin/components/telemetry/dist/posthog.js +2411 -689
- 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 +16 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-codex-validation.js +25 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-continuation.js +10 -4
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-reconciliation.d.ts +2 -5
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-reconciliation.js +5 -78
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-template.d.ts +12 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-template.js +114 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.d.ts +7 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.js +50 -42
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-arg-parser.js +2 -2
- 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.d.ts +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-subcommands.js +40 -37
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +1396 -516
- 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 +2 -5
- package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-snapshot.js +24 -20
- 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.d.ts +2 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/review-blockers.js +16 -7
- package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk/factory.d.ts +2 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk/factory.js +125 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk/manifest.d.ts +46 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk/manifest.js +28 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk/types.d.ts +127 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk/types.js +1 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk.d.ts +3 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk.js +3 -0
- 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 +10 -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 +40 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-continuation.ts +8 -6
- package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-reconciliation.ts +5 -98
- package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-template.ts +134 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint.ts +52 -73
- package/packages/omo-codex/plugin/components/ulw-loop/src/cli-arg-parser.ts +10 -4
- 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 +52 -46
- 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 +34 -28
- 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 +29 -8
- package/packages/omo-codex/plugin/components/ulw-loop/src/sdk/factory.ts +159 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/sdk/manifest.ts +42 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/sdk/types.ts +140 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/sdk.ts +3 -0
- 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 +131 -82
- package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-template.test.ts +147 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint.test.ts +16 -22
- 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 +31 -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 +27 -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 +52 -11
- 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 +67 -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/review-blockers.test.ts +9 -7
- package/packages/omo-codex/plugin/components/ulw-loop/test/sdk-contract.test.ts +137 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/sdk-session-context.test.ts +148 -0
- 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 +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/ATTRIBUTION.md +10 -0
- package/packages/omo-codex/plugin/skills/frontend/SKILL.md +15 -8
- package/packages/omo-codex/plugin/skills/frontend/references/design/README.md +10 -2
- package/packages/omo-codex/plugin/skills/frontend/references/design/_INDEX.md +2 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/ambience-skill.md +145 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/interaction-skill.md +2 -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 +8 -6
- 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 +29 -31
- package/packages/omo-codex/plugin/skills/ulw-execute/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +34 -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 +2987 -1370
- 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 +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/ATTRIBUTION.md +10 -0
- package/packages/shared-skills/skills/frontend/SKILL.md +15 -8
- package/packages/shared-skills/skills/frontend/references/design/README.md +10 -2
- package/packages/shared-skills/skills/frontend/references/design/_INDEX.md +2 -0
- package/packages/shared-skills/skills/frontend/references/design/ambience-skill.md +145 -0
- package/packages/shared-skills/skills/frontend/references/design/interaction-skill.md +2 -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 +4 -4
- package/packages/shared-skills/skills/remove-ai-slops/SKILL.md +1 -1
- package/packages/shared-skills/skills/review-work/SKILL.md +101 -419
- 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 +20 -19
- 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-plan/scripts/scaffold-plan.mjs +1 -1
- 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 -12149
- package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +0 -9747
- 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 { basename as basename3, 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);
|
|
3389
|
+
}
|
|
3390
|
+
}
|
|
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 };
|
|
3305
3408
|
}
|
|
3306
3409
|
}
|
|
3410
|
+
return candidate;
|
|
3307
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"]
|
|
4135
|
+
}
|
|
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;
|
|
3909
4155
|
}
|
|
3910
|
-
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
|
|
3915
|
-
|
|
3916
|
-
|
|
3917
|
-
|
|
3918
|
-
|
|
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();
|
|
@@ -4034,36 +4337,40 @@ function findWorkspaceRoot(filePath) {
|
|
|
4034
4337
|
const abs = resolveReadablePathInsideContext(filePath);
|
|
4035
4338
|
let dir = abs;
|
|
4036
4339
|
if (!isDirectoryPath(dir)) {
|
|
4037
|
-
dir =
|
|
4340
|
+
dir = dirname8(dir);
|
|
4038
4341
|
}
|
|
4342
|
+
if (!isPathInside(cwd, abs))
|
|
4343
|
+
return findWorkspaceRootOutsideContext(dir);
|
|
4039
4344
|
const fallbackRoot = nearestExistingDirectoryInsideContext(dir, cwd) ?? cwd;
|
|
4345
|
+
let nearestPackageRoot;
|
|
4040
4346
|
while (isPathInside(cwd, dir)) {
|
|
4041
4347
|
const canonicalDir = existingDirectoryInsideContext(dir, cwd);
|
|
4042
4348
|
if (canonicalDir !== undefined) {
|
|
4043
|
-
|
|
4044
|
-
|
|
4045
|
-
|
|
4046
|
-
|
|
4349
|
+
if (existsSync10(join5(dir, GIT_WORKSPACE_MARKER))) {
|
|
4350
|
+
return canonicalDir;
|
|
4351
|
+
}
|
|
4352
|
+
if (nearestPackageRoot === undefined && hasProjectWorkspaceMarker(dir)) {
|
|
4353
|
+
nearestPackageRoot = canonicalDir;
|
|
4047
4354
|
}
|
|
4048
4355
|
}
|
|
4049
4356
|
if (dir === cwd)
|
|
4050
4357
|
break;
|
|
4051
|
-
dir =
|
|
4358
|
+
dir = dirname8(dir);
|
|
4052
4359
|
}
|
|
4053
|
-
return fallbackRoot;
|
|
4360
|
+
return nearestPackageRoot ?? fallbackRoot;
|
|
4361
|
+
}
|
|
4362
|
+
function hasProjectWorkspaceMarker(directory) {
|
|
4363
|
+
return PROJECT_WORKSPACE_MARKERS.some((marker) => existsSync10(join5(directory, marker)));
|
|
4054
4364
|
}
|
|
4055
4365
|
function resolveReadablePathInsideContext(filePath) {
|
|
4056
4366
|
const cwd = contextCwd();
|
|
4057
|
-
const abs =
|
|
4367
|
+
const abs = resolve8(cwd, filePath);
|
|
4058
4368
|
if (isPathInside(cwd, abs))
|
|
4059
4369
|
return abs;
|
|
4060
4370
|
const rebased = rebaseThroughCanonicalAncestor(abs, cwd);
|
|
4061
4371
|
if (rebased !== undefined)
|
|
4062
4372
|
return rebased;
|
|
4063
|
-
|
|
4064
|
-
if (isPathInside(cwd, canonical))
|
|
4065
|
-
return canonical;
|
|
4066
|
-
throw new LspInvalidPathError(`LSP file path must be inside request cwd: ${filePath}`);
|
|
4373
|
+
return canonicalizeExistingOrNearestAncestor(abs);
|
|
4067
4374
|
}
|
|
4068
4375
|
function resolvePathInsideContext(filePath) {
|
|
4069
4376
|
const cwd = contextCwd();
|
|
@@ -4078,12 +4385,12 @@ function rebaseThroughCanonicalAncestor(path, cwd) {
|
|
|
4078
4385
|
let current = path;
|
|
4079
4386
|
const suffix = [];
|
|
4080
4387
|
while (true) {
|
|
4081
|
-
if (
|
|
4082
|
-
const canonical =
|
|
4388
|
+
if (existsSync10(current)) {
|
|
4389
|
+
const canonical = realpathSync5(current);
|
|
4083
4390
|
if (isPathInside(cwd, canonical))
|
|
4084
|
-
return suffix.length === 0 ? canonical :
|
|
4391
|
+
return suffix.length === 0 ? canonical : join5(canonical, ...suffix);
|
|
4085
4392
|
}
|
|
4086
|
-
const parent =
|
|
4393
|
+
const parent = dirname8(current);
|
|
4087
4394
|
if (parent === current)
|
|
4088
4395
|
return;
|
|
4089
4396
|
suffix.unshift(basename3(current));
|
|
@@ -4091,9 +4398,9 @@ function rebaseThroughCanonicalAncestor(path, cwd) {
|
|
|
4091
4398
|
}
|
|
4092
4399
|
}
|
|
4093
4400
|
function existingDirectoryInsideContext(directory, cwd) {
|
|
4094
|
-
if (!
|
|
4401
|
+
if (!existsSync10(directory))
|
|
4095
4402
|
return;
|
|
4096
|
-
const canonical =
|
|
4403
|
+
const canonical = realpathSync5(directory);
|
|
4097
4404
|
if (!statSync3(canonical).isDirectory())
|
|
4098
4405
|
return;
|
|
4099
4406
|
return isPathInside(cwd, canonical) ? canonical : undefined;
|
|
@@ -4106,7 +4413,7 @@ function nearestExistingDirectoryInsideContext(directory, cwd) {
|
|
|
4106
4413
|
return canonical;
|
|
4107
4414
|
if (current === cwd)
|
|
4108
4415
|
return;
|
|
4109
|
-
current =
|
|
4416
|
+
current = dirname8(current);
|
|
4110
4417
|
}
|
|
4111
4418
|
return;
|
|
4112
4419
|
}
|
|
@@ -4133,33 +4440,46 @@ function formatServerLookupError(result) {
|
|
|
4133
4440
|
].join(`
|
|
4134
4441
|
`);
|
|
4135
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
|
+
}
|
|
4136
4456
|
function formatNotInstalled(result) {
|
|
4137
|
-
const { server
|
|
4138
|
-
const extensions =
|
|
4139
|
-
const decision = loadInstallDecision(
|
|
4457
|
+
const { server, installHint } = result;
|
|
4458
|
+
const extensions = server.extensions.join(", ");
|
|
4459
|
+
const decision = loadInstallDecision(server.id)?.decision;
|
|
4140
4460
|
const context = lspRequestContext();
|
|
4141
4461
|
if (decision === "declined") {
|
|
4142
|
-
return `LSP server '${
|
|
4462
|
+
return `LSP server '${server.id}' (${extensions}) is NOT INSTALLED; user previously declined installation — proceed without LSP.`;
|
|
4143
4463
|
}
|
|
4144
4464
|
const header = [
|
|
4145
|
-
`LSP server '${
|
|
4465
|
+
`LSP server '${server.id}' for ${extensions} is NOT INSTALLED.`,
|
|
4146
4466
|
"",
|
|
4147
|
-
`Command not found: ${
|
|
4467
|
+
`Command not found: ${server.command[0]}`,
|
|
4148
4468
|
""
|
|
4149
4469
|
];
|
|
4470
|
+
const installOptions = formatInstallOptions(server.id, installHint);
|
|
4150
4471
|
if (decision === "allowed") {
|
|
4151
4472
|
return [
|
|
4152
4473
|
...header,
|
|
4153
4474
|
"The user has pre-authorized LSP installation. Run the install command, then retry this tool:",
|
|
4154
|
-
|
|
4475
|
+
...installOptions.slice(1)
|
|
4155
4476
|
].join(`
|
|
4156
4477
|
`);
|
|
4157
4478
|
}
|
|
4158
4479
|
if (!context.capabilities.installDecisionTool) {
|
|
4159
4480
|
return [
|
|
4160
4481
|
...header,
|
|
4161
|
-
|
|
4162
|
-
` ${installHint}`,
|
|
4482
|
+
...installOptions,
|
|
4163
4483
|
"",
|
|
4164
4484
|
"ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
|
|
4165
4485
|
"Install-decision recording is unavailable in this harness; proceed without LSP if the user declines."
|
|
@@ -4168,13 +4488,12 @@ function formatNotInstalled(result) {
|
|
|
4168
4488
|
}
|
|
4169
4489
|
return [
|
|
4170
4490
|
...header,
|
|
4171
|
-
|
|
4172
|
-
` ${installHint}`,
|
|
4491
|
+
...installOptions,
|
|
4173
4492
|
"",
|
|
4174
4493
|
"ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
|
|
4175
4494
|
"- If the user agrees: run the install command above, then retry this tool.",
|
|
4176
4495
|
"- If the user declines, OR has NOT explicitly asked for LSP installation:",
|
|
4177
|
-
` call lsp_install_decision { server_id: "${
|
|
4496
|
+
` call lsp_install_decision { server_id: "${server.id}", decision: "declined" },`,
|
|
4178
4497
|
` which writes to ${context.installDecisionsPath},`,
|
|
4179
4498
|
" then ignore this message and proceed WITHOUT LSP."
|
|
4180
4499
|
].join(`
|
|
@@ -4198,34 +4517,34 @@ async function withLspClient(filePath, fn, toolName, options = {}) {
|
|
|
4198
4517
|
if (result.status !== "found") {
|
|
4199
4518
|
throw new LspServerLookupError(formatServerLookupError(result), result);
|
|
4200
4519
|
}
|
|
4201
|
-
const
|
|
4520
|
+
const server = result.server;
|
|
4202
4521
|
const root = findWorkspaceRoot(absPath);
|
|
4203
4522
|
const manager = options.manager ?? getLspManager();
|
|
4204
4523
|
const acquireAndCall = async (allowRetry) => {
|
|
4205
|
-
const client = await manager.getClient(root,
|
|
4524
|
+
const client = await manager.getClient(root, server, options.signal);
|
|
4206
4525
|
try {
|
|
4207
4526
|
return await fn(client, root, absPath);
|
|
4208
4527
|
} catch (err) {
|
|
4209
4528
|
if (allowRetry && READ_ONLY_TOOLS.has(toolName) && isLspDeadConnectionError(err)) {
|
|
4210
|
-
manager.invalidateClient(root,
|
|
4529
|
+
manager.invalidateClient(root, server.id, client);
|
|
4211
4530
|
return acquireAndCall(false);
|
|
4212
4531
|
}
|
|
4213
4532
|
if (err instanceof LspRequestTimeoutError) {
|
|
4214
|
-
if (manager.isServerInitializing(root,
|
|
4533
|
+
if (manager.isServerInitializing(root, server.id)) {
|
|
4215
4534
|
throw new LspServerInitializingError(err);
|
|
4216
4535
|
}
|
|
4217
4536
|
}
|
|
4218
4537
|
throw err;
|
|
4219
4538
|
} finally {
|
|
4220
|
-
manager.releaseClient(root,
|
|
4539
|
+
manager.releaseClient(root, server.id);
|
|
4221
4540
|
}
|
|
4222
4541
|
};
|
|
4223
4542
|
return acquireAndCall(true);
|
|
4224
4543
|
}
|
|
4225
4544
|
|
|
4226
4545
|
// ../lsp-core/src/lsp/directory-diagnostics.ts
|
|
4227
|
-
import { existsSync as
|
|
4228
|
-
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";
|
|
4229
4548
|
|
|
4230
4549
|
// ../lsp-core/src/lsp/formatters.ts
|
|
4231
4550
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
@@ -4240,10 +4559,10 @@ function uriToPath(uri) {
|
|
|
4240
4559
|
}
|
|
4241
4560
|
function formatLocation(loc) {
|
|
4242
4561
|
if ("targetUri" in loc) {
|
|
4243
|
-
const
|
|
4244
|
-
const
|
|
4245
|
-
const
|
|
4246
|
-
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}`;
|
|
4247
4566
|
}
|
|
4248
4567
|
const uri = uriToPath(loc.uri);
|
|
4249
4568
|
const line = loc.range.start.line + 1;
|
|
@@ -4355,7 +4674,7 @@ function collectFilesWithExtension(dir, extension, maxFiles) {
|
|
|
4355
4674
|
for (const entry of entries) {
|
|
4356
4675
|
if (files.length >= maxFiles)
|
|
4357
4676
|
return;
|
|
4358
|
-
const fullPath =
|
|
4677
|
+
const fullPath = join6(currentDir, entry);
|
|
4359
4678
|
let stat;
|
|
4360
4679
|
try {
|
|
4361
4680
|
stat = lstatSync4(fullPath);
|
|
@@ -4380,15 +4699,15 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
|
|
|
4380
4699
|
if (!extension.startsWith(".")) {
|
|
4381
4700
|
throw new LspInvalidPathError(`Extension must start with a dot (e.g., ".ts", not "${extension}"). Use ".${extension}" instead.`);
|
|
4382
4701
|
}
|
|
4383
|
-
const absDir =
|
|
4384
|
-
if (!
|
|
4702
|
+
const absDir = resolve9(options.workspaceRoot ?? contextCwd(), directory);
|
|
4703
|
+
if (!existsSync11(absDir)) {
|
|
4385
4704
|
throw new LspInvalidPathError(`Directory does not exist: ${absDir}`);
|
|
4386
4705
|
}
|
|
4387
4706
|
const serverResult = options.server === undefined ? findServerForExtension(extension) : { status: "found", server: options.server };
|
|
4388
4707
|
if (serverResult.status !== "found") {
|
|
4389
4708
|
throw new LspServerLookupError(formatServerLookupError(serverResult));
|
|
4390
4709
|
}
|
|
4391
|
-
const
|
|
4710
|
+
const server = serverResult.server;
|
|
4392
4711
|
const allFiles = (options.listFiles ?? collectFilesWithExtension)(absDir, extension, maxFiles + 1);
|
|
4393
4712
|
const wasCapped = allFiles.length > maxFiles;
|
|
4394
4713
|
const filesToProcess = allFiles.slice(0, maxFiles);
|
|
@@ -4408,7 +4727,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
|
|
|
4408
4727
|
const fileErrors = [];
|
|
4409
4728
|
const maxConcurrency = Math.max(1, options.maxConcurrency ?? DIRECTORY_DIAGNOSTICS_MAX_CONCURRENCY);
|
|
4410
4729
|
options.signal?.throwIfAborted();
|
|
4411
|
-
const client = await manager.getClient(root,
|
|
4730
|
+
const client = await manager.getClient(root, server, options.signal);
|
|
4412
4731
|
try {
|
|
4413
4732
|
let nextIndex = 0;
|
|
4414
4733
|
const workers = Array.from({ length: Math.min(maxConcurrency, filesToProcess.length) }, async () => {
|
|
@@ -4436,7 +4755,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
|
|
|
4436
4755
|
});
|
|
4437
4756
|
await Promise.all(workers);
|
|
4438
4757
|
} finally {
|
|
4439
|
-
manager.releaseClient(root,
|
|
4758
|
+
manager.releaseClient(root, server.id);
|
|
4440
4759
|
}
|
|
4441
4760
|
const displayDiagnostics = allDiagnostics.slice(0, DEFAULT_MAX_DIAGNOSTICS);
|
|
4442
4761
|
const wasDiagCapped = allDiagnostics.length > DEFAULT_MAX_DIAGNOSTICS;
|
|
@@ -4468,7 +4787,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
|
|
|
4468
4787
|
|
|
4469
4788
|
// ../lsp-core/src/lsp/infer-extension.ts
|
|
4470
4789
|
import { lstatSync as lstatSync5, readdirSync as readdirSync4 } from "node:fs";
|
|
4471
|
-
import { join as
|
|
4790
|
+
import { join as join7 } from "node:path";
|
|
4472
4791
|
var SKIP_DIRECTORIES2 = new Set(["node_modules", ".git", "dist", "build", ".next", "out"]);
|
|
4473
4792
|
var MAX_SCAN_ENTRIES = 500;
|
|
4474
4793
|
function inferExtensionFromDirectory(directory) {
|
|
@@ -4486,7 +4805,7 @@ function inferExtensionFromDirectory(directory) {
|
|
|
4486
4805
|
for (const entry of entries) {
|
|
4487
4806
|
if (scanned >= MAX_SCAN_ENTRIES)
|
|
4488
4807
|
return;
|
|
4489
|
-
const fullPath =
|
|
4808
|
+
const fullPath = join7(dir, entry);
|
|
4490
4809
|
let stat;
|
|
4491
4810
|
try {
|
|
4492
4811
|
stat = lstatSync5(fullPath);
|
|
@@ -4645,8 +4964,8 @@ function clientOptions(signal) {
|
|
|
4645
4964
|
}
|
|
4646
4965
|
|
|
4647
4966
|
// ../lsp-core/src/tools/result.ts
|
|
4648
|
-
function text(
|
|
4649
|
-
return { content: [{ type: "text", text
|
|
4967
|
+
function text(text, details, isError = false) {
|
|
4968
|
+
return { content: [{ type: "text", text }], details, isError };
|
|
4650
4969
|
}
|
|
4651
4970
|
|
|
4652
4971
|
// ../lsp-core/src/tools/diagnostics.ts
|
|
@@ -4666,7 +4985,7 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
4666
4985
|
const extension = inferExtensionFromDirectory(absPath);
|
|
4667
4986
|
if (!extension) {
|
|
4668
4987
|
const message = `No supported source files found in directory: ${absPath}`;
|
|
4669
|
-
const
|
|
4988
|
+
const details = {
|
|
4670
4989
|
filePath,
|
|
4671
4990
|
severity,
|
|
4672
4991
|
mode: "directory",
|
|
@@ -4676,24 +4995,24 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
4676
4995
|
error: message,
|
|
4677
4996
|
errorKind: "no_files"
|
|
4678
4997
|
};
|
|
4679
|
-
return text(message,
|
|
4998
|
+
return text(message, details);
|
|
4680
4999
|
}
|
|
4681
|
-
const
|
|
4682
|
-
const
|
|
5000
|
+
const output = await aggregateDiagnosticsForDirectory(absPath, extension, severity, undefined, signal === undefined ? {} : { signal });
|
|
5001
|
+
const details = {
|
|
4683
5002
|
filePath,
|
|
4684
5003
|
severity,
|
|
4685
5004
|
mode: "directory",
|
|
4686
5005
|
diagnostics: [],
|
|
4687
|
-
totalDiagnostics:
|
|
5006
|
+
totalDiagnostics: output.totalDiagnostics,
|
|
4688
5007
|
truncated: false,
|
|
4689
|
-
fileFailures: [...
|
|
5008
|
+
fileFailures: [...output.fileFailures]
|
|
4690
5009
|
};
|
|
4691
|
-
return text(
|
|
5010
|
+
return text(output.output, details);
|
|
4692
5011
|
}
|
|
4693
5012
|
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.diagnostics(resolvedFilePath, signal), "diagnostics", clientOptions(signal));
|
|
4694
5013
|
if (result.transientError) {
|
|
4695
5014
|
const message = result.transientError.message;
|
|
4696
|
-
const
|
|
5015
|
+
const details = {
|
|
4697
5016
|
filePath,
|
|
4698
5017
|
severity,
|
|
4699
5018
|
mode: "file",
|
|
@@ -4703,7 +5022,7 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
4703
5022
|
error: message,
|
|
4704
5023
|
errorKind: result.transientError.kind
|
|
4705
5024
|
};
|
|
4706
|
-
return text(message,
|
|
5025
|
+
return text(message, details, true);
|
|
4707
5026
|
}
|
|
4708
5027
|
const diagnostics = filterDiagnosticsBySeverity(asDiagnosticArray(result), severity);
|
|
4709
5028
|
const total = diagnostics.length;
|
|
@@ -4737,6 +5056,96 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
4737
5056
|
throw error;
|
|
4738
5057
|
}
|
|
4739
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
|
+
|
|
4740
5149
|
// ../lsp-core/src/tools/install-decision.ts
|
|
4741
5150
|
async function executeLspInstallDecision(params) {
|
|
4742
5151
|
const serverId = requireString(params, "server_id");
|
|
@@ -4744,7 +5153,7 @@ async function executeLspInstallDecision(params) {
|
|
|
4744
5153
|
if (!isInstallDecision(decision)) {
|
|
4745
5154
|
return text(`Invalid decision '${String(decision)}'. Expected "declined" or "allowed".`, { serverId, errorKind: "invalid_decision" }, true);
|
|
4746
5155
|
}
|
|
4747
|
-
const serverIds = [...new Set(getMergedServers().map((
|
|
5156
|
+
const serverIds = [...new Set(getMergedServers().map((server) => server.id))];
|
|
4748
5157
|
if (!serverIds.includes(serverId)) {
|
|
4749
5158
|
const preview = serverIds.slice(0, 20).join(", ");
|
|
4750
5159
|
return text(`Unknown LSP server '${serverId}'. Known servers: ${preview}${serverIds.length > 20 ? "..." : ""}`, { serverId, errorKind: "unknown_server" }, true);
|
|
@@ -4884,10 +5293,10 @@ function objectSchema(properties, required = []) {
|
|
|
4884
5293
|
async function executeLspStatus() {
|
|
4885
5294
|
const servers = getAllServers();
|
|
4886
5295
|
const snapshots = getLspManager().getSnapshot();
|
|
4887
|
-
const installed = servers.filter((
|
|
4888
|
-
const configuredLines = servers.map((
|
|
4889
|
-
const state =
|
|
4890
|
-
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(", ")}`;
|
|
4891
5300
|
});
|
|
4892
5301
|
const activeLines = snapshots.map((snapshot) => {
|
|
4893
5302
|
const state = snapshot.alive ? snapshot.isInitializing ? "initializing" : "alive" : "dead";
|
|
@@ -4930,8 +5339,8 @@ async function executeLspSymbols(params, signal) {
|
|
|
4930
5339
|
errorKind: "missing_query"
|
|
4931
5340
|
});
|
|
4932
5341
|
}
|
|
4933
|
-
const
|
|
4934
|
-
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);
|
|
4935
5344
|
}
|
|
4936
5345
|
const symbols = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.documentSymbols(resolvedFilePath, signal), "documentSymbols", clientOptions(signal));
|
|
4937
5346
|
return formatSymbolsResult(filePath, scope, symbols, limit);
|
|
@@ -5069,6 +5478,16 @@ var LSP_MCP_TOOLS = [
|
|
|
5069
5478
|
}, ["filePath", "line", "character", "newName"]),
|
|
5070
5479
|
execute: executeLspRename
|
|
5071
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
|
+
},
|
|
5072
5491
|
{
|
|
5073
5492
|
name: "install_decision",
|
|
5074
5493
|
aliases: ["lsp_install_decision"],
|
|
@@ -5176,6 +5595,6 @@ function requestedProtocolVersion(params) {
|
|
|
5176
5595
|
return params["protocolVersion"];
|
|
5177
5596
|
}
|
|
5178
5597
|
export {
|
|
5179
|
-
|
|
5180
|
-
|
|
5598
|
+
handleLspMcpRequest,
|
|
5599
|
+
runMcpStdioServer
|
|
5181
5600
|
};
|