oh-my-opencode 5.0.0-beta.8 → 5.0.0-beta.80
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/command/remove-deadcode.md +1 -1
- package/.agents/skills/codex-qa/scripts/lsp-e2e.sh +1 -3
- package/.agents/skills/hyperplan/SKILL.md +5 -5
- 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/remove-deadcode/SKILL.md +1 -1
- package/.agents/skills/security-research/SKILL.md +4 -4
- 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/.opencode/command/publish.md +59 -23
- package/.opencode/skills/pre-publish-review/SKILL.md +9 -12
- package/README.ja.md +66 -61
- package/README.ko.md +67 -62
- package/README.md +108 -182
- package/README.ru.md +63 -61
- package/README.zh-cn.md +62 -61
- package/THIRD-PARTY-NOTICES.md +35 -105
- package/dist/agents/atlas/agent.d.ts +0 -1
- package/dist/agents/gpt-prompt-identity.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/browser-provider.d.ts +2 -0
- 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 +50191 -58043
- 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 +51708 -59537
- package/dist/config/index.d.ts +1 -1
- package/dist/config/schema/agent-names.d.ts +0 -1
- package/dist/config/schema/background-task.d.ts +1 -0
- package/dist/config/schema/browser-automation.d.ts +0 -2
- 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 -12
- 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/config-migration/category-deep-split.d.ts +3 -0
- package/dist/config-migration/migration-plans.d.ts +1 -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/boulder-state/storage.d.ts +1 -1
- 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/hyperplan.d.ts +1 -1
- package/dist/features/builtin-commands/templates/refactor-sections/team-mode-addendum.d.ts +1 -1
- package/dist/features/builtin-commands/templates/remove-ai-slops.d.ts +1 -1
- 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/comment-checker/__fixtures__/download-probe.fixture.d.ts +1 -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/plan-format-validator/hook.d.ts +19 -0
- 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 +30870 -27341
- package/dist/mcp/index.d.ts +0 -4
- package/dist/mcp/types.d.ts +0 -1
- package/dist/oh-my-opencode.schema.json +25 -52
- 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-config/omo-config-chain.d.ts +1 -0
- package/dist/plugin-dispose.d.ts +3 -0
- package/dist/shared/agent-tool-restrictions.d.ts +0 -1
- package/dist/shared/compaction-agent-config-checkpoint.d.ts +1 -0
- package/dist/shared/index.d.ts +2 -0
- package/dist/shared/legacy-plugin-warning.d.ts +2 -1
- package/dist/shared/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 +13 -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 +26 -5
- 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/debugging/references/tools/playwright-cli.md +79 -161
- package/dist/skills/frontend/ATTRIBUTION.md +10 -0
- package/dist/skills/frontend/SKILL.md +7 -3
- package/dist/skills/frontend/references/design/README.md +10 -2
- package/dist/skills/frontend/references/design/_INDEX.md +1 -0
- package/dist/skills/frontend/references/design/ambience-skill.md +145 -0
- package/dist/skills/frontend/references/design/aside.md +1 -1
- package/dist/skills/frontend/references/design/clone-from-url.md +1 -1
- 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/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/frontend/scripts/perfection/lighthouse-audit.py +2 -2
- 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 +5 -5
- package/dist/skills/remove-ai-slops/SKILL.md +5 -5
- package/dist/skills/review-work/SKILL.md +101 -419
- package/dist/skills/ultimate-browsing/ATTRIBUTION.md +32 -86
- package/dist/skills/ultimate-browsing/SKILL.md +32 -27
- package/dist/skills/ultimate-browsing/engine/AGENTS.md +111 -0
- package/dist/skills/ultimate-browsing/engine/templates/package.json +2 -2
- package/dist/skills/ultimate-browsing/engine/templates/playwright_mobile_chrome.js +5 -2
- package/dist/skills/ultimate-browsing/engine/templates/playwright_real_chrome.js +8 -6
- package/dist/skills/ultimate-browsing/engine/tests/test_playwright_stealth.py +86 -0
- package/dist/skills/ultimate-browsing/engine/tests/test_playwright_templates.py +4 -7
- package/dist/skills/ultimate-browsing/references/chrome-stealth.md +86 -95
- package/dist/skills/ultimate-browsing/references/insane-search/README.md +18 -5
- package/dist/skills/ultimate-browsing/references/insane-search/playwright.md +16 -13
- package/dist/skills/ultimate-browsing/scripts/extract_cookies.py +3 -3
- package/dist/skills/{start-work → ulw-execute}/SKILL.md +24 -22
- package/dist/skills/ulw-plan/SKILL.md +5 -6
- package/dist/skills/ulw-plan/references/full-workflow.md +6 -5
- package/dist/skills/ulw-plan/references/intent-unclear.md +2 -2
- package/dist/skills/ulw-plan/scripts/scaffold-plan.mjs +2 -1
- package/dist/skills/ulw-research/SKILL.md +10 -5
- package/dist/skills/visual-qa/AGENTS.md +58 -0
- package/dist/skills/visual-qa/SKILL.md +4 -3
- package/dist/skills/visual-qa/references/browser-setup.md +75 -0
- 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 +10 -3
- 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 +37073 -46672
- package/package.json +44 -45
- 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 +9 -1
- package/packages/lsp-core/src/lsp/client-diagnostics-freshness.integration.test.ts +100 -28
- 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 +90 -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 +35 -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 +904 -479
- package/packages/lsp-daemon/dist/client.d.ts +10 -0
- package/packages/lsp-daemon/dist/client.js +922 -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 +826 -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 +764 -341
- package/packages/lsp-tools-mcp/dist/lsp/manager.js +274 -138
- package/packages/lsp-tools-mcp/dist/mcp.js +789 -368
- package/packages/lsp-tools-mcp/dist/request-context.js +12 -13
- package/packages/lsp-tools-mcp/dist/tools.js +719 -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 +7175 -408
- 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/bootstrap/src/setup.ts +7 -1
- 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 +943 -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 +2470 -701
- package/packages/omo-codex/plugin/components/telemetry/dist/posthog.js +2488 -720
- 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 +4 -4
- package/packages/omo-codex/plugin/components/ultrawork/biome.json +2 -2
- package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +500 -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 +4 -5
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +5 -5
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-unclear.md +2 -2
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/scripts/scaffold-plan.mjs +1 -0
- 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 +11 -11
- 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 +17 -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 +44 -27
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-codex-validation.d.ts +18 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-codex-validation.js +30 -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 +57 -46
- 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 +2191 -737
- 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 +8 -5
- package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-snapshot.js +35 -23
- 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 +25 -9
- package/packages/omo-codex/plugin/components/ulw-loop/dist/driver-objective-ack.d.ts +4 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/driver-objective-ack.js +18 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/evidence-artifacts.d.ts +1 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/evidence-artifacts.js +37 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/evidence.d.ts +1 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/evidence.js +24 -12
- package/packages/omo-codex/plugin/components/ulw-loop/dist/ledger.d.ts +4 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/ledger.js +39 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/paths.d.ts +2 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/paths.js +19 -4
- package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-commit.d.ts +19 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-commit.js +108 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-crud.d.ts +6 -2
- package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-crud.js +54 -25
- package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-goal-factory.d.ts +10 -3
- package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-goal-factory.js +38 -31
- package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.d.ts +10 -7
- package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.js +121 -100
- package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-log.d.ts +16 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-log.js +115 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-missing-recovery.d.ts +18 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-missing-recovery.js +41 -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 +25 -13
- 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 +157 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk/manifest.d.ts +381 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk/manifest.js +127 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk/types.d.ts +130 -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-budget-io.d.ts +5 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-budget-io.js +67 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-guard.d.ts +7 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-guard.js +188 -59
- package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-role-guard.d.ts +2 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-role-guard.js +22 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/state-lock.d.ts +19 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/state-lock.js +259 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/status-next-actions.d.ts +7 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/status-next-actions.js +41 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-batch.js +4 -4
- package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-mutations.d.ts +3 -2
- package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-mutations.js +4 -4
- package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-types.d.ts +9 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/steering.d.ts +3 -2
- package/packages/omo-codex/plugin/components/ulw-loop/dist/steering.js +11 -11
- package/packages/omo-codex/plugin/components/ulw-loop/dist/stop-resume-hook.js +28 -23
- package/packages/omo-codex/plugin/components/ulw-loop/dist/success-criteria-input.d.ts +9 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/success-criteria-input.js +41 -0
- 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 +83 -0
- package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +18 -5
- 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 +7 -2
- package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +33 -10
- package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-codex-validation.ts +52 -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 +59 -77
- 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 +51 -33
- 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 +27 -9
- package/packages/omo-codex/plugin/components/ulw-loop/src/driver-objective-ack.ts +20 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/evidence-artifacts.ts +45 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/evidence.ts +23 -16
- package/packages/omo-codex/plugin/components/ulw-loop/src/ledger.ts +38 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/paths.ts +32 -4
- package/packages/omo-codex/plugin/components/ulw-loop/src/plan-commit.ts +132 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/plan-crud.ts +67 -54
- package/packages/omo-codex/plugin/components/ulw-loop/src/plan-goal-factory.ts +63 -31
- package/packages/omo-codex/plugin/components/ulw-loop/src/plan-io.ts +140 -119
- package/packages/omo-codex/plugin/components/ulw-loop/src/plan-log.ts +112 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/plan-missing-recovery.ts +61 -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 +38 -13
- package/packages/omo-codex/plugin/components/ulw-loop/src/sdk/factory.ts +218 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/sdk/manifest.ts +156 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/sdk/types.ts +143 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/sdk.ts +3 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/spawn-budget-io.ts +59 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/spawn-guard.ts +196 -52
- package/packages/omo-codex/plugin/components/ulw-loop/src/spawn-role-guard.ts +22 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/state-lock.ts +257 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/status-next-actions.ts +45 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/steering-batch.ts +4 -4
- package/packages/omo-codex/plugin/components/ulw-loop/src/steering-mutations.ts +5 -4
- package/packages/omo-codex/plugin/components/ulw-loop/src/steering-types.ts +13 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/steering.ts +12 -10
- package/packages/omo-codex/plugin/components/ulw-loop/src/stop-resume-hook.ts +27 -22
- package/packages/omo-codex/plugin/components/ulw-loop/src/success-criteria-input.ts +56 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/surface.ts +115 -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 +88 -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/barrier.ts +13 -0
- 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/commit-child.ts +65 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/commit-cli-qa.mjs +76 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/commit-crash.ts +23 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/commit-mutations.mjs +58 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/commit-writer.ts +65 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/lease-clock.ts +23 -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-commit-log.test.ts +252 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/plan-commit-recovery.test.ts +190 -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 +74 -25
- package/packages/omo-codex/plugin/components/ulw-loop/test/plan-log-legacy-projection.test.ts +228 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/plan-log-newest.test.ts +72 -0
- 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-completed-plan.test.ts +43 -0
- 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-driver-states.test.ts +174 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/sdk-dx.test.ts +219 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/sdk-session-context.test.ts +169 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/spawn-guard.test.ts +450 -7
- package/packages/omo-codex/plugin/components/ulw-loop/test/spawn-role-matrix.test.ts +113 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/state-lock.test.ts +310 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/status-next-actions-surface.test.ts +133 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/steering-batch.test.ts +12 -12
- package/packages/omo-codex/plugin/components/ulw-loop/test/steering.test.ts +12 -6
- 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.d.mts +4 -0
- package/packages/omo-codex/plugin/scripts/sync-skills.mjs +111 -64
- 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 +13 -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 +26 -5
- 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/debugging/references/tools/playwright-cli.md +79 -161
- package/packages/omo-codex/plugin/skills/frontend/ATTRIBUTION.md +10 -0
- package/packages/omo-codex/plugin/skills/frontend/SKILL.md +7 -3
- package/packages/omo-codex/plugin/skills/frontend/references/design/README.md +10 -2
- package/packages/omo-codex/plugin/skills/frontend/references/design/_INDEX.md +1 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/ambience-skill.md +145 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/aside.md +1 -1
- package/packages/omo-codex/plugin/skills/frontend/references/design/clone-from-url.md +1 -1
- 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/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/frontend/scripts/perfection/lighthouse-audit.py +2 -2
- package/packages/omo-codex/plugin/skills/git-master/SKILL.md +1 -1
- package/packages/omo-codex/plugin/skills/init-deep/SKILL.md +20 -18
- 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 +11 -9
- package/packages/omo-codex/plugin/skills/remove-ai-slops/SKILL.md +11 -9
- package/packages/omo-codex/plugin/skills/review-work/SKILL.md +116 -424
- package/packages/omo-codex/plugin/skills/ultimate-browsing/ATTRIBUTION.md +32 -86
- package/packages/omo-codex/plugin/skills/ultimate-browsing/SKILL.md +32 -27
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/AGENTS.md +111 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/templates/package.json +2 -2
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/templates/playwright_mobile_chrome.js +5 -2
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/templates/playwright_real_chrome.js +8 -6
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/test_playwright_stealth.py +86 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/test_playwright_templates.py +4 -7
- package/packages/omo-codex/plugin/skills/ultimate-browsing/references/chrome-stealth.md +86 -95
- package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/README.md +18 -5
- package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/playwright.md +16 -13
- package/packages/omo-codex/plugin/skills/ultimate-browsing/scripts/extract_cookies.py +3 -3
- package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +44 -27
- package/packages/omo-codex/plugin/skills/{start-work → ulw-execute}/SKILL.md +35 -36
- package/packages/omo-codex/plugin/skills/ulw-execute/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +31 -2
- package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +33 -10
- package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +4 -5
- package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +5 -5
- package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-unclear.md +2 -2
- package/packages/omo-codex/plugin/skills/ulw-plan/scripts/scaffold-plan.mjs +1 -0
- package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +16 -9
- package/packages/omo-codex/plugin/skills/visual-qa/AGENTS.md +58 -0
- package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +10 -7
- package/packages/omo-codex/plugin/skills/visual-qa/references/browser-setup.md +75 -0
- 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-default-role.test.mjs +66 -0
- 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 +100 -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 +9832 -1445
- 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} +44 -34
- 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 +13 -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 +26 -5
- 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/debugging/references/tools/playwright-cli.md +79 -161
- package/packages/shared-skills/skills/frontend/ATTRIBUTION.md +10 -0
- package/packages/shared-skills/skills/frontend/SKILL.md +7 -3
- package/packages/shared-skills/skills/frontend/references/design/README.md +10 -2
- package/packages/shared-skills/skills/frontend/references/design/_INDEX.md +1 -0
- package/packages/shared-skills/skills/frontend/references/design/ambience-skill.md +145 -0
- package/packages/shared-skills/skills/frontend/references/design/aside.md +1 -1
- package/packages/shared-skills/skills/frontend/references/design/clone-from-url.md +1 -1
- 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/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/frontend/scripts/perfection/lighthouse-audit.py +2 -2
- 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 +5 -5
- package/packages/shared-skills/skills/remove-ai-slops/SKILL.md +5 -5
- package/packages/shared-skills/skills/review-work/SKILL.md +101 -419
- package/packages/shared-skills/skills/ultimate-browsing/ATTRIBUTION.md +32 -86
- package/packages/shared-skills/skills/ultimate-browsing/SKILL.md +32 -27
- package/packages/shared-skills/skills/ultimate-browsing/engine/AGENTS.md +111 -0
- package/packages/shared-skills/skills/ultimate-browsing/engine/templates/package.json +2 -2
- package/packages/shared-skills/skills/ultimate-browsing/engine/templates/playwright_mobile_chrome.js +5 -2
- package/packages/shared-skills/skills/ultimate-browsing/engine/templates/playwright_real_chrome.js +8 -6
- package/packages/shared-skills/skills/ultimate-browsing/engine/tests/test_playwright_stealth.py +86 -0
- package/packages/shared-skills/skills/ultimate-browsing/engine/tests/test_playwright_templates.py +4 -7
- package/packages/shared-skills/skills/ultimate-browsing/references/chrome-stealth.md +86 -95
- package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/README.md +18 -5
- package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/playwright.md +16 -13
- package/packages/shared-skills/skills/ultimate-browsing/scripts/extract_cookies.py +3 -3
- package/packages/shared-skills/skills/{start-work → ulw-execute}/SKILL.md +24 -22
- package/packages/shared-skills/skills/ulw-plan/SKILL.md +5 -6
- package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +6 -5
- package/packages/shared-skills/skills/ulw-plan/references/intent-unclear.md +2 -2
- package/packages/shared-skills/skills/ulw-plan/scripts/scaffold-plan.mjs +2 -1
- package/packages/shared-skills/skills/ulw-research/SKILL.md +10 -5
- package/packages/shared-skills/skills/visual-qa/AGENTS.md +58 -0
- package/packages/shared-skills/skills/visual-qa/SKILL.md +4 -3
- package/packages/shared-skills/skills/visual-qa/references/browser-setup.md +75 -0
- 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/.agents/skills/work-with-pr-workspace/evals/evals.json +0 -76
- package/.agents/skills/work-with-pr-workspace/iteration-1/benchmark.json +0 -138
- package/.agents/skills/work-with-pr-workspace/iteration-1/benchmark.md +0 -42
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-1/eval_metadata.json +0 -57
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-1/with_skill/grading.json +0 -15
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-1/with_skill/outputs/code-changes.md +0 -454
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-1/with_skill/outputs/execution-plan.md +0 -136
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-1/with_skill/outputs/pr-description.md +0 -47
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-1/with_skill/outputs/verification-strategy.md +0 -163
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-1/with_skill/timing.json +0 -1
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-1/without_skill/grading.json +0 -15
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-1/without_skill/outputs/code-changes.md +0 -615
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-1/without_skill/outputs/execution-plan.md +0 -99
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-1/without_skill/outputs/pr-description.md +0 -50
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-1/without_skill/outputs/verification-strategy.md +0 -111
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-1/without_skill/timing.json +0 -1
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-2/eval_metadata.json +0 -37
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-2/with_skill/grading.json +0 -11
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-2/with_skill/outputs/code-changes.md +0 -205
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-2/with_skill/outputs/execution-plan.md +0 -78
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-2/with_skill/outputs/pr-description.md +0 -42
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-2/with_skill/outputs/verification-strategy.md +0 -87
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-2/with_skill/timing.json +0 -1
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-2/without_skill/grading.json +0 -11
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-2/without_skill/outputs/code-changes.md +0 -334
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-2/without_skill/outputs/execution-plan.md +0 -86
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-2/without_skill/outputs/pr-description.md +0 -23
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-2/without_skill/outputs/verification-strategy.md +0 -119
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-2/without_skill/timing.json +0 -1
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-3/eval_metadata.json +0 -32
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-3/with_skill/grading.json +0 -10
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-3/with_skill/outputs/code-changes.md +0 -221
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-3/with_skill/outputs/execution-plan.md +0 -104
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-3/with_skill/outputs/pr-description.md +0 -41
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-3/with_skill/outputs/verification-strategy.md +0 -84
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-3/with_skill/timing.json +0 -1
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-3/without_skill/grading.json +0 -10
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-3/without_skill/outputs/code-changes.md +0 -342
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-3/without_skill/outputs/execution-plan.md +0 -131
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-3/without_skill/outputs/pr-description.md +0 -39
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-3/without_skill/outputs/verification-strategy.md +0 -128
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-3/without_skill/timing.json +0 -1
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-4/eval_metadata.json +0 -32
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-4/with_skill/grading.json +0 -10
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-4/with_skill/outputs/code-changes.md +0 -143
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-4/with_skill/outputs/execution-plan.md +0 -82
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-4/with_skill/outputs/pr-description.md +0 -51
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-4/with_skill/outputs/verification-strategy.md +0 -69
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-4/with_skill/timing.json +0 -1
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-4/without_skill/grading.json +0 -10
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-4/without_skill/outputs/code-changes.md +0 -252
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-4/without_skill/outputs/execution-plan.md +0 -83
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-4/without_skill/outputs/pr-description.md +0 -33
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-4/without_skill/outputs/verification-strategy.md +0 -101
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-4/without_skill/timing.json +0 -1
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-5/eval_metadata.json +0 -32
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-5/with_skill/grading.json +0 -10
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-5/with_skill/outputs/code-changes.md +0 -387
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-5/with_skill/outputs/execution-plan.md +0 -112
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-5/with_skill/outputs/pr-description.md +0 -51
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-5/with_skill/outputs/verification-strategy.md +0 -75
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-5/with_skill/timing.json +0 -1
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-5/without_skill/grading.json +0 -10
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-5/without_skill/outputs/code-changes.md +0 -529
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-5/without_skill/outputs/execution-plan.md +0 -127
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-5/without_skill/outputs/pr-description.md +0 -42
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-5/without_skill/outputs/verification-strategy.md +0 -120
- package/.agents/skills/work-with-pr-workspace/iteration-1/eval-5/without_skill/timing.json +0 -1
- package/.agents/skills/work-with-pr-workspace/iteration-1/review.html +0 -1326
- package/.opencode/skills/work-with-pr-workspace/evals/evals.json +0 -76
- package/.opencode/skills/work-with-pr-workspace/iteration-1/benchmark.json +0 -138
- package/.opencode/skills/work-with-pr-workspace/iteration-1/benchmark.md +0 -42
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-1/eval_metadata.json +0 -57
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-1/with_skill/grading.json +0 -15
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-1/with_skill/outputs/code-changes.md +0 -454
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-1/with_skill/outputs/execution-plan.md +0 -136
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-1/with_skill/outputs/pr-description.md +0 -47
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-1/with_skill/outputs/verification-strategy.md +0 -163
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-1/with_skill/timing.json +0 -1
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-1/without_skill/grading.json +0 -15
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-1/without_skill/outputs/code-changes.md +0 -615
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-1/without_skill/outputs/execution-plan.md +0 -99
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-1/without_skill/outputs/pr-description.md +0 -50
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-1/without_skill/outputs/verification-strategy.md +0 -111
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-1/without_skill/timing.json +0 -1
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-2/eval_metadata.json +0 -37
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-2/with_skill/grading.json +0 -11
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-2/with_skill/outputs/code-changes.md +0 -205
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-2/with_skill/outputs/execution-plan.md +0 -78
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-2/with_skill/outputs/pr-description.md +0 -42
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-2/with_skill/outputs/verification-strategy.md +0 -87
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-2/with_skill/timing.json +0 -1
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-2/without_skill/grading.json +0 -11
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-2/without_skill/outputs/code-changes.md +0 -334
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-2/without_skill/outputs/execution-plan.md +0 -86
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-2/without_skill/outputs/pr-description.md +0 -23
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-2/without_skill/outputs/verification-strategy.md +0 -119
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-2/without_skill/timing.json +0 -1
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-3/eval_metadata.json +0 -32
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-3/with_skill/grading.json +0 -10
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-3/with_skill/outputs/code-changes.md +0 -221
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-3/with_skill/outputs/execution-plan.md +0 -104
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-3/with_skill/outputs/pr-description.md +0 -41
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-3/with_skill/outputs/verification-strategy.md +0 -84
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-3/with_skill/timing.json +0 -1
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-3/without_skill/grading.json +0 -10
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-3/without_skill/outputs/code-changes.md +0 -342
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-3/without_skill/outputs/execution-plan.md +0 -131
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-3/without_skill/outputs/pr-description.md +0 -39
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-3/without_skill/outputs/verification-strategy.md +0 -128
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-3/without_skill/timing.json +0 -1
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-4/eval_metadata.json +0 -32
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-4/with_skill/grading.json +0 -10
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-4/with_skill/outputs/code-changes.md +0 -143
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-4/with_skill/outputs/execution-plan.md +0 -82
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-4/with_skill/outputs/pr-description.md +0 -51
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-4/with_skill/outputs/verification-strategy.md +0 -69
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-4/with_skill/timing.json +0 -1
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-4/without_skill/grading.json +0 -10
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-4/without_skill/outputs/code-changes.md +0 -252
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-4/without_skill/outputs/execution-plan.md +0 -83
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-4/without_skill/outputs/pr-description.md +0 -33
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-4/without_skill/outputs/verification-strategy.md +0 -101
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-4/without_skill/timing.json +0 -1
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-5/eval_metadata.json +0 -32
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-5/with_skill/grading.json +0 -10
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-5/with_skill/outputs/code-changes.md +0 -387
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-5/with_skill/outputs/execution-plan.md +0 -112
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-5/with_skill/outputs/pr-description.md +0 -51
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-5/with_skill/outputs/verification-strategy.md +0 -75
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-5/with_skill/timing.json +0 -1
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-5/without_skill/grading.json +0 -10
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-5/without_skill/outputs/code-changes.md +0 -529
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-5/without_skill/outputs/execution-plan.md +0 -127
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-5/without_skill/outputs/pr-description.md +0 -42
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-5/without_skill/outputs/verification-strategy.md +0 -120
- package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-5/without_skill/timing.json +0 -1
- package/.opencode/skills/work-with-pr-workspace/iteration-1/review.html +0 -1326
- 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/skills/visual-qa/references/agent-browser-setup.md +0 -45
- 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 -12244
- package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +0 -9842
- 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 -477
- 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/skills/visual-qa/references/agent-browser-setup.md +0 -45
- 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/packages/shared-skills/skills/visual-qa/references/agent-browser-setup.md +0 -45
- /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
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
import { argv, stderr } from "node:process";
|
|
5
5
|
|
|
6
6
|
// src/proxy.ts
|
|
7
|
-
import { existsSync as
|
|
8
|
-
import { basename as basename4, delimiter as delimiter4, dirname as
|
|
7
|
+
import { existsSync as existsSync13, realpathSync as realpathSync6 } from "node:fs";
|
|
8
|
+
import { basename as basename4, delimiter as delimiter4, dirname as dirname11, isAbsolute as isAbsolute6 } from "node:path";
|
|
9
9
|
|
|
10
10
|
// ../mcp-stdio-core/src/record.ts
|
|
11
11
|
function isPlainRecord(value) {
|
|
@@ -184,6 +184,7 @@ async function runJsonRpcStdioServer(config) {
|
|
|
184
184
|
const idleTimer = createIdleTimer(idleTimeoutMs, log, () => {
|
|
185
185
|
isClosed = true;
|
|
186
186
|
config.onIdleTimeout?.();
|
|
187
|
+
config.input.destroy();
|
|
187
188
|
});
|
|
188
189
|
const watchdog = createParentWatchdog(config.parentWatchdog, (parentPid, pollIntervalMs) => {
|
|
189
190
|
isClosed = true;
|
|
@@ -280,7 +281,11 @@ function createParentWatchdog(config, onDeadParent) {
|
|
|
280
281
|
const probeAlive = config.probeAlive ?? isProcessAlive;
|
|
281
282
|
let fired = false;
|
|
282
283
|
const timer = setInterval(() => {
|
|
283
|
-
if (fired
|
|
284
|
+
if (fired)
|
|
285
|
+
return;
|
|
286
|
+
const alive = probeAlive(parentPid);
|
|
287
|
+
config.onPoll?.(alive);
|
|
288
|
+
if (alive)
|
|
284
289
|
return;
|
|
285
290
|
fired = true;
|
|
286
291
|
onDeadParent(parentPid, pollIntervalMs);
|
|
@@ -315,8 +320,8 @@ function createIdleTimer(idleTimeoutMs, log, onTimeout) {
|
|
|
315
320
|
};
|
|
316
321
|
}
|
|
317
322
|
// ../lsp-core/src/lsp/client-wrapper.ts
|
|
318
|
-
import { existsSync as
|
|
319
|
-
import { basename as basename3, dirname as
|
|
323
|
+
import { existsSync as existsSync10, realpathSync as realpathSync5, statSync as statSync3 } from "node:fs";
|
|
324
|
+
import { basename as basename3, dirname as dirname8, join as join5, resolve as resolve8 } from "node:path";
|
|
320
325
|
|
|
321
326
|
// ../lsp-core/src/request-context.ts
|
|
322
327
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
@@ -325,18 +330,17 @@ import { homedir } from "node:os";
|
|
|
325
330
|
import { basename, delimiter, dirname, isAbsolute, join, relative, resolve } from "node:path";
|
|
326
331
|
|
|
327
332
|
class LspRequestContextParseError extends Error {
|
|
328
|
-
code;
|
|
329
|
-
name = "LspRequestContextParseError";
|
|
330
333
|
constructor(code, message) {
|
|
331
334
|
super(message);
|
|
332
335
|
this.code = code;
|
|
336
|
+
this.name = "LspRequestContextParseError";
|
|
333
337
|
}
|
|
334
338
|
}
|
|
335
339
|
|
|
336
340
|
class LspRequestContextUnavailableError extends Error {
|
|
337
|
-
name = "LspRequestContextUnavailableError";
|
|
338
341
|
constructor() {
|
|
339
342
|
super("LSP request context is required. Standalone MCP startup must install one with runWithRequestContext(createStandaloneMcpRequestContext()).");
|
|
343
|
+
this.name = "LspRequestContextUnavailableError";
|
|
340
344
|
}
|
|
341
345
|
}
|
|
342
346
|
var storage = new AsyncLocalStorage;
|
|
@@ -356,7 +360,7 @@ function contextCwd() {
|
|
|
356
360
|
}
|
|
357
361
|
function createStandaloneMcpRequestContext(input = {}) {
|
|
358
362
|
const env = input.env ?? process.env;
|
|
359
|
-
const cwd = canonicalCwd(input.cwd ?? process.cwd());
|
|
363
|
+
const cwd = canonicalCwd(input.cwd ?? env["LSP_TOOLS_MCP_CWD"] ?? process.cwd());
|
|
360
364
|
const home = input.homeDir ?? homedir();
|
|
361
365
|
const projectConfigPaths = translateProjectConfigEnv(env["LSP_TOOLS_MCP_PROJECT_CONFIG"], cwd);
|
|
362
366
|
const userConfigPath = translateHomeConfigEnv(env["LSP_TOOLS_MCP_USER_CONFIG"], home, ".codex/lsp-client.json");
|
|
@@ -499,22 +503,15 @@ function effectiveExtension(filePath) {
|
|
|
499
503
|
|
|
500
504
|
// ../lsp-core/src/lsp/errors.ts
|
|
501
505
|
class LspConnectionClosedError extends Error {
|
|
502
|
-
serverId;
|
|
503
|
-
root;
|
|
504
|
-
name = "LspConnectionClosedError";
|
|
505
506
|
constructor(serverId, root, message) {
|
|
506
507
|
super(message ?? `LSP connection closed for ${serverId} at ${root}`);
|
|
507
508
|
this.serverId = serverId;
|
|
508
509
|
this.root = root;
|
|
510
|
+
this.name = "LspConnectionClosedError";
|
|
509
511
|
}
|
|
510
512
|
}
|
|
511
513
|
|
|
512
514
|
class LspProcessExitedError extends Error {
|
|
513
|
-
serverId;
|
|
514
|
-
root;
|
|
515
|
-
exitCode;
|
|
516
|
-
stderrTail;
|
|
517
|
-
name = "LspProcessExitedError";
|
|
518
515
|
constructor(serverId, root, exitCode, stderrTail) {
|
|
519
516
|
const stderrSuffix = stderrTail ? `
|
|
520
517
|
stderr tail: ${stderrTail}` : "";
|
|
@@ -523,46 +520,59 @@ stderr tail: ${stderrTail}` : "";
|
|
|
523
520
|
this.root = root;
|
|
524
521
|
this.exitCode = exitCode;
|
|
525
522
|
this.stderrTail = stderrTail;
|
|
523
|
+
this.name = "LspProcessExitedError";
|
|
526
524
|
}
|
|
527
525
|
}
|
|
528
526
|
|
|
529
527
|
class LspRequestTimeoutError extends Error {
|
|
530
|
-
method;
|
|
531
|
-
stderrTail;
|
|
532
|
-
name = "LspRequestTimeoutError";
|
|
533
528
|
constructor(method, stderrTail) {
|
|
534
529
|
const stderrSuffix = stderrTail ? `
|
|
535
530
|
recent stderr: ${stderrTail}` : "";
|
|
536
531
|
super(`LSP request timeout (method: ${method})${stderrSuffix}`);
|
|
537
532
|
this.method = method;
|
|
538
533
|
this.stderrTail = stderrTail;
|
|
534
|
+
this.name = "LspRequestTimeoutError";
|
|
539
535
|
}
|
|
540
536
|
}
|
|
541
537
|
|
|
542
538
|
class LspInvalidPathError extends Error {
|
|
543
|
-
|
|
539
|
+
constructor() {
|
|
540
|
+
super(...arguments);
|
|
541
|
+
this.name = "LspInvalidPathError";
|
|
542
|
+
}
|
|
544
543
|
}
|
|
545
544
|
|
|
546
545
|
class LspServerLookupError extends Error {
|
|
547
|
-
lookup;
|
|
548
|
-
name = "LspServerLookupError";
|
|
549
546
|
constructor(message, lookup) {
|
|
550
547
|
super(message);
|
|
551
548
|
this.lookup = lookup;
|
|
549
|
+
this.name = "LspServerLookupError";
|
|
552
550
|
}
|
|
553
551
|
}
|
|
554
552
|
|
|
555
553
|
class LspServerInitializingError extends Error {
|
|
556
|
-
originalError;
|
|
557
|
-
name = "LspServerInitializingError";
|
|
558
554
|
constructor(originalError) {
|
|
559
555
|
super(`LSP server is still initializing. Please retry in a few seconds. Original error: ${originalError.message}`);
|
|
560
556
|
this.originalError = originalError;
|
|
557
|
+
this.name = "LspServerInitializingError";
|
|
561
558
|
}
|
|
562
559
|
}
|
|
563
560
|
|
|
564
561
|
class LspProcessSpawnError extends Error {
|
|
565
|
-
|
|
562
|
+
constructor() {
|
|
563
|
+
super(...arguments);
|
|
564
|
+
this.name = "LspProcessSpawnError";
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
class LspClientRespawnBudgetExceededError extends Error {
|
|
569
|
+
constructor(serverId, root, retryLimit) {
|
|
570
|
+
super(`LSP server ${serverId} at ${root} failed to stay alive; respawn budget exhausted ` + `(${retryLimit} consecutive dead generations). Retrying after the cooldown may succeed.`);
|
|
571
|
+
this.serverId = serverId;
|
|
572
|
+
this.root = root;
|
|
573
|
+
this.retryLimit = retryLimit;
|
|
574
|
+
this.name = "LspClientRespawnBudgetExceededError";
|
|
575
|
+
}
|
|
566
576
|
}
|
|
567
577
|
function isLspDeadConnectionError(err) {
|
|
568
578
|
return err instanceof LspConnectionClosedError || err instanceof LspProcessExitedError;
|
|
@@ -585,6 +595,13 @@ import { pathToFileURL as pathToFileURL3 } from "node:url";
|
|
|
585
595
|
// ../lsp-core/src/lsp/connection.ts
|
|
586
596
|
import { pathToFileURL } from "node:url";
|
|
587
597
|
|
|
598
|
+
// ../lsp-core/src/lsp/timer-provider.ts
|
|
599
|
+
var realTimerProvider = {
|
|
600
|
+
now: () => Date.now(),
|
|
601
|
+
setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
|
|
602
|
+
clearTimeout: (handle) => clearTimeout(handle)
|
|
603
|
+
};
|
|
604
|
+
|
|
588
605
|
// ../lsp-core/src/lsp/constants.ts
|
|
589
606
|
var DEFAULT_MAX_REFERENCES = 200;
|
|
590
607
|
var DEFAULT_MAX_SYMBOLS = 200;
|
|
@@ -593,9 +610,12 @@ var DEFAULT_MAX_DIRECTORY_FILES = 50;
|
|
|
593
610
|
var REQUEST_TIMEOUT_MS = 15000;
|
|
594
611
|
var INIT_TIMEOUT_MS = 60000;
|
|
595
612
|
var IDLE_TIMEOUT_MS = 5 * 60000;
|
|
613
|
+
var MAX_RESIDENT_CLIENTS = 6;
|
|
596
614
|
var REAPER_INTERVAL_MS = 60000;
|
|
597
615
|
var STOP_HARD_KILL_TIMEOUT_MS = 5000;
|
|
598
616
|
var STOP_SIGKILL_GRACE_MS = 1000;
|
|
617
|
+
var CLIENT_RESPAWN_RETRY_LIMIT = 2;
|
|
618
|
+
var CLIENT_RESPAWN_COOLDOWN_MS = 60000;
|
|
599
619
|
|
|
600
620
|
// ../lsp-core/src/lsp/json-rpc-connection.ts
|
|
601
621
|
var HEADER_SEPARATOR2 = `\r
|
|
@@ -607,20 +627,31 @@ var METHOD_NOT_FOUND = -32601;
|
|
|
607
627
|
var INTERNAL_ERROR = -32603;
|
|
608
628
|
|
|
609
629
|
class JsonRpcConnection {
|
|
610
|
-
reader;
|
|
611
|
-
writer;
|
|
612
|
-
pendingRequests = new Map;
|
|
613
|
-
notificationHandlers = new Map;
|
|
614
|
-
requestHandlers = new Map;
|
|
615
|
-
closeHandlers = [];
|
|
616
|
-
errorHandlers = [];
|
|
617
|
-
inputBuffer = Buffer.alloc(0);
|
|
618
|
-
nextRequestId = 1;
|
|
619
|
-
listening = false;
|
|
620
|
-
disposed = false;
|
|
621
630
|
constructor(reader, writer) {
|
|
622
631
|
this.reader = reader;
|
|
623
632
|
this.writer = writer;
|
|
633
|
+
this.pendingRequests = new Map;
|
|
634
|
+
this.notificationHandlers = new Map;
|
|
635
|
+
this.requestHandlers = new Map;
|
|
636
|
+
this.closeHandlers = [];
|
|
637
|
+
this.errorHandlers = [];
|
|
638
|
+
this.inputBuffer = Buffer.alloc(0);
|
|
639
|
+
this.nextRequestId = 1;
|
|
640
|
+
this.listening = false;
|
|
641
|
+
this.disposed = false;
|
|
642
|
+
this.handleData = (chunk) => {
|
|
643
|
+
const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
|
|
644
|
+
this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
|
|
645
|
+
this.drainInputBuffer();
|
|
646
|
+
};
|
|
647
|
+
this.handleClose = () => {
|
|
648
|
+
for (const handler of this.closeHandlers) {
|
|
649
|
+
handler();
|
|
650
|
+
}
|
|
651
|
+
};
|
|
652
|
+
this.handleStreamError = (error) => {
|
|
653
|
+
this.emitError(error);
|
|
654
|
+
};
|
|
624
655
|
}
|
|
625
656
|
listen() {
|
|
626
657
|
if (this.listening)
|
|
@@ -655,7 +686,8 @@ class JsonRpcConnection {
|
|
|
655
686
|
let cancelAfterWrite = false;
|
|
656
687
|
let settled = false;
|
|
657
688
|
const writeCancel = () => this.writeMessage({ jsonrpc: "2.0", method: "$/cancelRequest", params: { id } });
|
|
658
|
-
|
|
689
|
+
let rejectAfterCancelWrite;
|
|
690
|
+
const responsePromise = new Promise((resolve, reject) => {
|
|
659
691
|
const cleanup = () => {
|
|
660
692
|
options.signal?.removeEventListener("abort", onAbort);
|
|
661
693
|
};
|
|
@@ -666,22 +698,26 @@ class JsonRpcConnection {
|
|
|
666
698
|
this.pendingRequests.delete(key);
|
|
667
699
|
cleanup();
|
|
668
700
|
const rejectCancelled = () => reject(abortError(options.signal));
|
|
701
|
+
rejectAfterCancelWrite = async () => {
|
|
702
|
+
try {
|
|
703
|
+
await writeCancel();
|
|
704
|
+
} catch (error) {
|
|
705
|
+
this.emitError(toError(error));
|
|
706
|
+
}
|
|
707
|
+
rejectCancelled();
|
|
708
|
+
};
|
|
669
709
|
if (!requestWritten) {
|
|
670
710
|
cancelAfterWrite = true;
|
|
671
|
-
rejectCancelled();
|
|
672
711
|
return;
|
|
673
712
|
}
|
|
674
|
-
|
|
675
|
-
this.emitError(toError(error));
|
|
676
|
-
rejectCancelled();
|
|
677
|
-
});
|
|
713
|
+
rejectAfterCancelWrite();
|
|
678
714
|
};
|
|
679
715
|
const onAbort = () => settleCancel();
|
|
680
716
|
this.pendingRequests.set(key, {
|
|
681
717
|
resolve(result) {
|
|
682
718
|
settled = true;
|
|
683
719
|
cleanup();
|
|
684
|
-
|
|
720
|
+
resolve(result);
|
|
685
721
|
},
|
|
686
722
|
reject(error) {
|
|
687
723
|
settled = true;
|
|
@@ -702,7 +738,7 @@ class JsonRpcConnection {
|
|
|
702
738
|
await this.writeMessage(message);
|
|
703
739
|
requestWritten = true;
|
|
704
740
|
if (cancelAfterWrite)
|
|
705
|
-
await
|
|
741
|
+
await rejectAfterCancelWrite?.();
|
|
706
742
|
} catch (error) {
|
|
707
743
|
if (settled)
|
|
708
744
|
return responsePromise;
|
|
@@ -741,19 +777,6 @@ class JsonRpcConnection {
|
|
|
741
777
|
this.notificationHandlers.clear();
|
|
742
778
|
this.requestHandlers.clear();
|
|
743
779
|
}
|
|
744
|
-
handleData = (chunk) => {
|
|
745
|
-
const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
|
|
746
|
-
this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
|
|
747
|
-
this.drainInputBuffer();
|
|
748
|
-
};
|
|
749
|
-
handleClose = () => {
|
|
750
|
-
for (const handler of this.closeHandlers) {
|
|
751
|
-
handler();
|
|
752
|
-
}
|
|
753
|
-
};
|
|
754
|
-
handleStreamError = (error) => {
|
|
755
|
-
this.emitError(error);
|
|
756
|
-
};
|
|
757
780
|
drainInputBuffer() {
|
|
758
781
|
while (true) {
|
|
759
782
|
const headerEnd = this.inputBuffer.indexOf(HEADER_SEPARATOR2);
|
|
@@ -853,13 +876,13 @@ class JsonRpcConnection {
|
|
|
853
876
|
const payload = `Content-Length: ${Buffer.byteLength(body, "utf8")}\r
|
|
854
877
|
\r
|
|
855
878
|
${body}`;
|
|
856
|
-
return new Promise((
|
|
879
|
+
return new Promise((resolve, reject) => {
|
|
857
880
|
this.writer.write(payload, (error) => {
|
|
858
881
|
if (error) {
|
|
859
882
|
reject(error);
|
|
860
883
|
return;
|
|
861
884
|
}
|
|
862
|
-
|
|
885
|
+
resolve();
|
|
863
886
|
});
|
|
864
887
|
});
|
|
865
888
|
}
|
|
@@ -946,9 +969,9 @@ function validateCwd(cwd) {
|
|
|
946
969
|
}
|
|
947
970
|
}
|
|
948
971
|
function wrap(proc) {
|
|
949
|
-
const exitedPromise = new Promise((
|
|
950
|
-
proc.once("close", (code) =>
|
|
951
|
-
proc.once("error", () =>
|
|
972
|
+
const exitedPromise = new Promise((resolve) => {
|
|
973
|
+
proc.once("close", (code) => resolve(code ?? 0));
|
|
974
|
+
proc.once("error", () => resolve(1));
|
|
952
975
|
});
|
|
953
976
|
if (!proc.stdin || !proc.stdout || !proc.stderr) {
|
|
954
977
|
throw new LspProcessSpawnError("Spawned process is missing one of stdin/stdout/stderr pipes");
|
|
@@ -1101,33 +1124,29 @@ function isPosition(value) {
|
|
|
1101
1124
|
|
|
1102
1125
|
// ../lsp-core/src/lsp/transport.ts
|
|
1103
1126
|
class LspClientNotStartedError extends Error {
|
|
1104
|
-
serverId;
|
|
1105
|
-
root;
|
|
1106
|
-
name = "LspClientNotStartedError";
|
|
1107
1127
|
constructor(serverId, root) {
|
|
1108
1128
|
super("LSP client not started");
|
|
1109
1129
|
this.serverId = serverId;
|
|
1110
1130
|
this.root = root;
|
|
1131
|
+
this.name = "LspClientNotStartedError";
|
|
1111
1132
|
}
|
|
1112
1133
|
}
|
|
1113
1134
|
|
|
1114
1135
|
class LspClientTransport {
|
|
1115
|
-
root
|
|
1116
|
-
server;
|
|
1117
|
-
proc = null;
|
|
1118
|
-
connection = null;
|
|
1119
|
-
stderrBuffer = [];
|
|
1120
|
-
processExited = false;
|
|
1121
|
-
diagnosticsStore = new Map;
|
|
1122
|
-
requestTimeoutMs;
|
|
1123
|
-
initializeTimeoutMs;
|
|
1124
|
-
workspaceApplyEditHandler = null;
|
|
1125
|
-
diagnosticPullSupported = false;
|
|
1126
|
-
constructor(root, server2, timeouts = {}) {
|
|
1136
|
+
constructor(root, server, timeouts = {}) {
|
|
1127
1137
|
this.root = root;
|
|
1128
|
-
this.server =
|
|
1138
|
+
this.server = server;
|
|
1139
|
+
this.proc = null;
|
|
1140
|
+
this.connection = null;
|
|
1141
|
+
this.stderrBuffer = [];
|
|
1142
|
+
this.processExited = false;
|
|
1143
|
+
this.diagnosticsStore = new Map;
|
|
1144
|
+
this.workspaceApplyEditHandler = null;
|
|
1145
|
+
this.diagnosticPullSupported = false;
|
|
1146
|
+
this.documentFormattingSupported = false;
|
|
1129
1147
|
this.requestTimeoutMs = timeouts.requestTimeoutMs ?? REQUEST_TIMEOUT_MS;
|
|
1130
1148
|
this.initializeTimeoutMs = timeouts.initializeTimeoutMs ?? INIT_TIMEOUT_MS;
|
|
1149
|
+
this.timerProvider = timeouts.timerProvider ?? realTimerProvider;
|
|
1131
1150
|
}
|
|
1132
1151
|
pid() {
|
|
1133
1152
|
return this.proc?.pid;
|
|
@@ -1147,6 +1166,12 @@ class LspClientTransport {
|
|
|
1147
1166
|
isDiagnosticPullSupported() {
|
|
1148
1167
|
return this.diagnosticPullSupported;
|
|
1149
1168
|
}
|
|
1169
|
+
setDocumentFormattingSupported(supported) {
|
|
1170
|
+
this.documentFormattingSupported = supported;
|
|
1171
|
+
}
|
|
1172
|
+
isDocumentFormattingSupported() {
|
|
1173
|
+
return this.documentFormattingSupported;
|
|
1174
|
+
}
|
|
1150
1175
|
handlePublishDiagnostics(params) {
|
|
1151
1176
|
this.diagnosticsStore.set(params.uri, [...params.diagnostics]);
|
|
1152
1177
|
}
|
|
@@ -1222,7 +1247,7 @@ class LspClientTransport {
|
|
|
1222
1247
|
const options = args[1];
|
|
1223
1248
|
const timeoutMs = options?.timeoutMs ?? this.requestTimeoutMs;
|
|
1224
1249
|
const timeoutController = new AbortController;
|
|
1225
|
-
const timeoutHandle = setTimeout(() => {
|
|
1250
|
+
const timeoutHandle = this.timerProvider.setTimeout(() => {
|
|
1226
1251
|
const stderrTail = this.stderrBuffer.slice(-5).join(`
|
|
1227
1252
|
`);
|
|
1228
1253
|
timeoutController.abort(new LspRequestTimeoutError(method, stderrTail || undefined));
|
|
@@ -1241,7 +1266,7 @@ class LspClientTransport {
|
|
|
1241
1266
|
}
|
|
1242
1267
|
throw error;
|
|
1243
1268
|
} finally {
|
|
1244
|
-
clearTimeout(timeoutHandle);
|
|
1269
|
+
this.timerProvider.clearTimeout(timeoutHandle);
|
|
1245
1270
|
combinedSignal.dispose();
|
|
1246
1271
|
}
|
|
1247
1272
|
}
|
|
@@ -1292,8 +1317,8 @@ class LspClientTransport {
|
|
|
1292
1317
|
try {
|
|
1293
1318
|
proc.kill();
|
|
1294
1319
|
let timeoutId;
|
|
1295
|
-
const timeoutPromise = new Promise((
|
|
1296
|
-
timeoutId = setTimeout(
|
|
1320
|
+
const timeoutPromise = new Promise((resolve) => {
|
|
1321
|
+
timeoutId = setTimeout(resolve, STOP_HARD_KILL_TIMEOUT_MS);
|
|
1297
1322
|
});
|
|
1298
1323
|
await Promise.race([
|
|
1299
1324
|
proc.exited.then(() => {
|
|
@@ -1309,7 +1334,7 @@ class LspClientTransport {
|
|
|
1309
1334
|
proc.kill("SIGKILL");
|
|
1310
1335
|
await Promise.race([
|
|
1311
1336
|
proc.exited,
|
|
1312
|
-
new Promise((
|
|
1337
|
+
new Promise((resolve) => setTimeout(resolve, STOP_SIGKILL_GRACE_MS))
|
|
1313
1338
|
]);
|
|
1314
1339
|
} catch (error) {
|
|
1315
1340
|
reportBestEffortCleanupError("hard process kill", error instanceof Error ? error : String(error));
|
|
@@ -1360,6 +1385,14 @@ function supportsDiagnosticPull(capabilities) {
|
|
|
1360
1385
|
return false;
|
|
1361
1386
|
return Object.hasOwn(capabilities, "diagnosticProvider");
|
|
1362
1387
|
}
|
|
1388
|
+
function supportsDocumentFormatting(capabilities) {
|
|
1389
|
+
if (capabilities === undefined)
|
|
1390
|
+
return false;
|
|
1391
|
+
const provider = capabilities.documentFormattingProvider;
|
|
1392
|
+
if (provider === undefined || provider === null || provider === false)
|
|
1393
|
+
return false;
|
|
1394
|
+
return provider === true || typeof provider === "object";
|
|
1395
|
+
}
|
|
1363
1396
|
|
|
1364
1397
|
class LspClientConnection extends LspClientTransport {
|
|
1365
1398
|
async initialize() {
|
|
@@ -1376,6 +1409,7 @@ class LspClientConnection extends LspClientTransport {
|
|
|
1376
1409
|
references: {},
|
|
1377
1410
|
documentSymbol: { hierarchicalDocumentSymbolSupport: true },
|
|
1378
1411
|
publishDiagnostics: {},
|
|
1412
|
+
formatting: { dynamicRegistration: false },
|
|
1379
1413
|
rename: {
|
|
1380
1414
|
prepareSupport: true,
|
|
1381
1415
|
prepareSupportDefaultBehavior: 1
|
|
@@ -1417,6 +1451,7 @@ class LspClientConnection extends LspClientTransport {
|
|
|
1417
1451
|
initializationOptions: this.server.initialization
|
|
1418
1452
|
}, { timeoutMs: this.initializeTimeoutMs });
|
|
1419
1453
|
this.setDiagnosticPullSupported(supportsDiagnosticPull(result?.capabilities));
|
|
1454
|
+
this.setDocumentFormattingSupported(supportsDocumentFormatting(result?.capabilities));
|
|
1420
1455
|
await this.sendNotification("initialized", {});
|
|
1421
1456
|
await this.sendNotification("workspace/didChangeConfiguration", {
|
|
1422
1457
|
settings: { json: { validate: { enable: true } } }
|
|
@@ -1612,6 +1647,17 @@ function canonicalPath(filePath) {
|
|
|
1612
1647
|
return absolute;
|
|
1613
1648
|
}
|
|
1614
1649
|
}
|
|
1650
|
+
function normalizeDocumentUri(uri) {
|
|
1651
|
+
let decoded = uri;
|
|
1652
|
+
try {
|
|
1653
|
+
decoded = decodeURIComponent(uri);
|
|
1654
|
+
} catch {
|
|
1655
|
+
decoded = uri;
|
|
1656
|
+
}
|
|
1657
|
+
if (process.platform !== "win32")
|
|
1658
|
+
return decoded;
|
|
1659
|
+
return decoded.replace(/^(file:\/\/\/)([a-z]):/, (_match, prefix, drive) => `${prefix}${drive.toUpperCase()}:`);
|
|
1660
|
+
}
|
|
1615
1661
|
function isSameOrDescendant(candidate, parent) {
|
|
1616
1662
|
const suffix = relative2(parent, candidate);
|
|
1617
1663
|
return suffix === "" || !suffix.startsWith("..") && suffix !== "..";
|
|
@@ -1622,17 +1668,18 @@ function movedPath(candidate, oldPath, newPath) {
|
|
|
1622
1668
|
}
|
|
1623
1669
|
|
|
1624
1670
|
class WorkspaceDocumentState {
|
|
1625
|
-
sendNotification;
|
|
1626
|
-
clearDiagnostics;
|
|
1627
|
-
openDocuments = new Map;
|
|
1628
|
-
openByUri = new Map;
|
|
1629
|
-
openPromises = new Map;
|
|
1630
|
-
now;
|
|
1631
|
-
versionlessPublishQuiescenceMs;
|
|
1632
1671
|
constructor(sendNotification, clearDiagnostics, options = {}) {
|
|
1633
1672
|
this.sendNotification = sendNotification;
|
|
1634
1673
|
this.clearDiagnostics = clearDiagnostics;
|
|
1635
|
-
this.
|
|
1674
|
+
this.openDocuments = new Map;
|
|
1675
|
+
this.openByUri = new Map;
|
|
1676
|
+
this.openPromises = new Map;
|
|
1677
|
+
this.timerProvider = options.timerProvider ?? {
|
|
1678
|
+
now: options.now ?? (() => Date.now()),
|
|
1679
|
+
setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
|
|
1680
|
+
clearTimeout: (handle) => clearTimeout(handle)
|
|
1681
|
+
};
|
|
1682
|
+
this.now = () => this.timerProvider.now();
|
|
1636
1683
|
this.versionlessPublishQuiescenceMs = options.versionlessPublishQuiescenceMs ?? DEFAULT_VERSIONLESS_PUBLISH_QUIESCENCE_MS;
|
|
1637
1684
|
}
|
|
1638
1685
|
async openFile(filePath) {
|
|
@@ -1654,7 +1701,7 @@ class WorkspaceDocumentState {
|
|
|
1654
1701
|
return this.openDocuments.get(canonicalPath(filePath))?.version;
|
|
1655
1702
|
}
|
|
1656
1703
|
getStoredDiagnostics(uri) {
|
|
1657
|
-
const state = this.openByUri.get(uri);
|
|
1704
|
+
const state = this.openByUri.get(normalizeDocumentUri(uri));
|
|
1658
1705
|
if (!state)
|
|
1659
1706
|
return [];
|
|
1660
1707
|
return state.lastPublish?.diagnostics ?? state.pullCache?.diagnostics ?? [];
|
|
@@ -1676,13 +1723,13 @@ class WorkspaceDocumentState {
|
|
|
1676
1723
|
return state !== undefined && state.uri === snapshot.uri && state.version === snapshot.version && state.generation === snapshot.documentGeneration;
|
|
1677
1724
|
}
|
|
1678
1725
|
getPullCache(snapshot) {
|
|
1679
|
-
const state = this.openByUri.get(snapshot.uri);
|
|
1726
|
+
const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
|
|
1680
1727
|
if (!state?.pullCache || state.pullCache.documentVersion !== snapshot.version)
|
|
1681
1728
|
return null;
|
|
1682
1729
|
return state.pullCache;
|
|
1683
1730
|
}
|
|
1684
1731
|
recordPullDiagnostics(snapshot, report) {
|
|
1685
|
-
const state = this.openByUri.get(snapshot.uri);
|
|
1732
|
+
const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
|
|
1686
1733
|
if (!state)
|
|
1687
1734
|
return;
|
|
1688
1735
|
state.pullCache = {
|
|
@@ -1692,7 +1739,7 @@ class WorkspaceDocumentState {
|
|
|
1692
1739
|
};
|
|
1693
1740
|
}
|
|
1694
1741
|
recordPublishedDiagnostics(params) {
|
|
1695
|
-
const state = this.openByUri.get(params.uri);
|
|
1742
|
+
const state = this.openByUri.get(normalizeDocumentUri(params.uri));
|
|
1696
1743
|
if (!state)
|
|
1697
1744
|
return;
|
|
1698
1745
|
state.publishGeneration += 1;
|
|
@@ -1706,7 +1753,7 @@ class WorkspaceDocumentState {
|
|
|
1706
1753
|
this.notifyWaiters(state);
|
|
1707
1754
|
}
|
|
1708
1755
|
resolvePushDiagnostics(snapshot) {
|
|
1709
|
-
const state = this.openByUri.get(snapshot.uri);
|
|
1756
|
+
const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
|
|
1710
1757
|
if (!state?.lastPublish)
|
|
1711
1758
|
return { status: "missing" };
|
|
1712
1759
|
const publish = state.lastPublish;
|
|
@@ -1720,20 +1767,22 @@ class WorkspaceDocumentState {
|
|
|
1720
1767
|
return waitMs === 0 ? { status: "ready", diagnostics: publish.diagnostics } : { status: "wait", waitMs };
|
|
1721
1768
|
}
|
|
1722
1769
|
waitForDiagnosticsActivity(snapshot, timeoutMs) {
|
|
1723
|
-
const state = this.openByUri.get(snapshot.uri);
|
|
1770
|
+
const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
|
|
1724
1771
|
if (!state || timeoutMs <= 0)
|
|
1725
1772
|
return Promise.resolve();
|
|
1773
|
+
if (state.publishGeneration !== snapshot.publishGeneration)
|
|
1774
|
+
return Promise.resolve();
|
|
1726
1775
|
return new Promise((resolveActivity) => {
|
|
1727
1776
|
let settled = false;
|
|
1728
1777
|
const finish = () => {
|
|
1729
1778
|
if (settled)
|
|
1730
1779
|
return;
|
|
1731
1780
|
settled = true;
|
|
1732
|
-
clearTimeout(timer);
|
|
1781
|
+
this.timerProvider.clearTimeout(timer);
|
|
1733
1782
|
state.waiters.delete(finish);
|
|
1734
1783
|
resolveActivity();
|
|
1735
1784
|
};
|
|
1736
|
-
const timer = setTimeout(finish, timeoutMs);
|
|
1785
|
+
const timer = this.timerProvider.setTimeout(finish, timeoutMs);
|
|
1737
1786
|
if (typeof timer.unref === "function")
|
|
1738
1787
|
timer.unref();
|
|
1739
1788
|
state.waiters.add(finish);
|
|
@@ -1841,7 +1890,7 @@ class WorkspaceDocumentState {
|
|
|
1841
1890
|
waiters: new Set
|
|
1842
1891
|
};
|
|
1843
1892
|
this.openDocuments.set(path, state);
|
|
1844
|
-
this.openByUri.set(state.uri, state);
|
|
1893
|
+
this.openByUri.set(normalizeDocumentUri(state.uri), state);
|
|
1845
1894
|
this.notifyWaiters(state);
|
|
1846
1895
|
await this.sendNotification("textDocument/didOpen", {
|
|
1847
1896
|
textDocument: { uri: state.uri, languageId: state.languageId, version: state.version, text }
|
|
@@ -1866,7 +1915,7 @@ class WorkspaceDocumentState {
|
|
|
1866
1915
|
}
|
|
1867
1916
|
async closeDocument(state) {
|
|
1868
1917
|
this.openDocuments.delete(state.path);
|
|
1869
|
-
this.openByUri.delete(state.uri);
|
|
1918
|
+
this.openByUri.delete(normalizeDocumentUri(state.uri));
|
|
1870
1919
|
this.clearDiagnostics(state.uri);
|
|
1871
1920
|
this.notifyWaiters(state);
|
|
1872
1921
|
await this.sendNotification("textDocument/didClose", { textDocument: { uri: state.uri } });
|
|
@@ -1895,13 +1944,11 @@ import { dirname as dirname2, isAbsolute as isAbsolute2, relative as relative3,
|
|
|
1895
1944
|
import { fileURLToPath } from "node:url";
|
|
1896
1945
|
|
|
1897
1946
|
class WorkspaceEditPathError extends Error {
|
|
1898
|
-
path;
|
|
1899
|
-
detail;
|
|
1900
|
-
name = "WorkspaceEditPathError";
|
|
1901
1947
|
constructor(path, detail) {
|
|
1902
1948
|
super(`${detail}: ${path}`);
|
|
1903
1949
|
this.path = path;
|
|
1904
1950
|
this.detail = detail;
|
|
1951
|
+
this.name = "WorkspaceEditPathError";
|
|
1905
1952
|
}
|
|
1906
1953
|
}
|
|
1907
1954
|
function isPathInsideWorkspace(filePath, workspaceRoot) {
|
|
@@ -2193,13 +2240,11 @@ function canonicalFingerprint(operations) {
|
|
|
2193
2240
|
|
|
2194
2241
|
// ../lsp-core/src/lsp/workspace-edit-types.ts
|
|
2195
2242
|
class WorkspaceEditValidationError extends Error {
|
|
2196
|
-
changeIndex;
|
|
2197
|
-
detail;
|
|
2198
|
-
name = "WorkspaceEditValidationError";
|
|
2199
2243
|
constructor(changeIndex, detail) {
|
|
2200
2244
|
super(`change ${changeIndex}: ${detail}`);
|
|
2201
2245
|
this.changeIndex = changeIndex;
|
|
2202
2246
|
this.detail = detail;
|
|
2247
|
+
this.name = "WorkspaceEditValidationError";
|
|
2203
2248
|
}
|
|
2204
2249
|
}
|
|
2205
2250
|
|
|
@@ -2285,14 +2330,14 @@ function parseSinglePathResource(input, kind) {
|
|
|
2285
2330
|
return;
|
|
2286
2331
|
}
|
|
2287
2332
|
if (kind === "create") {
|
|
2288
|
-
const
|
|
2333
|
+
const options = parseOptions(change["options"], ["overwrite", "ignoreIfExists"], changeIndex);
|
|
2289
2334
|
target.operations.push({
|
|
2290
2335
|
kind,
|
|
2291
2336
|
changeIndex,
|
|
2292
2337
|
path: resolvedPath.path,
|
|
2293
2338
|
reportedPath: resolvedPath.requestedPath,
|
|
2294
|
-
overwrite:
|
|
2295
|
-
ignoreIfExists:
|
|
2339
|
+
overwrite: options["overwrite"] ?? false,
|
|
2340
|
+
ignoreIfExists: options["ignoreIfExists"] ?? false,
|
|
2296
2341
|
followedSymbolicLink: resolvedPath.followedSymbolicLink
|
|
2297
2342
|
});
|
|
2298
2343
|
return;
|
|
@@ -2697,10 +2742,9 @@ function simulateDelete(operation, virtual) {
|
|
|
2697
2742
|
import { existsSync as existsSync5, lstatSync as lstatSync3, readdirSync as readdirSync2 } from "node:fs";
|
|
2698
2743
|
import { dirname as dirname4, resolve as resolve5 } from "node:path";
|
|
2699
2744
|
class WorkspaceSnapshotBuilder {
|
|
2700
|
-
workspaceRoot;
|
|
2701
|
-
snapshots = new Map;
|
|
2702
2745
|
constructor(workspaceRoot) {
|
|
2703
2746
|
this.workspaceRoot = workspaceRoot;
|
|
2747
|
+
this.snapshots = new Map;
|
|
2704
2748
|
}
|
|
2705
2749
|
build(operations) {
|
|
2706
2750
|
this.add(this.workspaceRoot, false);
|
|
@@ -2744,8 +2788,10 @@ function snapshotOperations(operations, workspaceRoot) {
|
|
|
2744
2788
|
|
|
2745
2789
|
// ../lsp-core/src/lsp/workspace-edit-plan.ts
|
|
2746
2790
|
class PlanPathIndex {
|
|
2747
|
-
|
|
2748
|
-
|
|
2791
|
+
constructor() {
|
|
2792
|
+
this.firstChangeByPath = new Map;
|
|
2793
|
+
this.reportedPathByCanonical = new Map;
|
|
2794
|
+
}
|
|
2749
2795
|
build(operations) {
|
|
2750
2796
|
for (const operation of operations) {
|
|
2751
2797
|
switch (operation.kind) {
|
|
@@ -2761,11 +2807,11 @@ class PlanPathIndex {
|
|
|
2761
2807
|
}
|
|
2762
2808
|
}
|
|
2763
2809
|
}
|
|
2764
|
-
add(path,
|
|
2810
|
+
add(path, reportedPath, changeIndex) {
|
|
2765
2811
|
if (!this.firstChangeByPath.has(path))
|
|
2766
2812
|
this.firstChangeByPath.set(path, changeIndex);
|
|
2767
2813
|
if (!this.reportedPathByCanonical.has(path))
|
|
2768
|
-
this.reportedPathByCanonical.set(path,
|
|
2814
|
+
this.reportedPathByCanonical.set(path, reportedPath);
|
|
2769
2815
|
}
|
|
2770
2816
|
}
|
|
2771
2817
|
function fingerprintWorkspaceEdit(edit, workspaceRoot) {
|
|
@@ -2834,14 +2880,11 @@ function isRecord4(value) {
|
|
|
2834
2880
|
}
|
|
2835
2881
|
|
|
2836
2882
|
class WorkspaceMutationController {
|
|
2837
|
-
workspaceRoot;
|
|
2838
|
-
documents;
|
|
2839
|
-
activeLease = null;
|
|
2840
|
-
nextLeaseId = 1;
|
|
2841
|
-
io;
|
|
2842
2883
|
constructor(workspaceRoot, documents) {
|
|
2843
2884
|
this.workspaceRoot = workspaceRoot;
|
|
2844
2885
|
this.documents = documents;
|
|
2886
|
+
this.activeLease = null;
|
|
2887
|
+
this.nextLeaseId = 1;
|
|
2845
2888
|
}
|
|
2846
2889
|
setIo(io) {
|
|
2847
2890
|
this.io = io;
|
|
@@ -2880,15 +2923,15 @@ class WorkspaceMutationController {
|
|
|
2880
2923
|
};
|
|
2881
2924
|
}
|
|
2882
2925
|
lease.phase = "applying";
|
|
2883
|
-
lease.applyCompletion = new Promise((
|
|
2884
|
-
lease.resolveApply =
|
|
2926
|
+
lease.applyCompletion = new Promise((resolve) => {
|
|
2927
|
+
lease.resolveApply = resolve;
|
|
2885
2928
|
});
|
|
2886
2929
|
const edit = isRecord4(params) ? params["edit"] : undefined;
|
|
2887
|
-
const
|
|
2888
|
-
lease.serverApply =
|
|
2930
|
+
const record = edit === undefined ? { fingerprint: null, result: failure("workspace/applyEdit params.edit is required", 0) } : await this.applyEdit(edit, lease);
|
|
2931
|
+
lease.serverApply = record;
|
|
2889
2932
|
lease.phase = "settled";
|
|
2890
2933
|
lease.resolveApply?.();
|
|
2891
|
-
return responseFor(
|
|
2934
|
+
return responseFor(record.result);
|
|
2892
2935
|
}
|
|
2893
2936
|
async reconcileRename(leaseToken, edit) {
|
|
2894
2937
|
const lease = this.requireActiveLease(leaseToken);
|
|
@@ -2904,16 +2947,16 @@ class WorkspaceMutationController {
|
|
|
2904
2947
|
const applied = await this.applyEdit(edit, lease);
|
|
2905
2948
|
return { edit, apply: applied.result };
|
|
2906
2949
|
}
|
|
2907
|
-
reconcileServerApply(
|
|
2950
|
+
reconcileServerApply(record, edit) {
|
|
2908
2951
|
if (!edit)
|
|
2909
|
-
return { edit, apply:
|
|
2952
|
+
return { edit, apply: record.result };
|
|
2910
2953
|
const fingerprint = fingerprintWorkspaceEdit(edit, this.workspaceRoot);
|
|
2911
|
-
if (fingerprint.success &&
|
|
2912
|
-
return { edit, apply:
|
|
2954
|
+
if (fingerprint.success && record.fingerprint !== null && fingerprint.fingerprint === record.fingerprint) {
|
|
2955
|
+
return { edit, apply: record.result };
|
|
2913
2956
|
}
|
|
2914
2957
|
return {
|
|
2915
2958
|
edit,
|
|
2916
|
-
apply: failure("rename result conflicts with server-applied workspace edit", 0,
|
|
2959
|
+
apply: failure("rename result conflicts with server-applied workspace edit", 0, record.result)
|
|
2917
2960
|
};
|
|
2918
2961
|
}
|
|
2919
2962
|
async applyEdit(edit, lease) {
|
|
@@ -2954,14 +2997,12 @@ var DIAGNOSTICS_FRESHNESS_TIMEOUT_MS = 3000;
|
|
|
2954
2997
|
var VERSIONLESS_PUBLISH_QUIESCENCE_MS = 250;
|
|
2955
2998
|
|
|
2956
2999
|
class LspClient extends LspClientConnection {
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
diagnosticsFreshnessTimeoutMs;
|
|
2961
|
-
constructor(root, server2, options = {}) {
|
|
2962
|
-
super(root, server2, options);
|
|
3000
|
+
constructor(root, server, options = {}) {
|
|
3001
|
+
super(root, server, options);
|
|
3002
|
+
this.diagnosticPullErrors = [];
|
|
2963
3003
|
this.diagnosticsFreshnessTimeoutMs = options.diagnosticsFreshnessTimeoutMs ?? DIAGNOSTICS_FRESHNESS_TIMEOUT_MS;
|
|
2964
3004
|
this.documents = new WorkspaceDocumentState((method, params) => this.sendNotification(method, params), (uri) => this.diagnosticsStore.delete(uri), {
|
|
3005
|
+
timerProvider: this.timerProvider,
|
|
2965
3006
|
versionlessPublishQuiescenceMs: options.versionlessPublishQuiescenceMs ?? VERSIONLESS_PUBLISH_QUIESCENCE_MS
|
|
2966
3007
|
});
|
|
2967
3008
|
this.workspaceMutations = new WorkspaceMutationController(root, this.documents);
|
|
@@ -3014,6 +3055,18 @@ class LspClient extends LspClientConnection {
|
|
|
3014
3055
|
textDocument: { uri: pathToFileURL3(absPath).href }
|
|
3015
3056
|
}, options);
|
|
3016
3057
|
}
|
|
3058
|
+
async formatDocument(filePath, options, signal) {
|
|
3059
|
+
if (!this.isDocumentFormattingSupported())
|
|
3060
|
+
return null;
|
|
3061
|
+
const absPath = this.resolveWorkspacePath(filePath);
|
|
3062
|
+
await this.openFile(absPath);
|
|
3063
|
+
const requestOptions = signal === undefined ? {} : { signal };
|
|
3064
|
+
const edits = await this.sendRequest("textDocument/formatting", {
|
|
3065
|
+
textDocument: { uri: pathToFileURL3(absPath).href },
|
|
3066
|
+
options
|
|
3067
|
+
}, requestOptions);
|
|
3068
|
+
return edits ?? [];
|
|
3069
|
+
}
|
|
3017
3070
|
async workspaceSymbols(query, signal) {
|
|
3018
3071
|
const options = signal === undefined ? {} : { signal };
|
|
3019
3072
|
return this.sendRequest("workspace/symbol", { query }, options);
|
|
@@ -3053,7 +3106,7 @@ class LspClient extends LspClientConnection {
|
|
|
3053
3106
|
const absPath = this.resolveWorkspacePath(filePath);
|
|
3054
3107
|
const uri = pathToFileURL3(absPath).href;
|
|
3055
3108
|
await this.openFile(absPath);
|
|
3056
|
-
const deadlineAt =
|
|
3109
|
+
const deadlineAt = this.timerProvider.now() + this.diagnosticsFreshnessTimeoutMs;
|
|
3057
3110
|
for (;; ) {
|
|
3058
3111
|
signal?.throwIfAborted();
|
|
3059
3112
|
const snapshot = this.documents.captureDiagnosticSnapshot(absPath);
|
|
@@ -3066,13 +3119,13 @@ class LspClient extends LspClientConnection {
|
|
|
3066
3119
|
if (!pushFallbackOnly) {
|
|
3067
3120
|
const cached = this.documents.getPullCache(snapshot);
|
|
3068
3121
|
try {
|
|
3069
|
-
const
|
|
3070
|
-
if (
|
|
3122
|
+
const remainingMs = deadlineAt - this.timerProvider.now();
|
|
3123
|
+
if (remainingMs <= 0)
|
|
3071
3124
|
return this.freshnessTimeout(absPath);
|
|
3072
3125
|
const result = await this.sendRequest("textDocument/diagnostic", {
|
|
3073
3126
|
textDocument: { uri },
|
|
3074
3127
|
...cached?.resultId === undefined ? {} : { previousResultId: cached.resultId }
|
|
3075
|
-
}, { timeoutMs:
|
|
3128
|
+
}, { timeoutMs: remainingMs, ...signal === undefined ? {} : { signal } });
|
|
3076
3129
|
if (!this.documents.isCurrentSnapshot(snapshot))
|
|
3077
3130
|
continue;
|
|
3078
3131
|
const report = this.parseDiagnosticPullReport(result);
|
|
@@ -3101,7 +3154,7 @@ class LspClient extends LspClientConnection {
|
|
|
3101
3154
|
}
|
|
3102
3155
|
if (!pushFallbackOnly)
|
|
3103
3156
|
continue;
|
|
3104
|
-
const remainingMs = deadlineAt -
|
|
3157
|
+
const remainingMs = deadlineAt - this.timerProvider.now();
|
|
3105
3158
|
if (remainingMs <= 0) {
|
|
3106
3159
|
if (!this.isDiagnosticPullSupported() && snapshot.publishGeneration === 0) {
|
|
3107
3160
|
const cached = this.documents.getPullCache(snapshot);
|
|
@@ -3153,7 +3206,7 @@ function waitForDiagnosticsActivity(wait, signal) {
|
|
|
3153
3206
|
return wait;
|
|
3154
3207
|
if (signal.aborted)
|
|
3155
3208
|
return Promise.reject(abortError2(signal));
|
|
3156
|
-
return new Promise((
|
|
3209
|
+
return new Promise((resolve, reject) => {
|
|
3157
3210
|
const onAbort = () => {
|
|
3158
3211
|
signal.removeEventListener("abort", onAbort);
|
|
3159
3212
|
reject(abortError2(signal));
|
|
@@ -3161,7 +3214,7 @@ function waitForDiagnosticsActivity(wait, signal) {
|
|
|
3161
3214
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
3162
3215
|
wait.then(() => {
|
|
3163
3216
|
signal.removeEventListener("abort", onAbort);
|
|
3164
|
-
|
|
3217
|
+
resolve();
|
|
3165
3218
|
}, (error) => {
|
|
3166
3219
|
signal.removeEventListener("abort", onAbort);
|
|
3167
3220
|
reject(error);
|
|
@@ -3229,7 +3282,7 @@ async function stopClientBestEffort(client) {
|
|
|
3229
3282
|
function awaitWithSignal(promise, signal) {
|
|
3230
3283
|
if (!signal)
|
|
3231
3284
|
return promise;
|
|
3232
|
-
return new Promise((
|
|
3285
|
+
return new Promise((resolve, reject) => {
|
|
3233
3286
|
let settled = false;
|
|
3234
3287
|
const onAbort = () => {
|
|
3235
3288
|
if (settled)
|
|
@@ -3247,7 +3300,7 @@ function awaitWithSignal(promise, signal) {
|
|
|
3247
3300
|
return;
|
|
3248
3301
|
settled = true;
|
|
3249
3302
|
signal.removeEventListener("abort", onAbort);
|
|
3250
|
-
|
|
3303
|
+
resolve(value);
|
|
3251
3304
|
}, (err) => {
|
|
3252
3305
|
if (settled)
|
|
3253
3306
|
return;
|
|
@@ -3259,20 +3312,18 @@ function awaitWithSignal(promise, signal) {
|
|
|
3259
3312
|
}
|
|
3260
3313
|
|
|
3261
3314
|
class LspManager {
|
|
3262
|
-
clients = new Map;
|
|
3263
|
-
reaperHandle = null;
|
|
3264
|
-
signalDisposer = null;
|
|
3265
|
-
disposed = false;
|
|
3266
|
-
idleTimeoutMs;
|
|
3267
|
-
initTimeoutMs;
|
|
3268
|
-
reaperIntervalMs;
|
|
3269
|
-
clientFactory;
|
|
3270
|
-
now;
|
|
3271
3315
|
constructor(options = {}) {
|
|
3316
|
+
this.clients = new Map;
|
|
3317
|
+
this.pendingStops = new Map;
|
|
3318
|
+
this.respawnBudgets = new Map;
|
|
3319
|
+
this.reaperHandle = null;
|
|
3320
|
+
this.signalDisposer = null;
|
|
3321
|
+
this.disposed = false;
|
|
3272
3322
|
this.idleTimeoutMs = options.idleTimeoutMs ?? IDLE_TIMEOUT_MS;
|
|
3273
3323
|
this.initTimeoutMs = options.initTimeoutMs ?? INIT_TIMEOUT_MS;
|
|
3324
|
+
this.maxResidentClients = options.maxResidentClients ?? MAX_RESIDENT_CLIENTS;
|
|
3274
3325
|
this.reaperIntervalMs = options.reaperIntervalMs ?? REAPER_INTERVAL_MS;
|
|
3275
|
-
this.clientFactory = options.clientFactory ?? ((root,
|
|
3326
|
+
this.clientFactory = options.clientFactory ?? ((root, server) => new LspClient(root, server));
|
|
3276
3327
|
this.now = options.now ?? (() => Date.now());
|
|
3277
3328
|
this.startReaper();
|
|
3278
3329
|
this.signalDisposer = installProcessSignalCleanup(() => this.stopAll());
|
|
@@ -3290,38 +3341,103 @@ class LspManager {
|
|
|
3290
3341
|
getKey(root, serverId) {
|
|
3291
3342
|
return `${root}::${serverId}`;
|
|
3292
3343
|
}
|
|
3344
|
+
tombstoneStop(key, client) {
|
|
3345
|
+
const stop = stopClientBestEffort(client);
|
|
3346
|
+
this.pendingStops.set(key, stop);
|
|
3347
|
+
stop.finally(() => {
|
|
3348
|
+
if (this.pendingStops.get(key) === stop) {
|
|
3349
|
+
this.pendingStops.delete(key);
|
|
3350
|
+
}
|
|
3351
|
+
});
|
|
3352
|
+
return stop;
|
|
3353
|
+
}
|
|
3354
|
+
recordDeadGeneration(key) {
|
|
3355
|
+
let budget = this.respawnBudgets.get(key);
|
|
3356
|
+
if (budget === undefined) {
|
|
3357
|
+
budget = { deadGenerations: 0, exhaustedAt: null };
|
|
3358
|
+
this.respawnBudgets.set(key, budget);
|
|
3359
|
+
}
|
|
3360
|
+
budget.deadGenerations += 1;
|
|
3361
|
+
}
|
|
3362
|
+
markHealthyGeneration(key) {
|
|
3363
|
+
this.respawnBudgets.delete(key);
|
|
3364
|
+
}
|
|
3365
|
+
ensureRespawnAllowed(key, root, serverId) {
|
|
3366
|
+
const budget = this.respawnBudgets.get(key);
|
|
3367
|
+
if (budget === undefined || budget.deadGenerations < CLIENT_RESPAWN_RETRY_LIMIT)
|
|
3368
|
+
return;
|
|
3369
|
+
if (budget.exhaustedAt === null) {
|
|
3370
|
+
budget.exhaustedAt = this.now();
|
|
3371
|
+
throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
|
|
3372
|
+
}
|
|
3373
|
+
if (this.now() - budget.exhaustedAt < CLIENT_RESPAWN_COOLDOWN_MS) {
|
|
3374
|
+
throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
|
|
3375
|
+
}
|
|
3376
|
+
budget.deadGenerations = 0;
|
|
3377
|
+
budget.exhaustedAt = null;
|
|
3378
|
+
}
|
|
3293
3379
|
reapStale() {
|
|
3294
3380
|
const t = this.now();
|
|
3295
3381
|
for (const [key, managed] of this.clients) {
|
|
3296
3382
|
if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
|
|
3297
|
-
stopClientBestEffort(managed.client);
|
|
3298
3383
|
this.clients.delete(key);
|
|
3384
|
+
this.tombstoneStop(key, managed.client);
|
|
3299
3385
|
continue;
|
|
3300
3386
|
}
|
|
3301
3387
|
if (!managed.isInitializing && managed.refCount === 0 && managed.pendingWaiters === 0 && t - managed.lastUsedAt > this.idleTimeoutMs) {
|
|
3302
|
-
stopClientBestEffort(managed.client);
|
|
3303
3388
|
this.clients.delete(key);
|
|
3389
|
+
this.tombstoneStop(key, managed.client);
|
|
3304
3390
|
}
|
|
3305
3391
|
}
|
|
3306
3392
|
}
|
|
3393
|
+
evictForAdmission() {
|
|
3394
|
+
while (this.clients.size >= this.maxResidentClients) {
|
|
3395
|
+
const victim = this.leastRecentlyUsedIdleClient();
|
|
3396
|
+
if (!victim)
|
|
3397
|
+
return;
|
|
3398
|
+
this.clients.delete(victim.key);
|
|
3399
|
+
this.tombstoneStop(victim.key, victim.managed.client);
|
|
3400
|
+
}
|
|
3401
|
+
}
|
|
3402
|
+
leastRecentlyUsedIdleClient() {
|
|
3403
|
+
let candidate = null;
|
|
3404
|
+
for (const [key, managed] of this.clients) {
|
|
3405
|
+
if (managed.refCount > 0 || managed.pendingWaiters > 0 || managed.isInitializing)
|
|
3406
|
+
continue;
|
|
3407
|
+
if (candidate === null || managed.lastUsedAt < candidate.managed.lastUsedAt) {
|
|
3408
|
+
candidate = { key, managed };
|
|
3409
|
+
}
|
|
3410
|
+
}
|
|
3411
|
+
return candidate;
|
|
3412
|
+
}
|
|
3307
3413
|
async tryDeleteIfOrphaned(key, managed) {
|
|
3308
3414
|
if (managed.refCount === 0 && managed.pendingWaiters === 0 && !managed.isInitializing && this.clients.get(key) === managed) {
|
|
3309
3415
|
this.clients.delete(key);
|
|
3310
|
-
await
|
|
3416
|
+
await this.tombstoneStop(key, managed.client);
|
|
3311
3417
|
}
|
|
3312
3418
|
}
|
|
3313
|
-
async getClient(root,
|
|
3419
|
+
async getClient(root, server, signal) {
|
|
3314
3420
|
if (this.disposed) {
|
|
3315
3421
|
throw new Error("LspManager has been disposed");
|
|
3316
3422
|
}
|
|
3317
3423
|
signal?.throwIfAborted();
|
|
3318
|
-
const key = this.getKey(root,
|
|
3424
|
+
const key = this.getKey(root, server.id);
|
|
3425
|
+
for (;; ) {
|
|
3426
|
+
const pendingStop = this.pendingStops.get(key);
|
|
3427
|
+
if (pendingStop === undefined)
|
|
3428
|
+
break;
|
|
3429
|
+
await awaitWithSignal(pendingStop, signal);
|
|
3430
|
+
signal?.throwIfAborted();
|
|
3431
|
+
}
|
|
3432
|
+
if (this.disposed) {
|
|
3433
|
+
throw new Error("LspManager has been disposed");
|
|
3434
|
+
}
|
|
3319
3435
|
let managed = this.clients.get(key);
|
|
3320
3436
|
if (managed) {
|
|
3321
3437
|
const t = this.now();
|
|
3322
3438
|
if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
|
|
3323
|
-
await stopClientBestEffort(managed.client);
|
|
3324
3439
|
this.clients.delete(key);
|
|
3440
|
+
await this.tombstoneStop(key, managed.client);
|
|
3325
3441
|
managed = undefined;
|
|
3326
3442
|
}
|
|
3327
3443
|
}
|
|
@@ -3342,15 +3458,21 @@ class LspManager {
|
|
|
3342
3458
|
signal.throwIfAborted();
|
|
3343
3459
|
}
|
|
3344
3460
|
if (!managed.client.isAlive()) {
|
|
3345
|
-
|
|
3346
|
-
this.clients.
|
|
3347
|
-
|
|
3461
|
+
this.recordDeadGeneration(key);
|
|
3462
|
+
if (this.clients.get(key) === managed) {
|
|
3463
|
+
this.clients.delete(key);
|
|
3464
|
+
}
|
|
3465
|
+
await this.tombstoneStop(key, managed.client);
|
|
3466
|
+
return this.getClient(root, server, signal);
|
|
3348
3467
|
}
|
|
3468
|
+
this.markHealthyGeneration(key);
|
|
3349
3469
|
managed.refCount++;
|
|
3350
3470
|
managed.lastUsedAt = this.now();
|
|
3351
3471
|
return managed.client;
|
|
3352
3472
|
}
|
|
3353
|
-
|
|
3473
|
+
this.evictForAdmission();
|
|
3474
|
+
this.ensureRespawnAllowed(key, root, server.id);
|
|
3475
|
+
const client = this.clientFactory(root, server);
|
|
3354
3476
|
const initStartedAt = this.now();
|
|
3355
3477
|
const initPromise = (async () => {
|
|
3356
3478
|
await client.start();
|
|
@@ -3373,7 +3495,7 @@ class LspManager {
|
|
|
3373
3495
|
if (this.clients.get(key) === newManaged) {
|
|
3374
3496
|
this.clients.delete(key);
|
|
3375
3497
|
}
|
|
3376
|
-
await
|
|
3498
|
+
await this.tombstoneStop(key, client);
|
|
3377
3499
|
throw err;
|
|
3378
3500
|
}
|
|
3379
3501
|
newManaged.pendingWaiters--;
|
|
@@ -3384,6 +3506,15 @@ class LspManager {
|
|
|
3384
3506
|
await this.tryDeleteIfOrphaned(key, newManaged);
|
|
3385
3507
|
signal.throwIfAborted();
|
|
3386
3508
|
}
|
|
3509
|
+
if (!client.isAlive()) {
|
|
3510
|
+
this.recordDeadGeneration(key);
|
|
3511
|
+
if (this.clients.get(key) === newManaged) {
|
|
3512
|
+
this.clients.delete(key);
|
|
3513
|
+
}
|
|
3514
|
+
await this.tombstoneStop(key, client);
|
|
3515
|
+
return this.getClient(root, server, signal);
|
|
3516
|
+
}
|
|
3517
|
+
this.markHealthyGeneration(key);
|
|
3387
3518
|
newManaged.refCount++;
|
|
3388
3519
|
newManaged.lastUsedAt = this.now();
|
|
3389
3520
|
return client;
|
|
@@ -3404,15 +3535,21 @@ class LspManager {
|
|
|
3404
3535
|
if (client && managed.client !== client)
|
|
3405
3536
|
return;
|
|
3406
3537
|
this.clients.delete(key);
|
|
3407
|
-
|
|
3538
|
+
this.tombstoneStop(key, managed.client);
|
|
3408
3539
|
}
|
|
3409
|
-
warmupClient(root,
|
|
3540
|
+
warmupClient(root, server) {
|
|
3410
3541
|
if (this.disposed)
|
|
3411
3542
|
return;
|
|
3412
|
-
const key = this.getKey(root,
|
|
3413
|
-
if (this.clients.has(key))
|
|
3543
|
+
const key = this.getKey(root, server.id);
|
|
3544
|
+
if (this.clients.has(key) || this.pendingStops.has(key))
|
|
3545
|
+
return;
|
|
3546
|
+
this.evictForAdmission();
|
|
3547
|
+
try {
|
|
3548
|
+
this.ensureRespawnAllowed(key, root, server.id);
|
|
3549
|
+
} catch {
|
|
3414
3550
|
return;
|
|
3415
|
-
|
|
3551
|
+
}
|
|
3552
|
+
const client = this.clientFactory(root, server);
|
|
3416
3553
|
const initStartedAt = this.now();
|
|
3417
3554
|
const initPromise = (async () => {
|
|
3418
3555
|
await client.start();
|
|
@@ -3437,7 +3574,7 @@ class LspManager {
|
|
|
3437
3574
|
if (this.clients.get(key) === managed) {
|
|
3438
3575
|
this.clients.delete(key);
|
|
3439
3576
|
}
|
|
3440
|
-
|
|
3577
|
+
this.tombstoneStop(key, client);
|
|
3441
3578
|
});
|
|
3442
3579
|
}
|
|
3443
3580
|
isServerInitializing(root, serverId) {
|
|
@@ -3481,8 +3618,11 @@ class LspManager {
|
|
|
3481
3618
|
for (const managed of this.clients.values()) {
|
|
3482
3619
|
stopPromises.push(stopClientBestEffort(managed.client));
|
|
3483
3620
|
}
|
|
3621
|
+
const tombstonedStops = [...this.pendingStops.values()];
|
|
3484
3622
|
this.clients.clear();
|
|
3485
|
-
|
|
3623
|
+
this.respawnBudgets.clear();
|
|
3624
|
+
await Promise.allSettled([...stopPromises, ...tombstonedStops]);
|
|
3625
|
+
this.pendingStops.clear();
|
|
3486
3626
|
}
|
|
3487
3627
|
}
|
|
3488
3628
|
var _defaultInstance = null;
|
|
@@ -3500,57 +3640,52 @@ async function disposeDefaultLspManager() {
|
|
|
3500
3640
|
}
|
|
3501
3641
|
}
|
|
3502
3642
|
|
|
3503
|
-
// ../lsp-core/src/lsp/
|
|
3504
|
-
import { existsSync as existsSync6,
|
|
3505
|
-
import { dirname as dirname5 } from "node:path";
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
|
|
3512
|
-
|
|
3513
|
-
|
|
3514
|
-
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
|
|
3643
|
+
// ../lsp-core/src/lsp/outside-context-workspace.ts
|
|
3644
|
+
import { existsSync as existsSync6, realpathSync as realpathSync4 } from "node:fs";
|
|
3645
|
+
import { dirname as dirname5, join as join3 } from "node:path";
|
|
3646
|
+
|
|
3647
|
+
// ../lsp-core/src/lsp/workspace-markers.ts
|
|
3648
|
+
var GIT_WORKSPACE_MARKER = ".git";
|
|
3649
|
+
var PROJECT_WORKSPACE_MARKERS = [
|
|
3650
|
+
"package.json",
|
|
3651
|
+
"pyproject.toml",
|
|
3652
|
+
"Cargo.toml",
|
|
3653
|
+
"go.mod",
|
|
3654
|
+
"pom.xml",
|
|
3655
|
+
"build.gradle"
|
|
3656
|
+
];
|
|
3657
|
+
var WORKSPACE_MARKERS = [GIT_WORKSPACE_MARKER, ...PROJECT_WORKSPACE_MARKERS];
|
|
3658
|
+
|
|
3659
|
+
// ../lsp-core/src/lsp/outside-context-workspace.ts
|
|
3660
|
+
function findWorkspaceRootOutsideContext(directory) {
|
|
3661
|
+
const marked = nearestMarkedAncestor(directory);
|
|
3662
|
+
if (marked !== undefined)
|
|
3663
|
+
return marked;
|
|
3664
|
+
return realpathSync4(nearestExistingAncestor(directory));
|
|
3665
|
+
}
|
|
3666
|
+
function nearestMarkedAncestor(directory) {
|
|
3667
|
+
let current = directory;
|
|
3668
|
+
for (;; ) {
|
|
3669
|
+
if (existsSync6(current) && WORKSPACE_MARKERS.some((marker) => existsSync6(join3(current, marker)))) {
|
|
3670
|
+
return realpathSync4(current);
|
|
3671
|
+
}
|
|
3672
|
+
const parent = dirname5(current);
|
|
3673
|
+
if (parent === current)
|
|
3674
|
+
return;
|
|
3675
|
+
current = parent;
|
|
3518
3676
|
}
|
|
3519
3677
|
}
|
|
3520
|
-
function
|
|
3521
|
-
|
|
3522
|
-
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
|
|
3526
|
-
|
|
3527
|
-
}
|
|
3528
|
-
|
|
3529
|
-
return value === "declined" || value === "allowed";
|
|
3530
|
-
}
|
|
3531
|
-
function writeInstallDecisions(decisions) {
|
|
3532
|
-
const path = getInstallDecisionsPath();
|
|
3533
|
-
mkdirSync(dirname5(path), { recursive: true });
|
|
3534
|
-
const tmpPath = `${path}.tmp`;
|
|
3535
|
-
writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
|
|
3536
|
-
`, "utf8");
|
|
3537
|
-
renameSync2(tmpPath, path);
|
|
3538
|
-
}
|
|
3539
|
-
function isInstallDecisions(value) {
|
|
3540
|
-
return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
|
|
3541
|
-
}
|
|
3542
|
-
function isInstallDecisionRecord(value) {
|
|
3543
|
-
if (!isRecord5(value))
|
|
3544
|
-
return false;
|
|
3545
|
-
return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
|
|
3546
|
-
}
|
|
3547
|
-
function isRecord5(value) {
|
|
3548
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3678
|
+
function nearestExistingAncestor(directory) {
|
|
3679
|
+
let current = directory;
|
|
3680
|
+
while (!existsSync6(current)) {
|
|
3681
|
+
const parent = dirname5(current);
|
|
3682
|
+
if (parent === current)
|
|
3683
|
+
return current;
|
|
3684
|
+
current = parent;
|
|
3685
|
+
}
|
|
3686
|
+
return current;
|
|
3549
3687
|
}
|
|
3550
3688
|
|
|
3551
|
-
// ../lsp-core/src/lsp/config-loader.ts
|
|
3552
|
-
import { existsSync as existsSync7, readFileSync as readFileSync4 } from "node:fs";
|
|
3553
|
-
|
|
3554
3689
|
// ../lsp-core/src/lsp/server-definitions.ts
|
|
3555
3690
|
var LSP_INSTALL_HINTS = {
|
|
3556
3691
|
typescript: "npm install -g typescript-language-server typescript",
|
|
@@ -3596,6 +3731,26 @@ var LSP_INSTALL_HINTS = {
|
|
|
3596
3731
|
julials: `julia -e 'using Pkg; Pkg.add("LanguageServer")'`,
|
|
3597
3732
|
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"
|
|
3598
3733
|
};
|
|
3734
|
+
var LSP_LOCAL_INSTALL_HINTS = {
|
|
3735
|
+
typescript: "bun add -d typescript-language-server typescript",
|
|
3736
|
+
vue: "bun add -d @vue/language-server",
|
|
3737
|
+
eslint: "bun add -d vscode-langservers-extracted",
|
|
3738
|
+
oxlint: "bun add -d oxlint",
|
|
3739
|
+
biome: "bun add -d @biomejs/biome",
|
|
3740
|
+
svelte: "bun add -d svelte-language-server",
|
|
3741
|
+
astro: "bun add -d @astrojs/language-server",
|
|
3742
|
+
bash: "bun add -d bash-language-server",
|
|
3743
|
+
"bash-ls": "bun add -d bash-language-server",
|
|
3744
|
+
"yaml-ls": "bun add -d yaml-language-server",
|
|
3745
|
+
php: "bun add -d intelephense",
|
|
3746
|
+
prisma: "bun add -d prisma",
|
|
3747
|
+
dockerfile: "bun add -d dockerfile-language-server-nodejs",
|
|
3748
|
+
pyright: "uv add --dev pyright",
|
|
3749
|
+
basedpyright: "uv add --dev basedpyright",
|
|
3750
|
+
ruff: "uv add --dev ruff",
|
|
3751
|
+
ty: "uv add --dev ty",
|
|
3752
|
+
"ruby-lsp": "bundle add ruby-lsp --group development"
|
|
3753
|
+
};
|
|
3599
3754
|
var BUILTIN_SERVERS = {
|
|
3600
3755
|
typescript: {
|
|
3601
3756
|
command: ["typescript-language-server", "--stdio"],
|
|
@@ -3698,7 +3853,56 @@ var BUILTIN_SERVERS = {
|
|
|
3698
3853
|
}
|
|
3699
3854
|
};
|
|
3700
3855
|
|
|
3856
|
+
// ../lsp-core/src/lsp/server-install-state.ts
|
|
3857
|
+
import { existsSync as existsSync7, mkdirSync, readFileSync as readFileSync3, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
3858
|
+
import { dirname as dirname6 } from "node:path";
|
|
3859
|
+
function getInstallDecisionsPath() {
|
|
3860
|
+
return lspRequestContext().installDecisionsPath;
|
|
3861
|
+
}
|
|
3862
|
+
function loadInstallDecisions() {
|
|
3863
|
+
const path = getInstallDecisionsPath();
|
|
3864
|
+
if (!existsSync7(path))
|
|
3865
|
+
return {};
|
|
3866
|
+
try {
|
|
3867
|
+
const parsed = JSON.parse(readFileSync3(path, "utf8"));
|
|
3868
|
+
return isInstallDecisions(parsed) ? parsed : {};
|
|
3869
|
+
} catch {
|
|
3870
|
+
return {};
|
|
3871
|
+
}
|
|
3872
|
+
}
|
|
3873
|
+
function loadInstallDecision(serverId) {
|
|
3874
|
+
return loadInstallDecisions()[serverId];
|
|
3875
|
+
}
|
|
3876
|
+
function recordInstallDecision(serverId, decision, decidedAt = new Date().toISOString()) {
|
|
3877
|
+
const decisions = loadInstallDecisions();
|
|
3878
|
+
decisions[serverId] = { decision, decidedAt };
|
|
3879
|
+
writeInstallDecisions(decisions);
|
|
3880
|
+
}
|
|
3881
|
+
function isInstallDecision(value) {
|
|
3882
|
+
return value === "declined" || value === "allowed";
|
|
3883
|
+
}
|
|
3884
|
+
function writeInstallDecisions(decisions) {
|
|
3885
|
+
const path = getInstallDecisionsPath();
|
|
3886
|
+
mkdirSync(dirname6(path), { recursive: true });
|
|
3887
|
+
const tmpPath = `${path}.tmp`;
|
|
3888
|
+
writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
|
|
3889
|
+
`, "utf8");
|
|
3890
|
+
renameSync2(tmpPath, path);
|
|
3891
|
+
}
|
|
3892
|
+
function isInstallDecisions(value) {
|
|
3893
|
+
return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
|
|
3894
|
+
}
|
|
3895
|
+
function isInstallDecisionRecord(value) {
|
|
3896
|
+
if (!isRecord5(value))
|
|
3897
|
+
return false;
|
|
3898
|
+
return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
|
|
3899
|
+
}
|
|
3900
|
+
function isRecord5(value) {
|
|
3901
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3902
|
+
}
|
|
3903
|
+
|
|
3701
3904
|
// ../lsp-core/src/lsp/config-loader.ts
|
|
3905
|
+
import { existsSync as existsSync8, readFileSync as readFileSync4 } from "node:fs";
|
|
3702
3906
|
function getProjectConfigPaths() {
|
|
3703
3907
|
return lspRequestContext().projectConfigPaths;
|
|
3704
3908
|
}
|
|
@@ -3706,7 +3910,7 @@ function getUserConfigPath() {
|
|
|
3706
3910
|
return lspRequestContext().userConfigPath;
|
|
3707
3911
|
}
|
|
3708
3912
|
function loadJsonFile(path) {
|
|
3709
|
-
if (!
|
|
3913
|
+
if (!existsSync8(path))
|
|
3710
3914
|
return null;
|
|
3711
3915
|
try {
|
|
3712
3916
|
const parsed = JSON.parse(readFileSync4(path, "utf-8"));
|
|
@@ -3753,10 +3957,10 @@ function getMergedServers() {
|
|
|
3753
3957
|
}
|
|
3754
3958
|
if (seen.has(id))
|
|
3755
3959
|
continue;
|
|
3756
|
-
const
|
|
3757
|
-
if (!
|
|
3960
|
+
const server = createServerFromEntry(id, entry, source);
|
|
3961
|
+
if (!server)
|
|
3758
3962
|
continue;
|
|
3759
|
-
servers.push(
|
|
3963
|
+
servers.push(server);
|
|
3760
3964
|
seen.add(id);
|
|
3761
3965
|
}
|
|
3762
3966
|
}
|
|
@@ -3788,7 +3992,7 @@ function createServerFromEntry(id, entry, source) {
|
|
|
3788
3992
|
if (source === "project") {
|
|
3789
3993
|
if (!builtin)
|
|
3790
3994
|
return null;
|
|
3791
|
-
const
|
|
3995
|
+
const server = createServer({
|
|
3792
3996
|
id,
|
|
3793
3997
|
command: builtin.command,
|
|
3794
3998
|
extensions: entry.extensions ?? builtin.extensions,
|
|
@@ -3796,35 +4000,35 @@ function createServerFromEntry(id, entry, source) {
|
|
|
3796
4000
|
source
|
|
3797
4001
|
});
|
|
3798
4002
|
if (entry.initialization !== undefined) {
|
|
3799
|
-
|
|
4003
|
+
server.initialization = entry.initialization;
|
|
3800
4004
|
}
|
|
3801
|
-
return
|
|
4005
|
+
return server;
|
|
3802
4006
|
}
|
|
3803
4007
|
if (entry.command && entry.extensions) {
|
|
3804
|
-
const
|
|
4008
|
+
const server = createServer({
|
|
3805
4009
|
id,
|
|
3806
4010
|
command: entry.command,
|
|
3807
4011
|
extensions: entry.extensions,
|
|
3808
4012
|
priority: entry.priority ?? 0,
|
|
3809
4013
|
source
|
|
3810
4014
|
});
|
|
3811
|
-
applyOptionalServerFields(
|
|
3812
|
-
return
|
|
4015
|
+
applyOptionalServerFields(server, entry);
|
|
4016
|
+
return server;
|
|
3813
4017
|
}
|
|
3814
4018
|
if (!builtin)
|
|
3815
4019
|
return null;
|
|
3816
|
-
const
|
|
4020
|
+
const server = createServer({
|
|
3817
4021
|
id,
|
|
3818
4022
|
command: entry.command ?? builtin.command,
|
|
3819
4023
|
extensions: entry.extensions ?? builtin.extensions,
|
|
3820
4024
|
priority: entry.priority ?? 0,
|
|
3821
4025
|
source
|
|
3822
4026
|
});
|
|
3823
|
-
applyOptionalServerFields(
|
|
3824
|
-
return
|
|
4027
|
+
applyOptionalServerFields(server, entry);
|
|
4028
|
+
return server;
|
|
3825
4029
|
}
|
|
3826
4030
|
function createServer(input) {
|
|
3827
|
-
const
|
|
4031
|
+
const server = {
|
|
3828
4032
|
id: input.id,
|
|
3829
4033
|
command: input.command,
|
|
3830
4034
|
extensions: input.extensions,
|
|
@@ -3832,19 +4036,19 @@ function createServer(input) {
|
|
|
3832
4036
|
source: input.source
|
|
3833
4037
|
};
|
|
3834
4038
|
if (input.env !== undefined) {
|
|
3835
|
-
|
|
4039
|
+
server.env = input.env;
|
|
3836
4040
|
}
|
|
3837
4041
|
if (input.initialization !== undefined) {
|
|
3838
|
-
|
|
4042
|
+
server.initialization = input.initialization;
|
|
3839
4043
|
}
|
|
3840
|
-
return
|
|
4044
|
+
return server;
|
|
3841
4045
|
}
|
|
3842
|
-
function applyOptionalServerFields(
|
|
4046
|
+
function applyOptionalServerFields(server, entry) {
|
|
3843
4047
|
if (entry.env !== undefined) {
|
|
3844
|
-
|
|
4048
|
+
server.env = entry.env;
|
|
3845
4049
|
}
|
|
3846
4050
|
if (entry.initialization !== undefined) {
|
|
3847
|
-
|
|
4051
|
+
server.initialization = entry.initialization;
|
|
3848
4052
|
}
|
|
3849
4053
|
}
|
|
3850
4054
|
function isConfigJson(value) {
|
|
@@ -3894,64 +4098,165 @@ function getDisabledServerIds() {
|
|
|
3894
4098
|
}
|
|
3895
4099
|
|
|
3896
4100
|
// ../lsp-core/src/lsp/server-installation.ts
|
|
3897
|
-
import { existsSync as
|
|
3898
|
-
import { delimiter as delimiter3, join as
|
|
3899
|
-
|
|
3900
|
-
|
|
3901
|
-
|
|
3902
|
-
|
|
3903
|
-
|
|
3904
|
-
|
|
3905
|
-
|
|
3906
|
-
|
|
3907
|
-
|
|
4101
|
+
import { existsSync as existsSync9 } from "node:fs";
|
|
4102
|
+
import { delimiter as delimiter3, dirname as dirname7, isAbsolute as isAbsolute3, join as join4, resolve as resolve7 } from "node:path";
|
|
4103
|
+
var LOCAL_BIN_RULES = [
|
|
4104
|
+
{
|
|
4105
|
+
markers: ["package.json", "bun.lock", "bun.lockb", "package-lock.json", "yarn.lock", "pnpm-lock.yaml"],
|
|
4106
|
+
binDirs: [join4("node_modules", ".bin")]
|
|
4107
|
+
},
|
|
4108
|
+
{
|
|
4109
|
+
markers: [
|
|
4110
|
+
"pyproject.toml",
|
|
4111
|
+
"ty.toml",
|
|
4112
|
+
"requirements.txt",
|
|
4113
|
+
"setup.py",
|
|
4114
|
+
"setup.cfg",
|
|
4115
|
+
"Pipfile",
|
|
4116
|
+
"pyrightconfig.json",
|
|
4117
|
+
"ruff.toml",
|
|
4118
|
+
".ruff.toml"
|
|
4119
|
+
],
|
|
4120
|
+
binDirs: [
|
|
4121
|
+
join4(".venv", "bin"),
|
|
4122
|
+
join4(".venv", "Scripts"),
|
|
4123
|
+
join4("venv", "bin"),
|
|
4124
|
+
join4("venv", "Scripts"),
|
|
4125
|
+
join4(".env", "bin"),
|
|
4126
|
+
join4(".env", "Scripts")
|
|
4127
|
+
]
|
|
4128
|
+
},
|
|
4129
|
+
{
|
|
4130
|
+
markers: ["Gemfile", "Gemfile.lock"],
|
|
4131
|
+
binDirs: [join4("vendor", "bundle", "bin"), "bin"]
|
|
4132
|
+
},
|
|
4133
|
+
{
|
|
4134
|
+
markers: ["go.mod", "go.sum", "go.work"],
|
|
4135
|
+
binDirs: ["bin"]
|
|
3908
4136
|
}
|
|
3909
|
-
|
|
3910
|
-
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
|
|
3915
|
-
|
|
3916
|
-
|
|
3917
|
-
|
|
4137
|
+
];
|
|
4138
|
+
var resolutionCache = new Map;
|
|
4139
|
+
var probeCount = 0;
|
|
4140
|
+
function probe(path) {
|
|
4141
|
+
probeCount += 1;
|
|
4142
|
+
return existsSync9(path);
|
|
4143
|
+
}
|
|
4144
|
+
function executableSuffixes(platform, pathExt) {
|
|
4145
|
+
if (platform !== "win32")
|
|
4146
|
+
return [""];
|
|
4147
|
+
const configured = pathExt ?? process.env["PATHEXT"] ?? "";
|
|
4148
|
+
const systemExts = configured.split(";").filter((entry) => entry.length > 0).map((entry) => entry.toLowerCase());
|
|
4149
|
+
return [...new Set(["", ...systemExts, ".exe", ".cmd", ".bat", ".ps1"])];
|
|
4150
|
+
}
|
|
4151
|
+
function probeWithSuffixes(directory, command, suffixes) {
|
|
4152
|
+
for (const suffix of suffixes) {
|
|
4153
|
+
const candidate = join4(directory, command + suffix);
|
|
4154
|
+
if (probe(candidate))
|
|
4155
|
+
return candidate;
|
|
4156
|
+
}
|
|
4157
|
+
return null;
|
|
4158
|
+
}
|
|
4159
|
+
function resolveLocal(command, workingDirectory, suffixes, stopAt) {
|
|
4160
|
+
const boundary = stopAt === undefined ? undefined : resolve7(stopAt);
|
|
4161
|
+
let current = resolve7(workingDirectory);
|
|
4162
|
+
while (true) {
|
|
4163
|
+
for (const rule of LOCAL_BIN_RULES) {
|
|
4164
|
+
if (!rule.markers.some((marker) => probe(join4(current, marker))))
|
|
4165
|
+
continue;
|
|
4166
|
+
for (const binDir of rule.binDirs) {
|
|
4167
|
+
const found = probeWithSuffixes(join4(current, binDir), command, suffixes);
|
|
4168
|
+
if (found !== null)
|
|
4169
|
+
return found;
|
|
4170
|
+
}
|
|
3918
4171
|
}
|
|
4172
|
+
if (probe(join4(current, ".git")))
|
|
4173
|
+
return null;
|
|
4174
|
+
if (boundary !== undefined && current === boundary)
|
|
4175
|
+
return null;
|
|
4176
|
+
const parent = dirname7(current);
|
|
4177
|
+
if (parent === current)
|
|
4178
|
+
return null;
|
|
4179
|
+
current = parent;
|
|
3919
4180
|
}
|
|
3920
|
-
|
|
3921
|
-
|
|
4181
|
+
}
|
|
4182
|
+
function resolveFromPath(command, suffixes, platform, pathEnvOverride) {
|
|
4183
|
+
let pathEnv = pathEnvOverride ?? process.env["PATH"] ?? "";
|
|
4184
|
+
if (platform === "win32" && !pathEnv) {
|
|
3922
4185
|
pathEnv = process.env["Path"] ?? "";
|
|
3923
4186
|
}
|
|
3924
|
-
const
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
}
|
|
4187
|
+
for (const entry of pathEnv.split(delimiter3)) {
|
|
4188
|
+
if (entry.length === 0)
|
|
4189
|
+
continue;
|
|
4190
|
+
const found = probeWithSuffixes(entry, command, suffixes);
|
|
4191
|
+
if (found !== null)
|
|
4192
|
+
return found;
|
|
3931
4193
|
}
|
|
3932
|
-
|
|
3933
|
-
|
|
3934
|
-
|
|
4194
|
+
return null;
|
|
4195
|
+
}
|
|
4196
|
+
function resolveServerBinary(command, workingDirectory, options = {}) {
|
|
4197
|
+
if (command.length === 0)
|
|
4198
|
+
return null;
|
|
4199
|
+
const [cmd] = command;
|
|
4200
|
+
if (cmd === undefined || cmd.length === 0)
|
|
4201
|
+
return null;
|
|
4202
|
+
const platform = options.platform ?? process.platform;
|
|
4203
|
+
const suffixes = executableSuffixes(platform, options.pathExt);
|
|
4204
|
+
if (cmd.includes("/") || cmd.includes("\\")) {
|
|
4205
|
+
const explicit = isAbsolute3(cmd) ? cmd : resolve7(workingDirectory ?? process.cwd(), cmd);
|
|
4206
|
+
return probe(explicit) ? explicit : null;
|
|
4207
|
+
}
|
|
4208
|
+
const cacheKey = JSON.stringify([
|
|
4209
|
+
workingDirectory ?? "",
|
|
4210
|
+
cmd,
|
|
4211
|
+
platform,
|
|
4212
|
+
options.stopAt ?? "",
|
|
4213
|
+
options.pathExt ?? "",
|
|
4214
|
+
options.pathEnv ?? process.env["PATH"] ?? ""
|
|
4215
|
+
]);
|
|
4216
|
+
const cached = resolutionCache.get(cacheKey);
|
|
4217
|
+
if (cached !== undefined)
|
|
4218
|
+
return cached;
|
|
4219
|
+
let resolved = null;
|
|
4220
|
+
if (workingDirectory !== undefined && workingDirectory.length > 0) {
|
|
4221
|
+
resolved = resolveLocal(cmd, workingDirectory, suffixes, options.stopAt);
|
|
4222
|
+
}
|
|
4223
|
+
resolved ??= resolveFromPath(cmd, suffixes, platform, options.pathEnv);
|
|
4224
|
+
if (resolved === null && cmd === "node")
|
|
4225
|
+
resolved = cmd;
|
|
4226
|
+
resolutionCache.set(cacheKey, resolved);
|
|
4227
|
+
return resolved;
|
|
4228
|
+
}
|
|
4229
|
+
function isServerInstalled(command, workingDirectory, options = {}) {
|
|
4230
|
+
if (command.length === 0)
|
|
4231
|
+
return false;
|
|
4232
|
+
return resolveServerBinary(command, workingDirectory, options) !== null;
|
|
3935
4233
|
}
|
|
3936
4234
|
|
|
3937
4235
|
// ../lsp-core/src/lsp/server-resolution.ts
|
|
4236
|
+
function withResolvedCommand(command, binaryPath) {
|
|
4237
|
+
return [binaryPath, ...command.slice(1)];
|
|
4238
|
+
}
|
|
3938
4239
|
function findServerForExtension(ext) {
|
|
3939
4240
|
const servers = getMergedServers();
|
|
3940
|
-
|
|
3941
|
-
|
|
4241
|
+
const workingDirectory = contextCwd();
|
|
4242
|
+
for (const server of servers) {
|
|
4243
|
+
if (!server.extensions.includes(ext))
|
|
4244
|
+
continue;
|
|
4245
|
+
const binaryPath = resolveServerBinary(server.command, workingDirectory);
|
|
4246
|
+
if (binaryPath !== null) {
|
|
3942
4247
|
const resolvedServer = {
|
|
3943
|
-
id:
|
|
3944
|
-
command:
|
|
3945
|
-
extensions:
|
|
3946
|
-
priority:
|
|
4248
|
+
id: server.id,
|
|
4249
|
+
command: withResolvedCommand(server.command, binaryPath),
|
|
4250
|
+
extensions: server.extensions,
|
|
4251
|
+
priority: server.priority
|
|
3947
4252
|
};
|
|
3948
|
-
if (
|
|
4253
|
+
if (server.env !== undefined) {
|
|
3949
4254
|
return {
|
|
3950
4255
|
status: "found",
|
|
3951
4256
|
server: {
|
|
3952
4257
|
...resolvedServer,
|
|
3953
|
-
env:
|
|
3954
|
-
...
|
|
4258
|
+
env: server.env,
|
|
4259
|
+
...server.initialization === undefined ? {} : { initialization: server.initialization }
|
|
3955
4260
|
}
|
|
3956
4261
|
};
|
|
3957
4262
|
}
|
|
@@ -3959,20 +4264,20 @@ function findServerForExtension(ext) {
|
|
|
3959
4264
|
status: "found",
|
|
3960
4265
|
server: {
|
|
3961
4266
|
...resolvedServer,
|
|
3962
|
-
...
|
|
4267
|
+
...server.initialization === undefined ? {} : { initialization: server.initialization }
|
|
3963
4268
|
}
|
|
3964
4269
|
};
|
|
3965
4270
|
}
|
|
3966
4271
|
}
|
|
3967
|
-
for (const
|
|
3968
|
-
if (
|
|
3969
|
-
const installHint = LSP_INSTALL_HINTS[
|
|
4272
|
+
for (const server of servers) {
|
|
4273
|
+
if (server.extensions.includes(ext)) {
|
|
4274
|
+
const installHint = LSP_INSTALL_HINTS[server.id] ?? `Install '${server.command[0]}' and ensure it's in your PATH`;
|
|
3970
4275
|
return {
|
|
3971
4276
|
status: "not_installed",
|
|
3972
4277
|
server: {
|
|
3973
|
-
id:
|
|
3974
|
-
command:
|
|
3975
|
-
extensions:
|
|
4278
|
+
id: server.id,
|
|
4279
|
+
command: server.command,
|
|
4280
|
+
extensions: server.extensions
|
|
3976
4281
|
},
|
|
3977
4282
|
installHint
|
|
3978
4283
|
};
|
|
@@ -3988,20 +4293,21 @@ function findServerForExtension(ext) {
|
|
|
3988
4293
|
function getAllServers() {
|
|
3989
4294
|
const servers = getMergedServers();
|
|
3990
4295
|
const disabled = getDisabledServerIds();
|
|
4296
|
+
const workingDirectory = contextCwd();
|
|
3991
4297
|
const result = [];
|
|
3992
4298
|
const seen = new Set;
|
|
3993
|
-
for (const
|
|
3994
|
-
if (seen.has(
|
|
4299
|
+
for (const server of servers) {
|
|
4300
|
+
if (seen.has(server.id))
|
|
3995
4301
|
continue;
|
|
3996
4302
|
result.push({
|
|
3997
|
-
id:
|
|
3998
|
-
installed: isServerInstalled(
|
|
3999
|
-
extensions:
|
|
4303
|
+
id: server.id,
|
|
4304
|
+
installed: isServerInstalled(server.command, workingDirectory),
|
|
4305
|
+
extensions: server.extensions,
|
|
4000
4306
|
disabled: false,
|
|
4001
|
-
source:
|
|
4002
|
-
priority:
|
|
4307
|
+
source: server.source,
|
|
4308
|
+
priority: server.priority
|
|
4003
4309
|
});
|
|
4004
|
-
seen.add(
|
|
4310
|
+
seen.add(server.id);
|
|
4005
4311
|
}
|
|
4006
4312
|
for (const id of disabled) {
|
|
4007
4313
|
if (seen.has(id))
|
|
@@ -4009,7 +4315,7 @@ function getAllServers() {
|
|
|
4009
4315
|
const builtin = BUILTIN_SERVERS[id];
|
|
4010
4316
|
result.push({
|
|
4011
4317
|
id,
|
|
4012
|
-
installed: builtin ? isServerInstalled(builtin.command) : false,
|
|
4318
|
+
installed: builtin ? isServerInstalled(builtin.command, workingDirectory) : false,
|
|
4013
4319
|
extensions: builtin?.extensions ?? [],
|
|
4014
4320
|
disabled: true,
|
|
4015
4321
|
source: "disabled",
|
|
@@ -4020,7 +4326,6 @@ function getAllServers() {
|
|
|
4020
4326
|
}
|
|
4021
4327
|
|
|
4022
4328
|
// ../lsp-core/src/lsp/client-wrapper.ts
|
|
4023
|
-
var WORKSPACE_MARKERS = [".git", "package.json", "pyproject.toml", "Cargo.toml", "go.mod", "pom.xml", "build.gradle"];
|
|
4024
4329
|
function isDirectoryPath(filePath) {
|
|
4025
4330
|
try {
|
|
4026
4331
|
return statSync3(filePath).isDirectory();
|
|
@@ -4033,36 +4338,40 @@ function findWorkspaceRoot(filePath) {
|
|
|
4033
4338
|
const abs = resolveReadablePathInsideContext(filePath);
|
|
4034
4339
|
let dir = abs;
|
|
4035
4340
|
if (!isDirectoryPath(dir)) {
|
|
4036
|
-
dir =
|
|
4341
|
+
dir = dirname8(dir);
|
|
4037
4342
|
}
|
|
4343
|
+
if (!isPathInside(cwd, abs))
|
|
4344
|
+
return findWorkspaceRootOutsideContext(dir);
|
|
4038
4345
|
const fallbackRoot = nearestExistingDirectoryInsideContext(dir, cwd) ?? cwd;
|
|
4346
|
+
let nearestPackageRoot;
|
|
4039
4347
|
while (isPathInside(cwd, dir)) {
|
|
4040
4348
|
const canonicalDir = existingDirectoryInsideContext(dir, cwd);
|
|
4041
4349
|
if (canonicalDir !== undefined) {
|
|
4042
|
-
|
|
4043
|
-
|
|
4044
|
-
|
|
4045
|
-
|
|
4350
|
+
if (existsSync10(join5(dir, GIT_WORKSPACE_MARKER))) {
|
|
4351
|
+
return canonicalDir;
|
|
4352
|
+
}
|
|
4353
|
+
if (nearestPackageRoot === undefined && hasProjectWorkspaceMarker(dir)) {
|
|
4354
|
+
nearestPackageRoot = canonicalDir;
|
|
4046
4355
|
}
|
|
4047
4356
|
}
|
|
4048
4357
|
if (dir === cwd)
|
|
4049
4358
|
break;
|
|
4050
|
-
dir =
|
|
4359
|
+
dir = dirname8(dir);
|
|
4051
4360
|
}
|
|
4052
|
-
return fallbackRoot;
|
|
4361
|
+
return nearestPackageRoot ?? fallbackRoot;
|
|
4362
|
+
}
|
|
4363
|
+
function hasProjectWorkspaceMarker(directory) {
|
|
4364
|
+
return PROJECT_WORKSPACE_MARKERS.some((marker) => existsSync10(join5(directory, marker)));
|
|
4053
4365
|
}
|
|
4054
4366
|
function resolveReadablePathInsideContext(filePath) {
|
|
4055
4367
|
const cwd = contextCwd();
|
|
4056
|
-
const abs =
|
|
4368
|
+
const abs = resolve8(cwd, filePath);
|
|
4057
4369
|
if (isPathInside(cwd, abs))
|
|
4058
4370
|
return abs;
|
|
4059
4371
|
const rebased = rebaseThroughCanonicalAncestor(abs, cwd);
|
|
4060
4372
|
if (rebased !== undefined)
|
|
4061
4373
|
return rebased;
|
|
4062
|
-
|
|
4063
|
-
if (isPathInside(cwd, canonical))
|
|
4064
|
-
return canonical;
|
|
4065
|
-
throw new LspInvalidPathError(`LSP file path must be inside request cwd: ${filePath}`);
|
|
4374
|
+
return canonicalizeExistingOrNearestAncestor(abs);
|
|
4066
4375
|
}
|
|
4067
4376
|
function resolvePathInsideContext(filePath) {
|
|
4068
4377
|
const cwd = contextCwd();
|
|
@@ -4077,12 +4386,12 @@ function rebaseThroughCanonicalAncestor(path, cwd) {
|
|
|
4077
4386
|
let current = path;
|
|
4078
4387
|
const suffix = [];
|
|
4079
4388
|
while (true) {
|
|
4080
|
-
if (
|
|
4081
|
-
const canonical =
|
|
4389
|
+
if (existsSync10(current)) {
|
|
4390
|
+
const canonical = realpathSync5(current);
|
|
4082
4391
|
if (isPathInside(cwd, canonical))
|
|
4083
|
-
return suffix.length === 0 ? canonical :
|
|
4392
|
+
return suffix.length === 0 ? canonical : join5(canonical, ...suffix);
|
|
4084
4393
|
}
|
|
4085
|
-
const parent =
|
|
4394
|
+
const parent = dirname8(current);
|
|
4086
4395
|
if (parent === current)
|
|
4087
4396
|
return;
|
|
4088
4397
|
suffix.unshift(basename3(current));
|
|
@@ -4090,9 +4399,9 @@ function rebaseThroughCanonicalAncestor(path, cwd) {
|
|
|
4090
4399
|
}
|
|
4091
4400
|
}
|
|
4092
4401
|
function existingDirectoryInsideContext(directory, cwd) {
|
|
4093
|
-
if (!
|
|
4402
|
+
if (!existsSync10(directory))
|
|
4094
4403
|
return;
|
|
4095
|
-
const canonical =
|
|
4404
|
+
const canonical = realpathSync5(directory);
|
|
4096
4405
|
if (!statSync3(canonical).isDirectory())
|
|
4097
4406
|
return;
|
|
4098
4407
|
return isPathInside(cwd, canonical) ? canonical : undefined;
|
|
@@ -4105,7 +4414,7 @@ function nearestExistingDirectoryInsideContext(directory, cwd) {
|
|
|
4105
4414
|
return canonical;
|
|
4106
4415
|
if (current === cwd)
|
|
4107
4416
|
return;
|
|
4108
|
-
current =
|
|
4417
|
+
current = dirname8(current);
|
|
4109
4418
|
}
|
|
4110
4419
|
return;
|
|
4111
4420
|
}
|
|
@@ -4132,33 +4441,46 @@ function formatServerLookupError(result) {
|
|
|
4132
4441
|
].join(`
|
|
4133
4442
|
`);
|
|
4134
4443
|
}
|
|
4444
|
+
function formatInstallOptions(serverId, installHint) {
|
|
4445
|
+
const localHint = LSP_LOCAL_INSTALL_HINTS[serverId];
|
|
4446
|
+
if (localHint === undefined) {
|
|
4447
|
+
return ["To install, run:", ` ${installHint}`];
|
|
4448
|
+
}
|
|
4449
|
+
return [
|
|
4450
|
+
"To install in THIS repository (preferred — no global install needed):",
|
|
4451
|
+
` ${localHint}`,
|
|
4452
|
+
"",
|
|
4453
|
+
"Or install it globally:",
|
|
4454
|
+
` ${installHint}`
|
|
4455
|
+
];
|
|
4456
|
+
}
|
|
4135
4457
|
function formatNotInstalled(result) {
|
|
4136
|
-
const { server
|
|
4137
|
-
const extensions =
|
|
4138
|
-
const decision = loadInstallDecision(
|
|
4458
|
+
const { server, installHint } = result;
|
|
4459
|
+
const extensions = server.extensions.join(", ");
|
|
4460
|
+
const decision = loadInstallDecision(server.id)?.decision;
|
|
4139
4461
|
const context = lspRequestContext();
|
|
4140
4462
|
if (decision === "declined") {
|
|
4141
|
-
return `LSP server '${
|
|
4463
|
+
return `LSP server '${server.id}' (${extensions}) is NOT INSTALLED; user previously declined installation — proceed without LSP.`;
|
|
4142
4464
|
}
|
|
4143
4465
|
const header = [
|
|
4144
|
-
`LSP server '${
|
|
4466
|
+
`LSP server '${server.id}' for ${extensions} is NOT INSTALLED.`,
|
|
4145
4467
|
"",
|
|
4146
|
-
`Command not found: ${
|
|
4468
|
+
`Command not found: ${server.command[0]}`,
|
|
4147
4469
|
""
|
|
4148
4470
|
];
|
|
4471
|
+
const installOptions = formatInstallOptions(server.id, installHint);
|
|
4149
4472
|
if (decision === "allowed") {
|
|
4150
4473
|
return [
|
|
4151
4474
|
...header,
|
|
4152
4475
|
"The user has pre-authorized LSP installation. Run the install command, then retry this tool:",
|
|
4153
|
-
|
|
4476
|
+
...installOptions.slice(1)
|
|
4154
4477
|
].join(`
|
|
4155
4478
|
`);
|
|
4156
4479
|
}
|
|
4157
4480
|
if (!context.capabilities.installDecisionTool) {
|
|
4158
4481
|
return [
|
|
4159
4482
|
...header,
|
|
4160
|
-
|
|
4161
|
-
` ${installHint}`,
|
|
4483
|
+
...installOptions,
|
|
4162
4484
|
"",
|
|
4163
4485
|
"ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
|
|
4164
4486
|
"Install-decision recording is unavailable in this harness; proceed without LSP if the user declines."
|
|
@@ -4167,13 +4489,12 @@ function formatNotInstalled(result) {
|
|
|
4167
4489
|
}
|
|
4168
4490
|
return [
|
|
4169
4491
|
...header,
|
|
4170
|
-
|
|
4171
|
-
` ${installHint}`,
|
|
4492
|
+
...installOptions,
|
|
4172
4493
|
"",
|
|
4173
4494
|
"ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
|
|
4174
4495
|
"- If the user agrees: run the install command above, then retry this tool.",
|
|
4175
4496
|
"- If the user declines, OR has NOT explicitly asked for LSP installation:",
|
|
4176
|
-
` call lsp_install_decision { server_id: "${
|
|
4497
|
+
` call lsp_install_decision { server_id: "${server.id}", decision: "declined" },`,
|
|
4177
4498
|
` which writes to ${context.installDecisionsPath},`,
|
|
4178
4499
|
" then ignore this message and proceed WITHOUT LSP."
|
|
4179
4500
|
].join(`
|
|
@@ -4197,34 +4518,34 @@ async function withLspClient(filePath, fn, toolName, options = {}) {
|
|
|
4197
4518
|
if (result.status !== "found") {
|
|
4198
4519
|
throw new LspServerLookupError(formatServerLookupError(result), result);
|
|
4199
4520
|
}
|
|
4200
|
-
const
|
|
4521
|
+
const server = result.server;
|
|
4201
4522
|
const root = findWorkspaceRoot(absPath);
|
|
4202
4523
|
const manager = options.manager ?? getLspManager();
|
|
4203
4524
|
const acquireAndCall = async (allowRetry) => {
|
|
4204
|
-
const client = await manager.getClient(root,
|
|
4525
|
+
const client = await manager.getClient(root, server, options.signal);
|
|
4205
4526
|
try {
|
|
4206
4527
|
return await fn(client, root, absPath);
|
|
4207
4528
|
} catch (err) {
|
|
4208
4529
|
if (allowRetry && READ_ONLY_TOOLS.has(toolName) && isLspDeadConnectionError(err)) {
|
|
4209
|
-
manager.invalidateClient(root,
|
|
4530
|
+
manager.invalidateClient(root, server.id, client);
|
|
4210
4531
|
return acquireAndCall(false);
|
|
4211
4532
|
}
|
|
4212
4533
|
if (err instanceof LspRequestTimeoutError) {
|
|
4213
|
-
if (manager.isServerInitializing(root,
|
|
4534
|
+
if (manager.isServerInitializing(root, server.id)) {
|
|
4214
4535
|
throw new LspServerInitializingError(err);
|
|
4215
4536
|
}
|
|
4216
4537
|
}
|
|
4217
4538
|
throw err;
|
|
4218
4539
|
} finally {
|
|
4219
|
-
manager.releaseClient(root,
|
|
4540
|
+
manager.releaseClient(root, server.id);
|
|
4220
4541
|
}
|
|
4221
4542
|
};
|
|
4222
4543
|
return acquireAndCall(true);
|
|
4223
4544
|
}
|
|
4224
4545
|
|
|
4225
4546
|
// ../lsp-core/src/lsp/directory-diagnostics.ts
|
|
4226
|
-
import { existsSync as
|
|
4227
|
-
import { join as
|
|
4547
|
+
import { existsSync as existsSync11, lstatSync as lstatSync4, readdirSync as readdirSync3 } from "node:fs";
|
|
4548
|
+
import { join as join6, resolve as resolve9 } from "node:path";
|
|
4228
4549
|
|
|
4229
4550
|
// ../lsp-core/src/lsp/formatters.ts
|
|
4230
4551
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
@@ -4239,10 +4560,10 @@ function uriToPath(uri) {
|
|
|
4239
4560
|
}
|
|
4240
4561
|
function formatLocation(loc) {
|
|
4241
4562
|
if ("targetUri" in loc) {
|
|
4242
|
-
const
|
|
4243
|
-
const
|
|
4244
|
-
const
|
|
4245
|
-
return `${
|
|
4563
|
+
const uri = uriToPath(loc.targetUri);
|
|
4564
|
+
const line = loc.targetRange.start.line + 1;
|
|
4565
|
+
const char = loc.targetRange.start.character;
|
|
4566
|
+
return `${uri}:${line}:${char}`;
|
|
4246
4567
|
}
|
|
4247
4568
|
const uri = uriToPath(loc.uri);
|
|
4248
4569
|
const line = loc.range.start.line + 1;
|
|
@@ -4354,7 +4675,7 @@ function collectFilesWithExtension(dir, extension, maxFiles) {
|
|
|
4354
4675
|
for (const entry of entries) {
|
|
4355
4676
|
if (files.length >= maxFiles)
|
|
4356
4677
|
return;
|
|
4357
|
-
const fullPath =
|
|
4678
|
+
const fullPath = join6(currentDir, entry);
|
|
4358
4679
|
let stat;
|
|
4359
4680
|
try {
|
|
4360
4681
|
stat = lstatSync4(fullPath);
|
|
@@ -4379,15 +4700,15 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
|
|
|
4379
4700
|
if (!extension.startsWith(".")) {
|
|
4380
4701
|
throw new LspInvalidPathError(`Extension must start with a dot (e.g., ".ts", not "${extension}"). Use ".${extension}" instead.`);
|
|
4381
4702
|
}
|
|
4382
|
-
const absDir =
|
|
4383
|
-
if (!
|
|
4703
|
+
const absDir = resolve9(options.workspaceRoot ?? contextCwd(), directory);
|
|
4704
|
+
if (!existsSync11(absDir)) {
|
|
4384
4705
|
throw new LspInvalidPathError(`Directory does not exist: ${absDir}`);
|
|
4385
4706
|
}
|
|
4386
4707
|
const serverResult = options.server === undefined ? findServerForExtension(extension) : { status: "found", server: options.server };
|
|
4387
4708
|
if (serverResult.status !== "found") {
|
|
4388
4709
|
throw new LspServerLookupError(formatServerLookupError(serverResult));
|
|
4389
4710
|
}
|
|
4390
|
-
const
|
|
4711
|
+
const server = serverResult.server;
|
|
4391
4712
|
const allFiles = (options.listFiles ?? collectFilesWithExtension)(absDir, extension, maxFiles + 1);
|
|
4392
4713
|
const wasCapped = allFiles.length > maxFiles;
|
|
4393
4714
|
const filesToProcess = allFiles.slice(0, maxFiles);
|
|
@@ -4407,7 +4728,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
|
|
|
4407
4728
|
const fileErrors = [];
|
|
4408
4729
|
const maxConcurrency = Math.max(1, options.maxConcurrency ?? DIRECTORY_DIAGNOSTICS_MAX_CONCURRENCY);
|
|
4409
4730
|
options.signal?.throwIfAborted();
|
|
4410
|
-
const client = await manager.getClient(root,
|
|
4731
|
+
const client = await manager.getClient(root, server, options.signal);
|
|
4411
4732
|
try {
|
|
4412
4733
|
let nextIndex = 0;
|
|
4413
4734
|
const workers = Array.from({ length: Math.min(maxConcurrency, filesToProcess.length) }, async () => {
|
|
@@ -4435,7 +4756,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
|
|
|
4435
4756
|
});
|
|
4436
4757
|
await Promise.all(workers);
|
|
4437
4758
|
} finally {
|
|
4438
|
-
manager.releaseClient(root,
|
|
4759
|
+
manager.releaseClient(root, server.id);
|
|
4439
4760
|
}
|
|
4440
4761
|
const displayDiagnostics = allDiagnostics.slice(0, DEFAULT_MAX_DIAGNOSTICS);
|
|
4441
4762
|
const wasDiagCapped = allDiagnostics.length > DEFAULT_MAX_DIAGNOSTICS;
|
|
@@ -4467,7 +4788,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
|
|
|
4467
4788
|
|
|
4468
4789
|
// ../lsp-core/src/lsp/infer-extension.ts
|
|
4469
4790
|
import { lstatSync as lstatSync5, readdirSync as readdirSync4 } from "node:fs";
|
|
4470
|
-
import { join as
|
|
4791
|
+
import { join as join7 } from "node:path";
|
|
4471
4792
|
var SKIP_DIRECTORIES2 = new Set(["node_modules", ".git", "dist", "build", ".next", "out"]);
|
|
4472
4793
|
var MAX_SCAN_ENTRIES = 500;
|
|
4473
4794
|
function inferExtensionFromDirectory(directory) {
|
|
@@ -4485,7 +4806,7 @@ function inferExtensionFromDirectory(directory) {
|
|
|
4485
4806
|
for (const entry of entries) {
|
|
4486
4807
|
if (scanned >= MAX_SCAN_ENTRIES)
|
|
4487
4808
|
return;
|
|
4488
|
-
const fullPath =
|
|
4809
|
+
const fullPath = join7(dir, entry);
|
|
4489
4810
|
let stat;
|
|
4490
4811
|
try {
|
|
4491
4812
|
stat = lstatSync5(fullPath);
|
|
@@ -4644,8 +4965,8 @@ function clientOptions(signal) {
|
|
|
4644
4965
|
}
|
|
4645
4966
|
|
|
4646
4967
|
// ../lsp-core/src/tools/result.ts
|
|
4647
|
-
function text(
|
|
4648
|
-
return { content: [{ type: "text", text
|
|
4968
|
+
function text(text, details, isError = false) {
|
|
4969
|
+
return { content: [{ type: "text", text }], details, isError };
|
|
4649
4970
|
}
|
|
4650
4971
|
|
|
4651
4972
|
// ../lsp-core/src/tools/diagnostics.ts
|
|
@@ -4665,7 +4986,7 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
4665
4986
|
const extension = inferExtensionFromDirectory(absPath);
|
|
4666
4987
|
if (!extension) {
|
|
4667
4988
|
const message = `No supported source files found in directory: ${absPath}`;
|
|
4668
|
-
const
|
|
4989
|
+
const details = {
|
|
4669
4990
|
filePath,
|
|
4670
4991
|
severity,
|
|
4671
4992
|
mode: "directory",
|
|
@@ -4675,24 +4996,24 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
4675
4996
|
error: message,
|
|
4676
4997
|
errorKind: "no_files"
|
|
4677
4998
|
};
|
|
4678
|
-
return text(message,
|
|
4999
|
+
return text(message, details);
|
|
4679
5000
|
}
|
|
4680
|
-
const
|
|
4681
|
-
const
|
|
5001
|
+
const output = await aggregateDiagnosticsForDirectory(absPath, extension, severity, undefined, signal === undefined ? {} : { signal });
|
|
5002
|
+
const details = {
|
|
4682
5003
|
filePath,
|
|
4683
5004
|
severity,
|
|
4684
5005
|
mode: "directory",
|
|
4685
5006
|
diagnostics: [],
|
|
4686
|
-
totalDiagnostics:
|
|
5007
|
+
totalDiagnostics: output.totalDiagnostics,
|
|
4687
5008
|
truncated: false,
|
|
4688
|
-
fileFailures: [...
|
|
5009
|
+
fileFailures: [...output.fileFailures]
|
|
4689
5010
|
};
|
|
4690
|
-
return text(
|
|
5011
|
+
return text(output.output, details);
|
|
4691
5012
|
}
|
|
4692
5013
|
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.diagnostics(resolvedFilePath, signal), "diagnostics", clientOptions(signal));
|
|
4693
5014
|
if (result.transientError) {
|
|
4694
5015
|
const message = result.transientError.message;
|
|
4695
|
-
const
|
|
5016
|
+
const details = {
|
|
4696
5017
|
filePath,
|
|
4697
5018
|
severity,
|
|
4698
5019
|
mode: "file",
|
|
@@ -4702,7 +5023,7 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
4702
5023
|
error: message,
|
|
4703
5024
|
errorKind: result.transientError.kind
|
|
4704
5025
|
};
|
|
4705
|
-
return text(message,
|
|
5026
|
+
return text(message, details, true);
|
|
4706
5027
|
}
|
|
4707
5028
|
const diagnostics = filterDiagnosticsBySeverity(asDiagnosticArray(result), severity);
|
|
4708
5029
|
const total = diagnostics.length;
|
|
@@ -4736,6 +5057,96 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
4736
5057
|
throw error;
|
|
4737
5058
|
}
|
|
4738
5059
|
}
|
|
5060
|
+
// ../lsp-core/src/lsp/format-document.ts
|
|
5061
|
+
import { readFileSync as readFileSync5, renameSync as renameSync3, unlinkSync, writeFileSync as writeFileSync3 } from "node:fs";
|
|
5062
|
+
var DEFAULT_FORMATTING_OPTIONS = {
|
|
5063
|
+
tabSize: 4,
|
|
5064
|
+
insertSpaces: false,
|
|
5065
|
+
trimTrailingWhitespace: true,
|
|
5066
|
+
insertFinalNewline: true,
|
|
5067
|
+
trimFinalNewlines: true
|
|
5068
|
+
};
|
|
5069
|
+
var UNCHANGED = { status: "unchanged", linesAdded: 0, linesRemoved: 0 };
|
|
5070
|
+
async function formatDocumentWithClient(client, filePath, options = {}) {
|
|
5071
|
+
const edits = await client.formatDocument(filePath, options.formattingOptions ?? DEFAULT_FORMATTING_OPTIONS, options.signal);
|
|
5072
|
+
if (edits === null)
|
|
5073
|
+
return { status: "unavailable", reason: "capability_not_advertised" };
|
|
5074
|
+
if (edits.length === 0)
|
|
5075
|
+
return UNCHANGED;
|
|
5076
|
+
const before = readFileSync5(filePath, "utf-8");
|
|
5077
|
+
const normalized = normalizeTextEdits(before, edits, 0);
|
|
5078
|
+
if (normalized.text === before)
|
|
5079
|
+
return UNCHANGED;
|
|
5080
|
+
writeAtomically(filePath, normalized.text);
|
|
5081
|
+
await client.openFile(filePath);
|
|
5082
|
+
return {
|
|
5083
|
+
status: "formatted",
|
|
5084
|
+
...lineDelta(normalized.edits)
|
|
5085
|
+
};
|
|
5086
|
+
}
|
|
5087
|
+
function lineDelta(edits) {
|
|
5088
|
+
let linesAdded = 0;
|
|
5089
|
+
let linesRemoved = 0;
|
|
5090
|
+
for (const edit of edits) {
|
|
5091
|
+
linesRemoved += edit.range.end.line - edit.range.start.line + 1;
|
|
5092
|
+
linesAdded += edit.newText.split(`
|
|
5093
|
+
`).length;
|
|
5094
|
+
}
|
|
5095
|
+
return { linesAdded, linesRemoved };
|
|
5096
|
+
}
|
|
5097
|
+
function writeAtomically(filePath, content) {
|
|
5098
|
+
const tempPath = `${filePath}.omo-format.tmp`;
|
|
5099
|
+
writeFileSync3(tempPath, content, "utf-8");
|
|
5100
|
+
try {
|
|
5101
|
+
renameSync3(tempPath, filePath);
|
|
5102
|
+
} catch (error) {
|
|
5103
|
+
try {
|
|
5104
|
+
unlinkSync(tempPath);
|
|
5105
|
+
} catch {}
|
|
5106
|
+
throw error;
|
|
5107
|
+
}
|
|
5108
|
+
}
|
|
5109
|
+
|
|
5110
|
+
// ../lsp-core/src/tools/format.ts
|
|
5111
|
+
async function executeLspFormat(params, signal) {
|
|
5112
|
+
const filePath = requireString(params, "filePath");
|
|
5113
|
+
try {
|
|
5114
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => formatDocumentWithClient(client, resolvedFilePath, signal === undefined ? {} : { signal }), "format", clientOptions(signal));
|
|
5115
|
+
return text(describeResult(filePath, result), formatDetails(filePath, result));
|
|
5116
|
+
} catch (error) {
|
|
5117
|
+
const missingDependency = missingDependencyResult(error, {
|
|
5118
|
+
filePath,
|
|
5119
|
+
status: "unavailable",
|
|
5120
|
+
reason: "server_unavailable",
|
|
5121
|
+
linesAdded: 0,
|
|
5122
|
+
linesRemoved: 0
|
|
5123
|
+
});
|
|
5124
|
+
if (missingDependency)
|
|
5125
|
+
return missingDependency;
|
|
5126
|
+
throw error;
|
|
5127
|
+
}
|
|
5128
|
+
}
|
|
5129
|
+
function formatDetails(filePath, result) {
|
|
5130
|
+
if (result.status === "unavailable") {
|
|
5131
|
+
return { filePath, status: "unavailable", reason: result.reason, linesAdded: 0, linesRemoved: 0 };
|
|
5132
|
+
}
|
|
5133
|
+
return {
|
|
5134
|
+
filePath,
|
|
5135
|
+
status: result.status,
|
|
5136
|
+
linesAdded: result.linesAdded,
|
|
5137
|
+
linesRemoved: result.linesRemoved
|
|
5138
|
+
};
|
|
5139
|
+
}
|
|
5140
|
+
function describeResult(filePath, result) {
|
|
5141
|
+
if (result.status === "unavailable") {
|
|
5142
|
+
return `Formatting unavailable for ${filePath}: the language server does not advertise documentFormattingProvider.`;
|
|
5143
|
+
}
|
|
5144
|
+
if (result.status === "unchanged") {
|
|
5145
|
+
return `Already formatted: ${filePath}`;
|
|
5146
|
+
}
|
|
5147
|
+
return `Formatted ${filePath} (+${result.linesAdded}/-${result.linesRemoved} lines)`;
|
|
5148
|
+
}
|
|
5149
|
+
|
|
4739
5150
|
// ../lsp-core/src/tools/install-decision.ts
|
|
4740
5151
|
async function executeLspInstallDecision(params) {
|
|
4741
5152
|
const serverId = requireString(params, "server_id");
|
|
@@ -4743,7 +5154,7 @@ async function executeLspInstallDecision(params) {
|
|
|
4743
5154
|
if (!isInstallDecision(decision)) {
|
|
4744
5155
|
return text(`Invalid decision '${String(decision)}'. Expected "declined" or "allowed".`, { serverId, errorKind: "invalid_decision" }, true);
|
|
4745
5156
|
}
|
|
4746
|
-
const serverIds = [...new Set(getMergedServers().map((
|
|
5157
|
+
const serverIds = [...new Set(getMergedServers().map((server) => server.id))];
|
|
4747
5158
|
if (!serverIds.includes(serverId)) {
|
|
4748
5159
|
const preview = serverIds.slice(0, 20).join(", ");
|
|
4749
5160
|
return text(`Unknown LSP server '${serverId}'. Known servers: ${preview}${serverIds.length > 20 ? "..." : ""}`, { serverId, errorKind: "unknown_server" }, true);
|
|
@@ -4883,10 +5294,10 @@ function objectSchema(properties, required = []) {
|
|
|
4883
5294
|
async function executeLspStatus() {
|
|
4884
5295
|
const servers = getAllServers();
|
|
4885
5296
|
const snapshots = getLspManager().getSnapshot();
|
|
4886
|
-
const installed = servers.filter((
|
|
4887
|
-
const configuredLines = servers.map((
|
|
4888
|
-
const state =
|
|
4889
|
-
return `- ${
|
|
5297
|
+
const installed = servers.filter((server) => server.installed && !server.disabled);
|
|
5298
|
+
const configuredLines = servers.map((server) => {
|
|
5299
|
+
const state = server.disabled ? "disabled" : server.installed ? "installed" : "missing";
|
|
5300
|
+
return `- ${server.id}: ${state}; source=${server.source}; extensions=${server.extensions.join(", ")}`;
|
|
4890
5301
|
});
|
|
4891
5302
|
const activeLines = snapshots.map((snapshot) => {
|
|
4892
5303
|
const state = snapshot.alive ? snapshot.isInitializing ? "initializing" : "alive" : "dead";
|
|
@@ -4929,8 +5340,8 @@ async function executeLspSymbols(params, signal) {
|
|
|
4929
5340
|
errorKind: "missing_query"
|
|
4930
5341
|
});
|
|
4931
5342
|
}
|
|
4932
|
-
const
|
|
4933
|
-
return formatSymbolsResult(filePath, scope,
|
|
5343
|
+
const symbols = await withLspClient(filePath, async (client) => client.workspaceSymbols(query, signal), "workspaceSymbols", clientOptions(signal));
|
|
5344
|
+
return formatSymbolsResult(filePath, scope, symbols, limit, query);
|
|
4934
5345
|
}
|
|
4935
5346
|
const symbols = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.documentSymbols(resolvedFilePath, signal), "documentSymbols", clientOptions(signal));
|
|
4936
5347
|
return formatSymbolsResult(filePath, scope, symbols, limit);
|
|
@@ -5068,6 +5479,16 @@ var LSP_MCP_TOOLS = [
|
|
|
5068
5479
|
}, ["filePath", "line", "character", "newName"]),
|
|
5069
5480
|
execute: executeLspRename
|
|
5070
5481
|
},
|
|
5482
|
+
{
|
|
5483
|
+
name: "format",
|
|
5484
|
+
aliases: ["lsp_format"],
|
|
5485
|
+
title: "LSP Format",
|
|
5486
|
+
description: "Format a source file with its language server and write the returned edits to disk.",
|
|
5487
|
+
inputSchema: objectSchema({
|
|
5488
|
+
filePath: { type: "string", description: "Source file path to format." }
|
|
5489
|
+
}, ["filePath"]),
|
|
5490
|
+
execute: executeLspFormat
|
|
5491
|
+
},
|
|
5071
5492
|
{
|
|
5072
5493
|
name: "install_decision",
|
|
5073
5494
|
aliases: ["lsp_install_decision"],
|
|
@@ -5167,11 +5588,10 @@ function requestedProtocolVersion(params) {
|
|
|
5167
5588
|
// src/daemon-client.ts
|
|
5168
5589
|
import { connect } from "node:net";
|
|
5169
5590
|
import { homedir as homedir3 } from "node:os";
|
|
5170
|
-
import { join as
|
|
5591
|
+
import { join as join8 } from "node:path";
|
|
5171
5592
|
|
|
5172
5593
|
// src/daemon-request-error.ts
|
|
5173
5594
|
class DaemonRequestError extends Error {
|
|
5174
|
-
requestWritten;
|
|
5175
5595
|
constructor(message, requestWritten) {
|
|
5176
5596
|
super(message);
|
|
5177
5597
|
this.name = "DaemonRequestError";
|
|
@@ -5194,7 +5614,6 @@ class DaemonRequestCancelledError extends DaemonRequestError {
|
|
|
5194
5614
|
}
|
|
5195
5615
|
|
|
5196
5616
|
class DaemonRequestTimedOutError extends DaemonRequestError {
|
|
5197
|
-
timeoutMs;
|
|
5198
5617
|
constructor(requestWritten, timeoutMs) {
|
|
5199
5618
|
super("daemon request timed out", requestWritten);
|
|
5200
5619
|
this.name = "DaemonRequestTimedOutError";
|
|
@@ -5211,26 +5630,26 @@ function daemonFailureResult(paths, error) {
|
|
|
5211
5630
|
return daemonUnreachableResult(paths, error);
|
|
5212
5631
|
}
|
|
5213
5632
|
function daemonCancelledResult(paths) {
|
|
5214
|
-
const
|
|
5633
|
+
const text = [
|
|
5215
5634
|
"LSP daemon request cancelled: the caller aborted this request (for example, the turn was interrupted).",
|
|
5216
5635
|
"The daemon stays available; no LSP work was applied. Retry when you are ready.",
|
|
5217
5636
|
`Socket: ${paths.socket}`
|
|
5218
5637
|
].join(`
|
|
5219
5638
|
`);
|
|
5220
|
-
return { content: [{ type: "text", text
|
|
5639
|
+
return { content: [{ type: "text", text }], isError: true };
|
|
5221
5640
|
}
|
|
5222
5641
|
function daemonTimedOutResult(paths, timeoutMs) {
|
|
5223
|
-
const
|
|
5642
|
+
const text = [
|
|
5224
5643
|
`LSP daemon request timed out after ${timeoutMs}ms: the daemon did not respond in time.`,
|
|
5225
5644
|
"The daemon stays available but may be busy. Retry when you are ready.",
|
|
5226
5645
|
`Socket: ${paths.socket}`,
|
|
5227
5646
|
`Logs: ${paths.log}`
|
|
5228
5647
|
].join(`
|
|
5229
5648
|
`);
|
|
5230
|
-
return { content: [{ type: "text", text
|
|
5649
|
+
return { content: [{ type: "text", text }], isError: true };
|
|
5231
5650
|
}
|
|
5232
5651
|
function daemonUnreachableResult(paths, error) {
|
|
5233
|
-
const
|
|
5652
|
+
const text = [
|
|
5234
5653
|
`LSP daemon unreachable: ${errorText(error)}.`,
|
|
5235
5654
|
"The MCP server is a thin proxy and never runs language servers in-process.",
|
|
5236
5655
|
`Socket: ${paths.socket}`,
|
|
@@ -5238,7 +5657,7 @@ function daemonUnreachableResult(paths, error) {
|
|
|
5238
5657
|
"The daemon is auto-started on demand and will be retried on the next request."
|
|
5239
5658
|
].join(`
|
|
5240
5659
|
`);
|
|
5241
|
-
return { content: [{ type: "text", text
|
|
5660
|
+
return { content: [{ type: "text", text }], isError: true };
|
|
5242
5661
|
}
|
|
5243
5662
|
function errorText(error) {
|
|
5244
5663
|
return error instanceof Error ? error.message : String(error);
|
|
@@ -5246,9 +5665,9 @@ function errorText(error) {
|
|
|
5246
5665
|
|
|
5247
5666
|
// src/ensure-daemon.ts
|
|
5248
5667
|
import { spawn as spawn2 } from "node:child_process";
|
|
5249
|
-
import { closeSync as closeSync2, existsSync as
|
|
5668
|
+
import { closeSync as closeSync2, existsSync as existsSync12, mkdirSync as mkdirSync3, openSync as openSync2, writeSync as writeSync2 } from "node:fs";
|
|
5250
5669
|
import { Socket } from "node:net";
|
|
5251
|
-
import { dirname as
|
|
5670
|
+
import { dirname as dirname10, isAbsolute as isAbsolute5 } from "node:path";
|
|
5252
5671
|
import { argv0, execPath } from "node:process";
|
|
5253
5672
|
|
|
5254
5673
|
// src/ipc-protocol.ts
|
|
@@ -5262,25 +5681,23 @@ import {
|
|
|
5262
5681
|
lstatSync as lstatSync6,
|
|
5263
5682
|
mkdirSync as mkdirSync2,
|
|
5264
5683
|
openSync,
|
|
5265
|
-
readFileSync as
|
|
5266
|
-
unlinkSync,
|
|
5684
|
+
readFileSync as readFileSync6,
|
|
5685
|
+
unlinkSync as unlinkSync2,
|
|
5267
5686
|
writeSync
|
|
5268
5687
|
} from "node:fs";
|
|
5269
|
-
import { dirname as
|
|
5688
|
+
import { dirname as dirname9 } from "node:path";
|
|
5270
5689
|
var OMO_DAEMON_PROTOCOL_VERSION = 1;
|
|
5271
5690
|
var AUTH_ERROR_CODE = -32001;
|
|
5272
5691
|
var PROTOCOL_ERROR_CODE = -32002;
|
|
5273
5692
|
var AUTH_TOKEN_BYTES = 32;
|
|
5274
5693
|
|
|
5275
5694
|
class UnsafePrivateDirectoryError extends Error {
|
|
5276
|
-
path;
|
|
5277
|
-
reason;
|
|
5278
|
-
name = "UnsafePrivateDirectoryError";
|
|
5279
|
-
code = "unsafe_private_directory";
|
|
5280
5695
|
constructor(path, reason) {
|
|
5281
5696
|
super(`unsafe private directory ${path}: ${reason}`);
|
|
5282
5697
|
this.path = path;
|
|
5283
5698
|
this.reason = reason;
|
|
5699
|
+
this.name = "UnsafePrivateDirectoryError";
|
|
5700
|
+
this.code = "unsafe_private_directory";
|
|
5284
5701
|
}
|
|
5285
5702
|
}
|
|
5286
5703
|
function authEnvelope(token) {
|
|
@@ -5288,7 +5705,7 @@ function authEnvelope(token) {
|
|
|
5288
5705
|
}
|
|
5289
5706
|
function readAuthToken(paths) {
|
|
5290
5707
|
try {
|
|
5291
|
-
const token =
|
|
5708
|
+
const token = readFileSync6(paths.auth, "utf8").trim();
|
|
5292
5709
|
return token.length > 0 ? token : null;
|
|
5293
5710
|
} catch (error) {
|
|
5294
5711
|
if (error instanceof Error)
|
|
@@ -5304,7 +5721,7 @@ function readOrCreateAuthToken(paths) {
|
|
|
5304
5721
|
}
|
|
5305
5722
|
function rotateAuthToken(paths) {
|
|
5306
5723
|
try {
|
|
5307
|
-
|
|
5724
|
+
unlinkSync2(paths.auth);
|
|
5308
5725
|
} catch (error) {
|
|
5309
5726
|
if (!(error instanceof Error))
|
|
5310
5727
|
throw error;
|
|
@@ -5376,7 +5793,7 @@ function setPrivateFileMode(path) {
|
|
|
5376
5793
|
chmodSync(path, 384);
|
|
5377
5794
|
}
|
|
5378
5795
|
function createAuthToken(paths) {
|
|
5379
|
-
ensurePrivateDirectory(
|
|
5796
|
+
ensurePrivateDirectory(dirname9(paths.auth));
|
|
5380
5797
|
const token = randomBytes(AUTH_TOKEN_BYTES).toString("base64url");
|
|
5381
5798
|
let fd;
|
|
5382
5799
|
try {
|
|
@@ -5457,27 +5874,25 @@ import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
|
5457
5874
|
|
|
5458
5875
|
// src/runtime-contract.ts
|
|
5459
5876
|
import { statSync as statSync4 } from "node:fs";
|
|
5460
|
-
import { isAbsolute as
|
|
5877
|
+
import { isAbsolute as isAbsolute4 } from "node:path";
|
|
5461
5878
|
var OMO_LSP_DAEMON_DIR = "OMO_LSP_DAEMON_DIR";
|
|
5462
5879
|
var OMO_LSP_DAEMON_CLI = "OMO_LSP_DAEMON_CLI";
|
|
5463
5880
|
var OMO_LSP_DAEMON_VERSION = "OMO_LSP_DAEMON_VERSION";
|
|
5464
5881
|
var DAEMON_VERSION_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._+-]{0,127}$/;
|
|
5465
5882
|
|
|
5466
5883
|
class InvalidRuntimeOverrideError extends Error {
|
|
5467
|
-
code = "invalid_runtime_override";
|
|
5468
|
-
reason;
|
|
5469
5884
|
constructor(reason, message) {
|
|
5470
5885
|
super(message);
|
|
5886
|
+
this.code = "invalid_runtime_override";
|
|
5471
5887
|
this.name = "InvalidRuntimeOverrideError";
|
|
5472
5888
|
this.reason = reason;
|
|
5473
5889
|
}
|
|
5474
5890
|
}
|
|
5475
5891
|
|
|
5476
5892
|
class InvalidDaemonVersionError extends Error {
|
|
5477
|
-
code = "invalid_daemon_version";
|
|
5478
|
-
version;
|
|
5479
5893
|
constructor(version) {
|
|
5480
5894
|
super("LSP daemon version must match [A-Za-z0-9][A-Za-z0-9._+-]{0,127}");
|
|
5895
|
+
this.code = "invalid_daemon_version";
|
|
5481
5896
|
this.name = "InvalidDaemonVersionError";
|
|
5482
5897
|
this.version = version;
|
|
5483
5898
|
}
|
|
@@ -5496,12 +5911,12 @@ function resolveDaemonRuntime(env, defaults) {
|
|
|
5496
5911
|
throw new InvalidRuntimeOverrideError("paired_values_required", `${OMO_LSP_DAEMON_CLI} and ${OMO_LSP_DAEMON_VERSION} must be set together`);
|
|
5497
5912
|
}
|
|
5498
5913
|
if (!hasCliOverride || !hasVersionOverride) {
|
|
5499
|
-
if (!
|
|
5914
|
+
if (!isAbsolute4(defaults.cliPath)) {
|
|
5500
5915
|
throw new InvalidRuntimeOverrideError("packaged_cli_must_be_absolute", "Packaged LSP daemon CLI path must be absolute");
|
|
5501
5916
|
}
|
|
5502
5917
|
return { cliPath: defaults.cliPath, version: validateDaemonVersion(defaults.version) };
|
|
5503
5918
|
}
|
|
5504
|
-
if (!
|
|
5919
|
+
if (!isAbsolute4(cliOverride)) {
|
|
5505
5920
|
throw new InvalidRuntimeOverrideError("cli_must_be_absolute", `${OMO_LSP_DAEMON_CLI} must be an absolute path to an existing regular file`);
|
|
5506
5921
|
}
|
|
5507
5922
|
let cliStats;
|
|
@@ -5523,10 +5938,9 @@ var requireFromHere = createRequire(import.meta.url);
|
|
|
5523
5938
|
var MAX_SOCKET_PATH_LENGTH = 100;
|
|
5524
5939
|
|
|
5525
5940
|
class InvalidDaemonDirectoryError extends Error {
|
|
5526
|
-
code = "invalid_daemon_directory";
|
|
5527
|
-
directory;
|
|
5528
5941
|
constructor(directory) {
|
|
5529
5942
|
super(`${OMO_LSP_DAEMON_DIR} must be an absolute path`);
|
|
5943
|
+
this.code = "invalid_daemon_directory";
|
|
5530
5944
|
this.name = "InvalidDaemonDirectoryError";
|
|
5531
5945
|
this.directory = directory;
|
|
5532
5946
|
}
|
|
@@ -5680,7 +6094,7 @@ async function probeDaemon(paths, timeoutMs = PROBE_TIMEOUT_MS, signal) {
|
|
|
5680
6094
|
return await pingDaemon(paths, token, timeoutMs, signal) !== null;
|
|
5681
6095
|
}
|
|
5682
6096
|
function pingDaemon(paths, token, timeoutMs = PROBE_TIMEOUT_MS, signal) {
|
|
5683
|
-
return new Promise((
|
|
6097
|
+
return new Promise((resolve) => {
|
|
5684
6098
|
const socket = new Socket;
|
|
5685
6099
|
let settled = false;
|
|
5686
6100
|
let timer;
|
|
@@ -5692,7 +6106,7 @@ function pingDaemon(paths, token, timeoutMs = PROBE_TIMEOUT_MS, signal) {
|
|
|
5692
6106
|
clearTimeout(timer);
|
|
5693
6107
|
signal?.removeEventListener("abort", onAbort);
|
|
5694
6108
|
socket.destroy();
|
|
5695
|
-
|
|
6109
|
+
resolve(value);
|
|
5696
6110
|
};
|
|
5697
6111
|
const onAbort = () => finish(null);
|
|
5698
6112
|
const decoder = createLineDecoder((message) => {
|
|
@@ -5715,13 +6129,17 @@ function pingDaemon(paths, token, timeoutMs = PROBE_TIMEOUT_MS, signal) {
|
|
|
5715
6129
|
socket.connect(paths.socket);
|
|
5716
6130
|
});
|
|
5717
6131
|
}
|
|
5718
|
-
function spawnDaemonProcess(paths) {
|
|
5719
|
-
mkdirSync3(
|
|
6132
|
+
function spawnDaemonProcess(paths, deps = {}) {
|
|
6133
|
+
mkdirSync3(dirname10(paths.log), { recursive: true });
|
|
5720
6134
|
const logFd = openSync2(paths.log, "a");
|
|
5721
6135
|
try {
|
|
5722
|
-
const
|
|
6136
|
+
const spawnDaemonChild = deps.spawn ?? spawn2;
|
|
6137
|
+
const executable = deps.resolveExecutable?.() ?? resolveDaemonNodeExecutable();
|
|
6138
|
+
const child = spawnDaemonChild(executable, [paths.cliPath, "daemon"], {
|
|
5723
6139
|
detached: true,
|
|
5724
|
-
stdio: ["ignore", logFd, logFd]
|
|
6140
|
+
stdio: ["ignore", logFd, logFd],
|
|
6141
|
+
windowsHide: true,
|
|
6142
|
+
env: { ...process.env, BUN_BE_BUN: "1" }
|
|
5725
6143
|
});
|
|
5726
6144
|
child.once("spawn", () => closeSync2(logFd));
|
|
5727
6145
|
child.once("error", (error) => {
|
|
@@ -5735,10 +6153,10 @@ function spawnDaemonProcess(paths) {
|
|
|
5735
6153
|
throw error;
|
|
5736
6154
|
}
|
|
5737
6155
|
}
|
|
5738
|
-
function resolveDaemonNodeExecutable(cachedExecPath = execPath, originalArgv0 = argv0, pathExists =
|
|
6156
|
+
function resolveDaemonNodeExecutable(cachedExecPath = execPath, originalArgv0 = argv0, pathExists = existsSync12) {
|
|
5739
6157
|
if (pathExists(cachedExecPath))
|
|
5740
6158
|
return cachedExecPath;
|
|
5741
|
-
if (
|
|
6159
|
+
if (isAbsolute5(originalArgv0) && pathExists(originalArgv0))
|
|
5742
6160
|
return originalArgv0;
|
|
5743
6161
|
return "node";
|
|
5744
6162
|
}
|
|
@@ -5751,7 +6169,7 @@ function defaultEnsureDaemonDeps() {
|
|
|
5751
6169
|
};
|
|
5752
6170
|
}
|
|
5753
6171
|
function sleepWithSignal(ms, signal) {
|
|
5754
|
-
return new Promise((
|
|
6172
|
+
return new Promise((resolve) => {
|
|
5755
6173
|
let settled = false;
|
|
5756
6174
|
const finish = () => {
|
|
5757
6175
|
if (settled)
|
|
@@ -5759,7 +6177,7 @@ function sleepWithSignal(ms, signal) {
|
|
|
5759
6177
|
settled = true;
|
|
5760
6178
|
clearTimeout(timer);
|
|
5761
6179
|
signal?.removeEventListener("abort", finish);
|
|
5762
|
-
|
|
6180
|
+
resolve();
|
|
5763
6181
|
};
|
|
5764
6182
|
const timer = setTimeout(finish, ms);
|
|
5765
6183
|
if (signal?.aborted) {
|
|
@@ -5774,7 +6192,7 @@ function awaitWithSignal2(promise, signal) {
|
|
|
5774
6192
|
return promise;
|
|
5775
6193
|
if (signal.aborted)
|
|
5776
6194
|
return Promise.reject(abortError3(signal));
|
|
5777
|
-
return new Promise((
|
|
6195
|
+
return new Promise((resolve, reject) => {
|
|
5778
6196
|
let settled = false;
|
|
5779
6197
|
const finish = (run) => {
|
|
5780
6198
|
if (settled)
|
|
@@ -5785,7 +6203,7 @@ function awaitWithSignal2(promise, signal) {
|
|
|
5785
6203
|
};
|
|
5786
6204
|
const onAbort = () => finish(() => reject(abortError3(signal)));
|
|
5787
6205
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
5788
|
-
promise.then((value) => finish(() =>
|
|
6206
|
+
promise.then((value) => finish(() => resolve(value)), (error) => finish(() => reject(error)));
|
|
5789
6207
|
});
|
|
5790
6208
|
}
|
|
5791
6209
|
function throwIfAborted(signal) {
|
|
@@ -5814,18 +6232,18 @@ function parsePingResponse(message) {
|
|
|
5814
6232
|
return null;
|
|
5815
6233
|
if (!endpoint || typeof endpoint !== "object" || Array.isArray(endpoint))
|
|
5816
6234
|
return null;
|
|
5817
|
-
const
|
|
6235
|
+
const path = Reflect.get(endpoint, "path");
|
|
5818
6236
|
const kind = Reflect.get(endpoint, "kind");
|
|
5819
|
-
if (typeof
|
|
6237
|
+
if (typeof path !== "string")
|
|
5820
6238
|
return null;
|
|
5821
6239
|
if (kind === "windows")
|
|
5822
|
-
return { pid, nonce, startedAt, endpoint: { kind, path
|
|
6240
|
+
return { pid, nonce, startedAt, endpoint: { kind, path } };
|
|
5823
6241
|
if (kind === "missing")
|
|
5824
|
-
return { pid, nonce, startedAt, endpoint: { kind, path
|
|
6242
|
+
return { pid, nonce, startedAt, endpoint: { kind, path } };
|
|
5825
6243
|
const dev = Reflect.get(endpoint, "dev");
|
|
5826
6244
|
const ino = Reflect.get(endpoint, "ino");
|
|
5827
6245
|
if (kind === "unix" && typeof dev === "number" && typeof ino === "number") {
|
|
5828
|
-
return { pid, nonce, startedAt, endpoint: { kind, path
|
|
6246
|
+
return { pid, nonce, startedAt, endpoint: { kind, path, dev, ino } };
|
|
5829
6247
|
}
|
|
5830
6248
|
return null;
|
|
5831
6249
|
}
|
|
@@ -5834,7 +6252,10 @@ function parsePingResponse(message) {
|
|
|
5834
6252
|
var CONTEXT_KEY = "_context";
|
|
5835
6253
|
|
|
5836
6254
|
class InvalidDaemonRequestError extends Error {
|
|
5837
|
-
|
|
6255
|
+
constructor() {
|
|
6256
|
+
super(...arguments);
|
|
6257
|
+
this.name = "InvalidDaemonRequestError";
|
|
6258
|
+
}
|
|
5838
6259
|
}
|
|
5839
6260
|
function extractRequestContext(raw) {
|
|
5840
6261
|
if (!isPlainRecord(raw) || raw["method"] !== "tools/call")
|
|
@@ -5950,14 +6371,17 @@ async function callToolViaDaemon(name, args, options) {
|
|
|
5950
6371
|
function callDiagnosticsViaDaemon(filePath, options) {
|
|
5951
6372
|
return callToolViaDaemon("diagnostics", { filePath, severity: "error" }, options);
|
|
5952
6373
|
}
|
|
6374
|
+
function callFormatViaDaemon(filePath, options) {
|
|
6375
|
+
return callToolViaDaemon("format", { filePath }, options);
|
|
6376
|
+
}
|
|
5953
6377
|
function currentRequestContext(env = process.env) {
|
|
5954
6378
|
const cwd = process.cwd();
|
|
5955
6379
|
const home = env["HOME"] ?? homedir3();
|
|
5956
6380
|
return parseLspRequestContext({
|
|
5957
6381
|
cwd,
|
|
5958
|
-
projectConfigPaths: [
|
|
5959
|
-
userConfigPath:
|
|
5960
|
-
installDecisionsPath:
|
|
6382
|
+
projectConfigPaths: [join8(cwd, ".codex", "lsp-client.json")],
|
|
6383
|
+
userConfigPath: join8(home, ".codex", "lsp-client.json"),
|
|
6384
|
+
installDecisionsPath: join8(home, ".codex", "lsp-install-decisions.json"),
|
|
5961
6385
|
capabilities: { installDecisionTool: true }
|
|
5962
6386
|
});
|
|
5963
6387
|
}
|
|
@@ -5972,7 +6396,7 @@ function withContext(args, context) {
|
|
|
5972
6396
|
function ensureDaemonAvailable(paths, ensure, signal) {
|
|
5973
6397
|
if (!signal)
|
|
5974
6398
|
return ensure(paths);
|
|
5975
|
-
return new Promise((
|
|
6399
|
+
return new Promise((resolve, reject) => {
|
|
5976
6400
|
let settled = false;
|
|
5977
6401
|
const finish = (run) => {
|
|
5978
6402
|
if (settled)
|
|
@@ -5987,11 +6411,11 @@ function ensureDaemonAvailable(paths, ensure, signal) {
|
|
|
5987
6411
|
return;
|
|
5988
6412
|
}
|
|
5989
6413
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
5990
|
-
Promise.resolve().then(() => ensure(paths, signal)).then(() => finish(() =>
|
|
6414
|
+
Promise.resolve().then(() => ensure(paths, signal)).then(() => finish(() => resolve()), (error) => finish(() => reject(signal.aborted ? new DaemonRequestCancelledError(false) : error)));
|
|
5991
6415
|
});
|
|
5992
6416
|
}
|
|
5993
6417
|
function sendToolCall(paths, token, name, args, options) {
|
|
5994
|
-
return new Promise((
|
|
6418
|
+
return new Promise((resolve, reject) => {
|
|
5995
6419
|
const socket = connect(paths.socket);
|
|
5996
6420
|
const requestId = allocateProxyRequestId();
|
|
5997
6421
|
let settled = false;
|
|
@@ -6044,7 +6468,7 @@ function sendToolCall(paths, token, name, args, options) {
|
|
|
6044
6468
|
}
|
|
6045
6469
|
const result = toToolResult(message, requestId);
|
|
6046
6470
|
if (result)
|
|
6047
|
-
finish(() =>
|
|
6471
|
+
finish(() => resolve(result));
|
|
6048
6472
|
else
|
|
6049
6473
|
finish(() => reject(new DaemonRequestError("invalid daemon response", requestWritten)));
|
|
6050
6474
|
});
|
|
@@ -6212,18 +6636,18 @@ function canonicalizePathList(value) {
|
|
|
6212
6636
|
return value.split(delimiter4).map((entry) => canonicalizePath(entry) ?? entry).join(delimiter4);
|
|
6213
6637
|
}
|
|
6214
6638
|
function canonicalizePath(value) {
|
|
6215
|
-
if (value === undefined || !
|
|
6639
|
+
if (value === undefined || !isAbsolute6(value) || !existsSync13(value))
|
|
6216
6640
|
return value;
|
|
6217
|
-
return
|
|
6641
|
+
return realpathSync6(value);
|
|
6218
6642
|
}
|
|
6219
|
-
function projectRootFromOpenCodeConfigPath(
|
|
6220
|
-
if (basename4(
|
|
6643
|
+
function projectRootFromOpenCodeConfigPath(path) {
|
|
6644
|
+
if (basename4(path) !== "lsp.json" && basename4(path) !== "lsp-client.json")
|
|
6221
6645
|
return;
|
|
6222
|
-
const configDir =
|
|
6646
|
+
const configDir = dirname11(path);
|
|
6223
6647
|
const configDirName = basename4(configDir);
|
|
6224
6648
|
if (configDirName !== ".opencode" && configDirName !== ".omo")
|
|
6225
6649
|
return;
|
|
6226
|
-
return
|
|
6650
|
+
return dirname11(configDir);
|
|
6227
6651
|
}
|
|
6228
6652
|
|
|
6229
6653
|
// src/daemon-server.ts
|
|
@@ -6232,12 +6656,12 @@ import { createServer as createServer2 } from "node:net";
|
|
|
6232
6656
|
|
|
6233
6657
|
// src/ownership.ts
|
|
6234
6658
|
import { randomUUID } from "node:crypto";
|
|
6235
|
-
import { existsSync as
|
|
6236
|
-
import { dirname as
|
|
6659
|
+
import { existsSync as existsSync14, lstatSync as lstatSync7, readFileSync as readFileSync8, statSync as statSync5, unlinkSync as unlinkSync4 } from "node:fs";
|
|
6660
|
+
import { dirname as dirname13 } from "node:path";
|
|
6237
6661
|
|
|
6238
6662
|
// src/lock.ts
|
|
6239
|
-
import { closeSync as closeSync3, mkdirSync as mkdirSync4, openSync as openSync3, readFileSync as
|
|
6240
|
-
import { dirname as
|
|
6663
|
+
import { closeSync as closeSync3, mkdirSync as mkdirSync4, openSync as openSync3, readFileSync as readFileSync7, unlinkSync as unlinkSync3, writeSync as writeSync3 } from "node:fs";
|
|
6664
|
+
import { dirname as dirname12 } from "node:path";
|
|
6241
6665
|
function isProcessAlive2(pid) {
|
|
6242
6666
|
if (!Number.isInteger(pid) || pid <= 0)
|
|
6243
6667
|
return false;
|
|
@@ -6252,14 +6676,14 @@ function isProcessAlive2(pid) {
|
|
|
6252
6676
|
}
|
|
6253
6677
|
function readLockPid(lockPath) {
|
|
6254
6678
|
try {
|
|
6255
|
-
const pid = Number.parseInt(
|
|
6679
|
+
const pid = Number.parseInt(readFileSync7(lockPath, "utf8").trim(), 10);
|
|
6256
6680
|
return Number.isInteger(pid) ? pid : null;
|
|
6257
6681
|
} catch {
|
|
6258
6682
|
return null;
|
|
6259
6683
|
}
|
|
6260
6684
|
}
|
|
6261
6685
|
function tryAcquireLock(lockPath, ownerPid = process.pid) {
|
|
6262
|
-
mkdirSync4(
|
|
6686
|
+
mkdirSync4(dirname12(lockPath), { recursive: true });
|
|
6263
6687
|
for (let attempt = 0;attempt < 2; attempt += 1) {
|
|
6264
6688
|
const handle = writeLockFile(lockPath, ownerPid);
|
|
6265
6689
|
if (handle)
|
|
@@ -6289,9 +6713,9 @@ function reapStaleLock(lockPath) {
|
|
|
6289
6713
|
unlinkQuietly(lockPath);
|
|
6290
6714
|
return true;
|
|
6291
6715
|
}
|
|
6292
|
-
function unlinkQuietly(
|
|
6716
|
+
function unlinkQuietly(path) {
|
|
6293
6717
|
try {
|
|
6294
|
-
|
|
6718
|
+
unlinkSync3(path);
|
|
6295
6719
|
} catch (error) {
|
|
6296
6720
|
if (error instanceof Error)
|
|
6297
6721
|
return;
|
|
@@ -6307,17 +6731,19 @@ function errorCode3(error) {
|
|
|
6307
6731
|
|
|
6308
6732
|
// src/ownership.ts
|
|
6309
6733
|
class DaemonAlreadyRunningError extends Error {
|
|
6310
|
-
|
|
6311
|
-
|
|
6734
|
+
constructor() {
|
|
6735
|
+
super(...arguments);
|
|
6736
|
+
this.name = "DaemonAlreadyRunningError";
|
|
6737
|
+
this.code = "daemon_already_running";
|
|
6738
|
+
}
|
|
6312
6739
|
}
|
|
6313
6740
|
|
|
6314
6741
|
class DaemonStartupDeferredError extends Error {
|
|
6315
|
-
reason;
|
|
6316
|
-
name = "DaemonStartupDeferredError";
|
|
6317
|
-
code = "daemon_startup_deferred";
|
|
6318
6742
|
constructor(reason) {
|
|
6319
6743
|
super(`LSP daemon startup deferred: ${reason}`);
|
|
6320
6744
|
this.reason = reason;
|
|
6745
|
+
this.name = "DaemonStartupDeferredError";
|
|
6746
|
+
this.code = "daemon_startup_deferred";
|
|
6321
6747
|
}
|
|
6322
6748
|
}
|
|
6323
6749
|
async function acquireStartupLease(paths, pingOwner) {
|
|
@@ -6340,11 +6766,11 @@ async function acquireStartupLease(paths, pingOwner) {
|
|
|
6340
6766
|
function ensureDaemonDirectories(paths) {
|
|
6341
6767
|
ensurePrivateDirectory(paths.dir);
|
|
6342
6768
|
if (process.platform !== "win32")
|
|
6343
|
-
ensurePrivateDirectory(
|
|
6769
|
+
ensurePrivateDirectory(dirname13(paths.socket));
|
|
6344
6770
|
}
|
|
6345
6771
|
function readDaemonOwner(paths) {
|
|
6346
6772
|
try {
|
|
6347
|
-
return parseOwner(JSON.parse(
|
|
6773
|
+
return parseOwner(JSON.parse(readFileSync8(paths.owner, "utf8")));
|
|
6348
6774
|
} catch (error) {
|
|
6349
6775
|
if (error instanceof Error)
|
|
6350
6776
|
return null;
|
|
@@ -6409,8 +6835,7 @@ async function validateExistingOwner(paths, pingOwner) {
|
|
|
6409
6835
|
if (isProcessAlive2(owner.pid))
|
|
6410
6836
|
throw new DaemonStartupDeferredError("owner_pid_live_unreachable");
|
|
6411
6837
|
const reread = readDaemonOwner(paths);
|
|
6412
|
-
|
|
6413
|
-
if (!reread || reread.nonce !== owner.nonce || !sameEndpoint(endpoint, owner.endpoint)) {
|
|
6838
|
+
if (!reread || !sameOwner(reread, owner)) {
|
|
6414
6839
|
throw new DaemonStartupDeferredError("owner_changed_during_cleanup");
|
|
6415
6840
|
}
|
|
6416
6841
|
cleanupDeadOwner(paths, owner);
|
|
@@ -6420,10 +6845,10 @@ async function validateExistingOwner(paths, pingOwner) {
|
|
|
6420
6845
|
throw new DaemonStartupDeferredError("reachable_owner_mismatch");
|
|
6421
6846
|
}
|
|
6422
6847
|
function cleanupDeadOwner(paths, owner) {
|
|
6423
|
-
if (process.platform !== "win32" &&
|
|
6848
|
+
if (process.platform !== "win32" && existsSync14(owner.endpoint.path)) {
|
|
6424
6849
|
const stat = lstatSync7(owner.endpoint.path);
|
|
6425
6850
|
if (stat.isSocket())
|
|
6426
|
-
|
|
6851
|
+
unlinkSync4(owner.endpoint.path);
|
|
6427
6852
|
}
|
|
6428
6853
|
unlinkQuietly(paths.pid);
|
|
6429
6854
|
unlinkQuietly(paths.endpoint);
|
|
@@ -6452,26 +6877,26 @@ function parseEndpoint(value) {
|
|
|
6452
6877
|
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
6453
6878
|
return null;
|
|
6454
6879
|
const kind = Reflect.get(value, "kind");
|
|
6455
|
-
const
|
|
6456
|
-
if (typeof
|
|
6880
|
+
const path = Reflect.get(value, "path");
|
|
6881
|
+
if (typeof path !== "string")
|
|
6457
6882
|
return null;
|
|
6458
6883
|
if (kind === undefined)
|
|
6459
|
-
return endpointIdentity(
|
|
6884
|
+
return endpointIdentity(path);
|
|
6460
6885
|
if (kind === "windows")
|
|
6461
|
-
return { kind, path
|
|
6886
|
+
return { kind, path };
|
|
6462
6887
|
if (kind === "missing")
|
|
6463
|
-
return { kind, path
|
|
6888
|
+
return { kind, path };
|
|
6464
6889
|
const dev = Reflect.get(value, "dev");
|
|
6465
6890
|
const ino = Reflect.get(value, "ino");
|
|
6466
6891
|
if (kind === "unix" && typeof dev === "number" && typeof ino === "number")
|
|
6467
|
-
return { kind, path
|
|
6892
|
+
return { kind, path, dev, ino };
|
|
6468
6893
|
return null;
|
|
6469
6894
|
}
|
|
6470
6895
|
|
|
6471
6896
|
// src/version-reap.ts
|
|
6472
6897
|
import { execFile } from "node:child_process";
|
|
6473
6898
|
import { readdir, readFile, rm } from "node:fs/promises";
|
|
6474
|
-
import { basename as basename5, dirname as
|
|
6899
|
+
import { basename as basename5, dirname as dirname14, join as join9 } from "node:path";
|
|
6475
6900
|
var TERM_GRACE_MS = 5000;
|
|
6476
6901
|
var KILL_GRACE_MS = 1000;
|
|
6477
6902
|
var VERSION_ENTRY_PATTERN = /^v([A-Za-z0-9][A-Za-z0-9._+-]{0,127})$/;
|
|
@@ -6492,13 +6917,13 @@ async function attestDaemonCliProcess(pid, platform, deps = {}) {
|
|
|
6492
6917
|
return isNodeCliDaemonCommand(command.trim());
|
|
6493
6918
|
}
|
|
6494
6919
|
async function reapStaleDaemonVersions(ownPaths, deps = {}) {
|
|
6495
|
-
const baseDir =
|
|
6920
|
+
const baseDir = dirname14(ownPaths.dir);
|
|
6496
6921
|
const platform = deps.platform ?? process.platform;
|
|
6497
6922
|
const isAlive = deps.isAlive ?? isProcessAlive2;
|
|
6498
6923
|
const attest = deps.attest ?? ((pid) => attestDaemonCliProcess(pid, platform));
|
|
6499
6924
|
const sendSignal = deps.sendSignal ?? defaultSendSignal;
|
|
6500
6925
|
const waitForExit = deps.waitForExit ?? defaultWaitForExit;
|
|
6501
|
-
const removeDir = deps.removeDir ?? ((
|
|
6926
|
+
const removeDir = deps.removeDir ?? ((path) => rm(path, { recursive: true, force: true }));
|
|
6502
6927
|
const readOwner = deps.readOwner ?? readDaemonOwner;
|
|
6503
6928
|
const log = deps.log ?? defaultLog;
|
|
6504
6929
|
const termGraceMs = deps.termGraceMs ?? TERM_GRACE_MS;
|
|
@@ -6511,7 +6936,7 @@ async function reapStaleDaemonVersions(ownPaths, deps = {}) {
|
|
|
6511
6936
|
const version = parseVersionEntry(entry.name);
|
|
6512
6937
|
if (version === null || !entry.isDirectory())
|
|
6513
6938
|
continue;
|
|
6514
|
-
const versionDir =
|
|
6939
|
+
const versionDir = join9(baseDir, entry.name);
|
|
6515
6940
|
const siblingPaths = daemonPaths({ [OMO_LSP_DAEMON_DIR]: baseDir }, { cliPath: ownPaths.cliPath, version });
|
|
6516
6941
|
results.push(await reapOneVersion({
|
|
6517
6942
|
version,
|
|
@@ -6535,7 +6960,7 @@ async function reapOneVersion(context) {
|
|
|
6535
6960
|
const { version, versionDir } = context;
|
|
6536
6961
|
const owner = context.readOwner(context.siblingPaths);
|
|
6537
6962
|
if (!owner) {
|
|
6538
|
-
const lockPid = readLockPid(
|
|
6963
|
+
const lockPid = readLockPid(join9(versionDir, "daemon.lock"));
|
|
6539
6964
|
if (lockPid !== null && context.isAlive(lockPid)) {
|
|
6540
6965
|
context.log(`reap: sparing v${version}: owner metadata missing but daemon.lock is held by live pid ${lockPid}`);
|
|
6541
6966
|
return { version, status: "spared", reason: `owner metadata missing but lock held by live pid ${lockPid}` };
|
|
@@ -6609,17 +7034,17 @@ function isNodeCliDaemonArgv(argv) {
|
|
|
6609
7034
|
function isNodeCliDaemonCommand(command) {
|
|
6610
7035
|
return /\bnode(?:\.exe)?\b/i.test(command) && /\bcli\.js\b/.test(command) && /\bdaemon\b/.test(command);
|
|
6611
7036
|
}
|
|
6612
|
-
function defaultReadProcFile(
|
|
6613
|
-
return readFile(
|
|
7037
|
+
function defaultReadProcFile(path) {
|
|
7038
|
+
return readFile(path);
|
|
6614
7039
|
}
|
|
6615
7040
|
function defaultExecuteForStdout(file, args) {
|
|
6616
|
-
return new Promise((
|
|
6617
|
-
execFile(file, [...args], { encoding: "utf8", maxBuffer: 1024 * 1024, timeout: 1000 }, (error, stdout) => {
|
|
7041
|
+
return new Promise((resolve) => {
|
|
7042
|
+
execFile(file, [...args], { encoding: "utf8", maxBuffer: 1024 * 1024, timeout: 1000, windowsHide: true }, (error, stdout) => {
|
|
6618
7043
|
if (error !== null) {
|
|
6619
|
-
|
|
7044
|
+
resolve(null);
|
|
6620
7045
|
return;
|
|
6621
7046
|
}
|
|
6622
|
-
|
|
7047
|
+
resolve(stdout);
|
|
6623
7048
|
});
|
|
6624
7049
|
});
|
|
6625
7050
|
}
|
|
@@ -6638,7 +7063,7 @@ async function defaultWaitForExit(pid, timeoutMs) {
|
|
|
6638
7063
|
return true;
|
|
6639
7064
|
if (Date.now() >= deadline)
|
|
6640
7065
|
return false;
|
|
6641
|
-
await new Promise((
|
|
7066
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
6642
7067
|
}
|
|
6643
7068
|
}
|
|
6644
7069
|
function defaultLog(message) {
|
|
@@ -6659,7 +7084,7 @@ async function startDaemonServer(paths, options = {}) {
|
|
|
6659
7084
|
lastActiveAt = Date.now();
|
|
6660
7085
|
};
|
|
6661
7086
|
let routeOwner = lease.owner;
|
|
6662
|
-
const
|
|
7087
|
+
const server = createServer2((socket) => {
|
|
6663
7088
|
connections.add(socket);
|
|
6664
7089
|
const activeRequests = new Map;
|
|
6665
7090
|
touch();
|
|
@@ -6677,10 +7102,10 @@ async function startDaemonServer(paths, options = {}) {
|
|
|
6677
7102
|
touch();
|
|
6678
7103
|
});
|
|
6679
7104
|
});
|
|
6680
|
-
|
|
7105
|
+
server.on("error", (error) => logServerError(error));
|
|
6681
7106
|
let owner;
|
|
6682
7107
|
try {
|
|
6683
|
-
await listen(
|
|
7108
|
+
await listen(server, paths.socket);
|
|
6684
7109
|
if (process.platform !== "win32")
|
|
6685
7110
|
chmodSync2(paths.socket, 384);
|
|
6686
7111
|
owner = { ...lease.owner, endpoint: endpointIdentity(paths.socket) };
|
|
@@ -6702,7 +7127,7 @@ async function startDaemonServer(paths, options = {}) {
|
|
|
6702
7127
|
for (const socket of connections)
|
|
6703
7128
|
socket.destroy();
|
|
6704
7129
|
connections.clear();
|
|
6705
|
-
await closeServer(
|
|
7130
|
+
await closeServer(server);
|
|
6706
7131
|
removeDaemonMetadataForOwner(paths, owner);
|
|
6707
7132
|
await disposeDefaultLspManager();
|
|
6708
7133
|
};
|
|
@@ -6723,7 +7148,7 @@ async function startDaemonServer(paths, options = {}) {
|
|
|
6723
7148
|
}, idleCheckIntervalMs);
|
|
6724
7149
|
idleTimer.unref();
|
|
6725
7150
|
installSignalHandlers(close);
|
|
6726
|
-
return { server
|
|
7151
|
+
return { server, close };
|
|
6727
7152
|
}
|
|
6728
7153
|
async function respond(socket, message, token, owner, activeRequests) {
|
|
6729
7154
|
try {
|
|
@@ -6744,18 +7169,18 @@ async function assertSelfProbe(paths, token, owner) {
|
|
|
6744
7169
|
if (!ping || ping.nonce !== owner.nonce)
|
|
6745
7170
|
throw new DaemonStartupDeferredError("self_probe_failed");
|
|
6746
7171
|
}
|
|
6747
|
-
function listen(
|
|
6748
|
-
return new Promise((
|
|
7172
|
+
function listen(server, socketPath) {
|
|
7173
|
+
return new Promise((resolve, reject) => {
|
|
6749
7174
|
const onError = (error) => reject(error);
|
|
6750
|
-
|
|
6751
|
-
|
|
6752
|
-
|
|
6753
|
-
|
|
7175
|
+
server.once("error", onError);
|
|
7176
|
+
server.listen(socketPath, () => {
|
|
7177
|
+
server.removeListener("error", onError);
|
|
7178
|
+
resolve();
|
|
6754
7179
|
});
|
|
6755
7180
|
});
|
|
6756
7181
|
}
|
|
6757
|
-
function closeServer(
|
|
6758
|
-
return new Promise((
|
|
7182
|
+
function closeServer(server) {
|
|
7183
|
+
return new Promise((resolve) => server.close(() => resolve()));
|
|
6759
7184
|
}
|
|
6760
7185
|
function installSignalHandlers(close) {
|
|
6761
7186
|
const handler = () => {
|