oh-my-opencode 5.0.0-beta.8 → 5.0.0-beta.81
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 +59118 -63486
- 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 +58841 -63186
- 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/lifecycle-inline-spec.d.ts +1 -1
- 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 +34199 -28037
- package/dist/mcp/index.d.ts +0 -4
- package/dist/mcp/types.d.ts +0 -1
- package/dist/oh-my-opencode.schema.json +28 -59
- 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 +8 -3
- package/dist/skills/frontend/references/design/README.md +13 -4
- 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/design-system-architecture.md +1 -0
- package/dist/skills/frontend/references/design/interaction-skill.md +2 -0
- package/dist/skills/frontend/references/design/print-paged-media.md +76 -0
- package/dist/skills/frontend/references/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/references/perfection/README.md +1 -0
- 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 +22186 -30577
- package/package.json +51 -50
- 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 +1421 -960
- package/packages/lsp-daemon/dist/client.d.ts +10 -0
- package/packages/lsp-daemon/dist/client.js +956 -498
- package/packages/lsp-daemon/dist/daemon-client.d.ts +3 -0
- package/packages/lsp-daemon/dist/daemon-client.js +23 -3
- package/packages/lsp-daemon/dist/ensure-daemon.d.ts +6 -1
- package/packages/lsp-daemon/dist/ensure-daemon.js +27 -5
- package/packages/lsp-daemon/dist/index.js +860 -407
- 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 +5 -4
- 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 +5 -4
- 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 +8402 -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 +6 -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 +6 -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 +977 -545
- 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 +6 -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 +8 -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 +6 -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 +5328 -1382
- package/packages/omo-codex/plugin/components/telemetry/dist/posthog.js +5524 -1579
- package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/package.json +6 -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 +6 -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 +13 -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 +7 -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 +992 -681
- package/packages/omo-codex/plugin/package.json +6 -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 +8 -3
- package/packages/omo-codex/plugin/skills/frontend/references/design/README.md +13 -4
- 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/design-system-architecture.md +1 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/interaction-skill.md +2 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/print-paged-media.md +76 -0
- package/packages/omo-codex/plugin/skills/frontend/references/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/references/perfection/README.md +1 -0
- 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 +16149 -4304
- 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 +8 -3
- package/packages/shared-skills/skills/frontend/references/design/README.md +13 -4
- 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/design-system-architecture.md +1 -0
- package/packages/shared-skills/skills/frontend/references/design/interaction-skill.md +2 -0
- package/packages/shared-skills/skills/frontend/references/design/print-paged-media.md +76 -0
- package/packages/shared-skills/skills/frontend/references/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/references/perfection/README.md +1 -0
- 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
|
@@ -1,7 +1,12 @@
|
|
|
1
|
+
// src/client.ts
|
|
2
|
+
import { statSync as statSync5 } from "node:fs";
|
|
3
|
+
import { isAbsolute as isAbsolute6 } from "node:path";
|
|
4
|
+
|
|
1
5
|
// src/daemon-client.ts
|
|
2
6
|
import { connect } from "node:net";
|
|
3
7
|
import { homedir as homedir3 } from "node:os";
|
|
4
|
-
import { join as
|
|
8
|
+
import { join as join8 } from "node:path";
|
|
9
|
+
import { setTimeout as delay } from "node:timers/promises";
|
|
5
10
|
|
|
6
11
|
// ../lsp-core/src/request-context.ts
|
|
7
12
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
@@ -10,18 +15,17 @@ import { homedir } from "node:os";
|
|
|
10
15
|
import { basename, delimiter, dirname, isAbsolute, join, relative, resolve } from "node:path";
|
|
11
16
|
|
|
12
17
|
class LspRequestContextParseError extends Error {
|
|
13
|
-
code;
|
|
14
|
-
name = "LspRequestContextParseError";
|
|
15
18
|
constructor(code, message) {
|
|
16
19
|
super(message);
|
|
17
20
|
this.code = code;
|
|
21
|
+
this.name = "LspRequestContextParseError";
|
|
18
22
|
}
|
|
19
23
|
}
|
|
20
24
|
|
|
21
25
|
class LspRequestContextUnavailableError extends Error {
|
|
22
|
-
name = "LspRequestContextUnavailableError";
|
|
23
26
|
constructor() {
|
|
24
27
|
super("LSP request context is required. Standalone MCP startup must install one with runWithRequestContext(createStandaloneMcpRequestContext()).");
|
|
28
|
+
this.name = "LspRequestContextUnavailableError";
|
|
25
29
|
}
|
|
26
30
|
}
|
|
27
31
|
var storage = new AsyncLocalStorage;
|
|
@@ -41,7 +45,7 @@ function contextCwd() {
|
|
|
41
45
|
}
|
|
42
46
|
function createStandaloneMcpRequestContext(input = {}) {
|
|
43
47
|
const env = input.env ?? process.env;
|
|
44
|
-
const cwd = canonicalCwd(input.cwd ?? process.cwd());
|
|
48
|
+
const cwd = canonicalCwd(input.cwd ?? env["LSP_TOOLS_MCP_CWD"] ?? process.cwd());
|
|
45
49
|
const home = input.homeDir ?? homedir();
|
|
46
50
|
const projectConfigPaths = translateProjectConfigEnv(env["LSP_TOOLS_MCP_PROJECT_CONFIG"], cwd);
|
|
47
51
|
const userConfigPath = translateHomeConfigEnv(env["LSP_TOOLS_MCP_USER_CONFIG"], home, ".codex/lsp-client.json");
|
|
@@ -179,7 +183,6 @@ function isPlainRecord(value) {
|
|
|
179
183
|
|
|
180
184
|
// src/daemon-request-error.ts
|
|
181
185
|
class DaemonRequestError extends Error {
|
|
182
|
-
requestWritten;
|
|
183
186
|
constructor(message, requestWritten) {
|
|
184
187
|
super(message);
|
|
185
188
|
this.name = "DaemonRequestError";
|
|
@@ -202,7 +205,6 @@ class DaemonRequestCancelledError extends DaemonRequestError {
|
|
|
202
205
|
}
|
|
203
206
|
|
|
204
207
|
class DaemonRequestTimedOutError extends DaemonRequestError {
|
|
205
|
-
timeoutMs;
|
|
206
208
|
constructor(requestWritten, timeoutMs) {
|
|
207
209
|
super("daemon request timed out", requestWritten);
|
|
208
210
|
this.name = "DaemonRequestTimedOutError";
|
|
@@ -281,14 +283,12 @@ var PROTOCOL_ERROR_CODE = -32002;
|
|
|
281
283
|
var AUTH_TOKEN_BYTES = 32;
|
|
282
284
|
|
|
283
285
|
class UnsafePrivateDirectoryError extends Error {
|
|
284
|
-
path;
|
|
285
|
-
reason;
|
|
286
|
-
name = "UnsafePrivateDirectoryError";
|
|
287
|
-
code = "unsafe_private_directory";
|
|
288
286
|
constructor(path, reason) {
|
|
289
287
|
super(`unsafe private directory ${path}: ${reason}`);
|
|
290
288
|
this.path = path;
|
|
291
289
|
this.reason = reason;
|
|
290
|
+
this.name = "UnsafePrivateDirectoryError";
|
|
291
|
+
this.code = "unsafe_private_directory";
|
|
292
292
|
}
|
|
293
293
|
}
|
|
294
294
|
function authEnvelope(token) {
|
|
@@ -472,20 +472,18 @@ var OMO_LSP_DAEMON_VERSION = "OMO_LSP_DAEMON_VERSION";
|
|
|
472
472
|
var DAEMON_VERSION_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._+-]{0,127}$/;
|
|
473
473
|
|
|
474
474
|
class InvalidRuntimeOverrideError extends Error {
|
|
475
|
-
code = "invalid_runtime_override";
|
|
476
|
-
reason;
|
|
477
475
|
constructor(reason, message) {
|
|
478
476
|
super(message);
|
|
477
|
+
this.code = "invalid_runtime_override";
|
|
479
478
|
this.name = "InvalidRuntimeOverrideError";
|
|
480
479
|
this.reason = reason;
|
|
481
480
|
}
|
|
482
481
|
}
|
|
483
482
|
|
|
484
483
|
class InvalidDaemonVersionError extends Error {
|
|
485
|
-
code = "invalid_daemon_version";
|
|
486
|
-
version;
|
|
487
484
|
constructor(version) {
|
|
488
485
|
super("LSP daemon version must match [A-Za-z0-9][A-Za-z0-9._+-]{0,127}");
|
|
486
|
+
this.code = "invalid_daemon_version";
|
|
489
487
|
this.name = "InvalidDaemonVersionError";
|
|
490
488
|
this.version = version;
|
|
491
489
|
}
|
|
@@ -531,10 +529,9 @@ var requireFromHere = createRequire(import.meta.url);
|
|
|
531
529
|
var MAX_SOCKET_PATH_LENGTH = 100;
|
|
532
530
|
|
|
533
531
|
class InvalidDaemonDirectoryError extends Error {
|
|
534
|
-
code = "invalid_daemon_directory";
|
|
535
|
-
directory;
|
|
536
532
|
constructor(directory) {
|
|
537
533
|
super(`${OMO_LSP_DAEMON_DIR} must be an absolute path`);
|
|
534
|
+
this.code = "invalid_daemon_directory";
|
|
538
535
|
this.name = "InvalidDaemonDirectoryError";
|
|
539
536
|
this.directory = directory;
|
|
540
537
|
}
|
|
@@ -649,9 +646,11 @@ function createLineDecoder(onMessage, onParseError) {
|
|
|
649
646
|
}
|
|
650
647
|
|
|
651
648
|
// src/ensure-daemon.ts
|
|
652
|
-
var PROBE_TIMEOUT_MS =
|
|
649
|
+
var PROBE_TIMEOUT_MS = 2000;
|
|
653
650
|
var DEFAULT_READY_TIMEOUT_MS = 5000;
|
|
654
651
|
var DEFAULT_POLL_INTERVAL_MS = 100;
|
|
652
|
+
var FAILED_SPAWN_COOLDOWN_MS = 5000;
|
|
653
|
+
var failedSpawnUntil = new Map;
|
|
655
654
|
|
|
656
655
|
class DaemonUnreachableError extends Error {
|
|
657
656
|
constructor(socketPath) {
|
|
@@ -664,11 +663,22 @@ async function ensureDaemonRunning(paths, deps = defaultEnsureDaemonDeps(), opti
|
|
|
664
663
|
const pollIntervalMs = options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;
|
|
665
664
|
const signal = options.signal;
|
|
666
665
|
throwIfAborted(signal);
|
|
667
|
-
if (await awaitWithSignal(deps.probe(paths, signal), signal))
|
|
666
|
+
if (await awaitWithSignal(deps.probe(paths, signal), signal)) {
|
|
667
|
+
failedSpawnUntil.delete(paths.socket);
|
|
668
668
|
return;
|
|
669
|
+
}
|
|
669
670
|
throwIfAborted(signal);
|
|
671
|
+
const retryAt = failedSpawnUntil.get(paths.socket);
|
|
672
|
+
if (retryAt !== undefined && deps.now() < retryAt)
|
|
673
|
+
throw new DaemonUnreachableError(paths.socket);
|
|
674
|
+
failedSpawnUntil.delete(paths.socket);
|
|
670
675
|
deps.spawnDaemon(paths);
|
|
671
|
-
|
|
676
|
+
try {
|
|
677
|
+
await waitUntilReachable(paths, deps, readyTimeoutMs, pollIntervalMs, signal);
|
|
678
|
+
} catch (error) {
|
|
679
|
+
failedSpawnUntil.set(paths.socket, deps.now() + FAILED_SPAWN_COOLDOWN_MS);
|
|
680
|
+
throw error;
|
|
681
|
+
}
|
|
672
682
|
}
|
|
673
683
|
async function waitUntilReachable(paths, deps, readyTimeoutMs, pollIntervalMs, signal) {
|
|
674
684
|
const deadline = deps.now() + readyTimeoutMs;
|
|
@@ -688,7 +698,7 @@ async function probeDaemon(paths, timeoutMs = PROBE_TIMEOUT_MS, signal) {
|
|
|
688
698
|
return await pingDaemon(paths, token, timeoutMs, signal) !== null;
|
|
689
699
|
}
|
|
690
700
|
function pingDaemon(paths, token, timeoutMs = PROBE_TIMEOUT_MS, signal) {
|
|
691
|
-
return new Promise((
|
|
701
|
+
return new Promise((resolve) => {
|
|
692
702
|
const socket = new Socket;
|
|
693
703
|
let settled = false;
|
|
694
704
|
let timer;
|
|
@@ -700,7 +710,7 @@ function pingDaemon(paths, token, timeoutMs = PROBE_TIMEOUT_MS, signal) {
|
|
|
700
710
|
clearTimeout(timer);
|
|
701
711
|
signal?.removeEventListener("abort", onAbort);
|
|
702
712
|
socket.destroy();
|
|
703
|
-
|
|
713
|
+
resolve(value);
|
|
704
714
|
};
|
|
705
715
|
const onAbort = () => finish(null);
|
|
706
716
|
const decoder = createLineDecoder((message) => {
|
|
@@ -723,13 +733,17 @@ function pingDaemon(paths, token, timeoutMs = PROBE_TIMEOUT_MS, signal) {
|
|
|
723
733
|
socket.connect(paths.socket);
|
|
724
734
|
});
|
|
725
735
|
}
|
|
726
|
-
function spawnDaemonProcess(paths) {
|
|
736
|
+
function spawnDaemonProcess(paths, deps = {}) {
|
|
727
737
|
mkdirSync2(dirname3(paths.log), { recursive: true });
|
|
728
738
|
const logFd = openSync2(paths.log, "a");
|
|
729
739
|
try {
|
|
730
|
-
const
|
|
740
|
+
const spawnDaemonChild = deps.spawn ?? spawn;
|
|
741
|
+
const executable = deps.resolveExecutable?.() ?? resolveDaemonNodeExecutable();
|
|
742
|
+
const child = spawnDaemonChild(executable, [paths.cliPath, "daemon"], {
|
|
731
743
|
detached: true,
|
|
732
|
-
stdio: ["ignore", logFd, logFd]
|
|
744
|
+
stdio: ["ignore", logFd, logFd],
|
|
745
|
+
windowsHide: true,
|
|
746
|
+
env: { ...process.env, BUN_BE_BUN: "1" }
|
|
733
747
|
});
|
|
734
748
|
child.once("spawn", () => closeSync2(logFd));
|
|
735
749
|
child.once("error", (error) => {
|
|
@@ -759,7 +773,7 @@ function defaultEnsureDaemonDeps() {
|
|
|
759
773
|
};
|
|
760
774
|
}
|
|
761
775
|
function sleepWithSignal(ms, signal) {
|
|
762
|
-
return new Promise((
|
|
776
|
+
return new Promise((resolve) => {
|
|
763
777
|
let settled = false;
|
|
764
778
|
const finish = () => {
|
|
765
779
|
if (settled)
|
|
@@ -767,7 +781,7 @@ function sleepWithSignal(ms, signal) {
|
|
|
767
781
|
settled = true;
|
|
768
782
|
clearTimeout(timer);
|
|
769
783
|
signal?.removeEventListener("abort", finish);
|
|
770
|
-
|
|
784
|
+
resolve();
|
|
771
785
|
};
|
|
772
786
|
const timer = setTimeout(finish, ms);
|
|
773
787
|
if (signal?.aborted) {
|
|
@@ -782,7 +796,7 @@ function awaitWithSignal(promise, signal) {
|
|
|
782
796
|
return promise;
|
|
783
797
|
if (signal.aborted)
|
|
784
798
|
return Promise.reject(abortError(signal));
|
|
785
|
-
return new Promise((
|
|
799
|
+
return new Promise((resolve, reject) => {
|
|
786
800
|
let settled = false;
|
|
787
801
|
const finish = (run) => {
|
|
788
802
|
if (settled)
|
|
@@ -793,7 +807,7 @@ function awaitWithSignal(promise, signal) {
|
|
|
793
807
|
};
|
|
794
808
|
const onAbort = () => finish(() => reject(abortError(signal)));
|
|
795
809
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
796
|
-
promise.then((value) => finish(() =>
|
|
810
|
+
promise.then((value) => finish(() => resolve(value)), (error) => finish(() => reject(error)));
|
|
797
811
|
});
|
|
798
812
|
}
|
|
799
813
|
function throwIfAborted(signal) {
|
|
@@ -822,18 +836,18 @@ function parsePingResponse(message) {
|
|
|
822
836
|
return null;
|
|
823
837
|
if (!endpoint || typeof endpoint !== "object" || Array.isArray(endpoint))
|
|
824
838
|
return null;
|
|
825
|
-
const
|
|
839
|
+
const path = Reflect.get(endpoint, "path");
|
|
826
840
|
const kind = Reflect.get(endpoint, "kind");
|
|
827
|
-
if (typeof
|
|
841
|
+
if (typeof path !== "string")
|
|
828
842
|
return null;
|
|
829
843
|
if (kind === "windows")
|
|
830
|
-
return { pid, nonce, startedAt, endpoint: { kind, path
|
|
844
|
+
return { pid, nonce, startedAt, endpoint: { kind, path } };
|
|
831
845
|
if (kind === "missing")
|
|
832
|
-
return { pid, nonce, startedAt, endpoint: { kind, path
|
|
846
|
+
return { pid, nonce, startedAt, endpoint: { kind, path } };
|
|
833
847
|
const dev = Reflect.get(endpoint, "dev");
|
|
834
848
|
const ino = Reflect.get(endpoint, "ino");
|
|
835
849
|
if (kind === "unix" && typeof dev === "number" && typeof ino === "number") {
|
|
836
|
-
return { pid, nonce, startedAt, endpoint: { kind, path
|
|
850
|
+
return { pid, nonce, startedAt, endpoint: { kind, path, dev, ino } };
|
|
837
851
|
}
|
|
838
852
|
return null;
|
|
839
853
|
}
|
|
@@ -881,7 +895,7 @@ ${body}` : `${body}
|
|
|
881
895
|
await writeChunk(output, payload);
|
|
882
896
|
}
|
|
883
897
|
function writeChunk(output, chunk) {
|
|
884
|
-
return new Promise((
|
|
898
|
+
return new Promise((resolve, reject) => {
|
|
885
899
|
let settled = false;
|
|
886
900
|
const onError = (error) => {
|
|
887
901
|
if (settled)
|
|
@@ -901,7 +915,7 @@ function writeChunk(output, chunk) {
|
|
|
901
915
|
return;
|
|
902
916
|
}
|
|
903
917
|
output.removeListener("error", onError);
|
|
904
|
-
|
|
918
|
+
resolve();
|
|
905
919
|
});
|
|
906
920
|
} catch (error) {
|
|
907
921
|
output.removeListener("error", onError);
|
|
@@ -1010,6 +1024,7 @@ async function runJsonRpcStdioServer(config) {
|
|
|
1010
1024
|
const idleTimer = createIdleTimer(idleTimeoutMs, log, () => {
|
|
1011
1025
|
isClosed = true;
|
|
1012
1026
|
config.onIdleTimeout?.();
|
|
1027
|
+
config.input.destroy();
|
|
1013
1028
|
});
|
|
1014
1029
|
const watchdog = createParentWatchdog(config.parentWatchdog, (parentPid, pollIntervalMs) => {
|
|
1015
1030
|
isClosed = true;
|
|
@@ -1106,7 +1121,11 @@ function createParentWatchdog(config, onDeadParent) {
|
|
|
1106
1121
|
const probeAlive = config.probeAlive ?? isProcessAlive;
|
|
1107
1122
|
let fired = false;
|
|
1108
1123
|
const timer = setInterval(() => {
|
|
1109
|
-
if (fired
|
|
1124
|
+
if (fired)
|
|
1125
|
+
return;
|
|
1126
|
+
const alive = probeAlive(parentPid);
|
|
1127
|
+
config.onPoll?.(alive);
|
|
1128
|
+
if (alive)
|
|
1110
1129
|
return;
|
|
1111
1130
|
fired = true;
|
|
1112
1131
|
onDeadParent(parentPid, pollIntervalMs);
|
|
@@ -1141,8 +1160,8 @@ function createIdleTimer(idleTimeoutMs, log, onTimeout) {
|
|
|
1141
1160
|
};
|
|
1142
1161
|
}
|
|
1143
1162
|
// ../lsp-core/src/lsp/client-wrapper.ts
|
|
1144
|
-
import { existsSync as
|
|
1145
|
-
import { basename as basename3, dirname as
|
|
1163
|
+
import { existsSync as existsSync11, realpathSync as realpathSync5, statSync as statSync4 } from "node:fs";
|
|
1164
|
+
import { basename as basename3, dirname as dirname10, join as join5, resolve as resolve8 } from "node:path";
|
|
1146
1165
|
|
|
1147
1166
|
// ../lsp-core/src/lsp/effective-extension.ts
|
|
1148
1167
|
import { basename as basename2, extname } from "node:path";
|
|
@@ -1156,22 +1175,15 @@ function effectiveExtension(filePath) {
|
|
|
1156
1175
|
|
|
1157
1176
|
// ../lsp-core/src/lsp/errors.ts
|
|
1158
1177
|
class LspConnectionClosedError extends Error {
|
|
1159
|
-
serverId;
|
|
1160
|
-
root;
|
|
1161
|
-
name = "LspConnectionClosedError";
|
|
1162
1178
|
constructor(serverId, root, message) {
|
|
1163
1179
|
super(message ?? `LSP connection closed for ${serverId} at ${root}`);
|
|
1164
1180
|
this.serverId = serverId;
|
|
1165
1181
|
this.root = root;
|
|
1182
|
+
this.name = "LspConnectionClosedError";
|
|
1166
1183
|
}
|
|
1167
1184
|
}
|
|
1168
1185
|
|
|
1169
1186
|
class LspProcessExitedError extends Error {
|
|
1170
|
-
serverId;
|
|
1171
|
-
root;
|
|
1172
|
-
exitCode;
|
|
1173
|
-
stderrTail;
|
|
1174
|
-
name = "LspProcessExitedError";
|
|
1175
1187
|
constructor(serverId, root, exitCode, stderrTail) {
|
|
1176
1188
|
const stderrSuffix = stderrTail ? `
|
|
1177
1189
|
stderr tail: ${stderrTail}` : "";
|
|
@@ -1180,46 +1192,59 @@ stderr tail: ${stderrTail}` : "";
|
|
|
1180
1192
|
this.root = root;
|
|
1181
1193
|
this.exitCode = exitCode;
|
|
1182
1194
|
this.stderrTail = stderrTail;
|
|
1195
|
+
this.name = "LspProcessExitedError";
|
|
1183
1196
|
}
|
|
1184
1197
|
}
|
|
1185
1198
|
|
|
1186
1199
|
class LspRequestTimeoutError extends Error {
|
|
1187
|
-
method;
|
|
1188
|
-
stderrTail;
|
|
1189
|
-
name = "LspRequestTimeoutError";
|
|
1190
1200
|
constructor(method, stderrTail) {
|
|
1191
1201
|
const stderrSuffix = stderrTail ? `
|
|
1192
1202
|
recent stderr: ${stderrTail}` : "";
|
|
1193
1203
|
super(`LSP request timeout (method: ${method})${stderrSuffix}`);
|
|
1194
1204
|
this.method = method;
|
|
1195
1205
|
this.stderrTail = stderrTail;
|
|
1206
|
+
this.name = "LspRequestTimeoutError";
|
|
1196
1207
|
}
|
|
1197
1208
|
}
|
|
1198
1209
|
|
|
1199
1210
|
class LspInvalidPathError extends Error {
|
|
1200
|
-
|
|
1211
|
+
constructor() {
|
|
1212
|
+
super(...arguments);
|
|
1213
|
+
this.name = "LspInvalidPathError";
|
|
1214
|
+
}
|
|
1201
1215
|
}
|
|
1202
1216
|
|
|
1203
1217
|
class LspServerLookupError extends Error {
|
|
1204
|
-
lookup;
|
|
1205
|
-
name = "LspServerLookupError";
|
|
1206
1218
|
constructor(message, lookup) {
|
|
1207
1219
|
super(message);
|
|
1208
1220
|
this.lookup = lookup;
|
|
1221
|
+
this.name = "LspServerLookupError";
|
|
1209
1222
|
}
|
|
1210
1223
|
}
|
|
1211
1224
|
|
|
1212
1225
|
class LspServerInitializingError extends Error {
|
|
1213
|
-
originalError;
|
|
1214
|
-
name = "LspServerInitializingError";
|
|
1215
1226
|
constructor(originalError) {
|
|
1216
1227
|
super(`LSP server is still initializing. Please retry in a few seconds. Original error: ${originalError.message}`);
|
|
1217
1228
|
this.originalError = originalError;
|
|
1229
|
+
this.name = "LspServerInitializingError";
|
|
1218
1230
|
}
|
|
1219
1231
|
}
|
|
1220
1232
|
|
|
1221
1233
|
class LspProcessSpawnError extends Error {
|
|
1222
|
-
|
|
1234
|
+
constructor() {
|
|
1235
|
+
super(...arguments);
|
|
1236
|
+
this.name = "LspProcessSpawnError";
|
|
1237
|
+
}
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1240
|
+
class LspClientRespawnBudgetExceededError extends Error {
|
|
1241
|
+
constructor(serverId, root, retryLimit) {
|
|
1242
|
+
super(`LSP server ${serverId} at ${root} failed to stay alive; respawn budget exhausted ` + `(${retryLimit} consecutive dead generations). Retrying after the cooldown may succeed.`);
|
|
1243
|
+
this.serverId = serverId;
|
|
1244
|
+
this.root = root;
|
|
1245
|
+
this.retryLimit = retryLimit;
|
|
1246
|
+
this.name = "LspClientRespawnBudgetExceededError";
|
|
1247
|
+
}
|
|
1223
1248
|
}
|
|
1224
1249
|
function isLspDeadConnectionError(err) {
|
|
1225
1250
|
return err instanceof LspConnectionClosedError || err instanceof LspProcessExitedError;
|
|
@@ -1242,6 +1267,13 @@ import { pathToFileURL as pathToFileURL3 } from "node:url";
|
|
|
1242
1267
|
// ../lsp-core/src/lsp/connection.ts
|
|
1243
1268
|
import { pathToFileURL } from "node:url";
|
|
1244
1269
|
|
|
1270
|
+
// ../lsp-core/src/lsp/timer-provider.ts
|
|
1271
|
+
var realTimerProvider = {
|
|
1272
|
+
now: () => Date.now(),
|
|
1273
|
+
setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
|
|
1274
|
+
clearTimeout: (handle) => clearTimeout(handle)
|
|
1275
|
+
};
|
|
1276
|
+
|
|
1245
1277
|
// ../lsp-core/src/lsp/constants.ts
|
|
1246
1278
|
var DEFAULT_MAX_REFERENCES = 200;
|
|
1247
1279
|
var DEFAULT_MAX_SYMBOLS = 200;
|
|
@@ -1250,9 +1282,12 @@ var DEFAULT_MAX_DIRECTORY_FILES = 50;
|
|
|
1250
1282
|
var REQUEST_TIMEOUT_MS = 15000;
|
|
1251
1283
|
var INIT_TIMEOUT_MS = 60000;
|
|
1252
1284
|
var IDLE_TIMEOUT_MS = 5 * 60000;
|
|
1285
|
+
var MAX_RESIDENT_CLIENTS = 6;
|
|
1253
1286
|
var REAPER_INTERVAL_MS = 60000;
|
|
1254
1287
|
var STOP_HARD_KILL_TIMEOUT_MS = 5000;
|
|
1255
1288
|
var STOP_SIGKILL_GRACE_MS = 1000;
|
|
1289
|
+
var CLIENT_RESPAWN_RETRY_LIMIT = 2;
|
|
1290
|
+
var CLIENT_RESPAWN_COOLDOWN_MS = 60000;
|
|
1256
1291
|
|
|
1257
1292
|
// ../lsp-core/src/lsp/json-rpc-connection.ts
|
|
1258
1293
|
var HEADER_SEPARATOR2 = `\r
|
|
@@ -1264,20 +1299,31 @@ var METHOD_NOT_FOUND = -32601;
|
|
|
1264
1299
|
var INTERNAL_ERROR = -32603;
|
|
1265
1300
|
|
|
1266
1301
|
class JsonRpcConnection {
|
|
1267
|
-
reader;
|
|
1268
|
-
writer;
|
|
1269
|
-
pendingRequests = new Map;
|
|
1270
|
-
notificationHandlers = new Map;
|
|
1271
|
-
requestHandlers = new Map;
|
|
1272
|
-
closeHandlers = [];
|
|
1273
|
-
errorHandlers = [];
|
|
1274
|
-
inputBuffer = Buffer.alloc(0);
|
|
1275
|
-
nextRequestId = 1;
|
|
1276
|
-
listening = false;
|
|
1277
|
-
disposed = false;
|
|
1278
1302
|
constructor(reader, writer) {
|
|
1279
1303
|
this.reader = reader;
|
|
1280
1304
|
this.writer = writer;
|
|
1305
|
+
this.pendingRequests = new Map;
|
|
1306
|
+
this.notificationHandlers = new Map;
|
|
1307
|
+
this.requestHandlers = new Map;
|
|
1308
|
+
this.closeHandlers = [];
|
|
1309
|
+
this.errorHandlers = [];
|
|
1310
|
+
this.inputBuffer = Buffer.alloc(0);
|
|
1311
|
+
this.nextRequestId = 1;
|
|
1312
|
+
this.listening = false;
|
|
1313
|
+
this.disposed = false;
|
|
1314
|
+
this.handleData = (chunk) => {
|
|
1315
|
+
const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
|
|
1316
|
+
this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
|
|
1317
|
+
this.drainInputBuffer();
|
|
1318
|
+
};
|
|
1319
|
+
this.handleClose = () => {
|
|
1320
|
+
for (const handler of this.closeHandlers) {
|
|
1321
|
+
handler();
|
|
1322
|
+
}
|
|
1323
|
+
};
|
|
1324
|
+
this.handleStreamError = (error) => {
|
|
1325
|
+
this.emitError(error);
|
|
1326
|
+
};
|
|
1281
1327
|
}
|
|
1282
1328
|
listen() {
|
|
1283
1329
|
if (this.listening)
|
|
@@ -1312,7 +1358,8 @@ class JsonRpcConnection {
|
|
|
1312
1358
|
let cancelAfterWrite = false;
|
|
1313
1359
|
let settled = false;
|
|
1314
1360
|
const writeCancel = () => this.writeMessage({ jsonrpc: "2.0", method: "$/cancelRequest", params: { id } });
|
|
1315
|
-
|
|
1361
|
+
let rejectAfterCancelWrite;
|
|
1362
|
+
const responsePromise = new Promise((resolve, reject) => {
|
|
1316
1363
|
const cleanup = () => {
|
|
1317
1364
|
options.signal?.removeEventListener("abort", onAbort);
|
|
1318
1365
|
};
|
|
@@ -1323,22 +1370,26 @@ class JsonRpcConnection {
|
|
|
1323
1370
|
this.pendingRequests.delete(key);
|
|
1324
1371
|
cleanup();
|
|
1325
1372
|
const rejectCancelled = () => reject(abortError2(options.signal));
|
|
1373
|
+
rejectAfterCancelWrite = async () => {
|
|
1374
|
+
try {
|
|
1375
|
+
await writeCancel();
|
|
1376
|
+
} catch (error) {
|
|
1377
|
+
this.emitError(toError(error));
|
|
1378
|
+
}
|
|
1379
|
+
rejectCancelled();
|
|
1380
|
+
};
|
|
1326
1381
|
if (!requestWritten) {
|
|
1327
1382
|
cancelAfterWrite = true;
|
|
1328
|
-
rejectCancelled();
|
|
1329
1383
|
return;
|
|
1330
1384
|
}
|
|
1331
|
-
|
|
1332
|
-
this.emitError(toError(error));
|
|
1333
|
-
rejectCancelled();
|
|
1334
|
-
});
|
|
1385
|
+
rejectAfterCancelWrite();
|
|
1335
1386
|
};
|
|
1336
1387
|
const onAbort = () => settleCancel();
|
|
1337
1388
|
this.pendingRequests.set(key, {
|
|
1338
1389
|
resolve(result) {
|
|
1339
1390
|
settled = true;
|
|
1340
1391
|
cleanup();
|
|
1341
|
-
|
|
1392
|
+
resolve(result);
|
|
1342
1393
|
},
|
|
1343
1394
|
reject(error) {
|
|
1344
1395
|
settled = true;
|
|
@@ -1359,7 +1410,7 @@ class JsonRpcConnection {
|
|
|
1359
1410
|
await this.writeMessage(message);
|
|
1360
1411
|
requestWritten = true;
|
|
1361
1412
|
if (cancelAfterWrite)
|
|
1362
|
-
await
|
|
1413
|
+
await rejectAfterCancelWrite?.();
|
|
1363
1414
|
} catch (error) {
|
|
1364
1415
|
if (settled)
|
|
1365
1416
|
return responsePromise;
|
|
@@ -1398,19 +1449,6 @@ class JsonRpcConnection {
|
|
|
1398
1449
|
this.notificationHandlers.clear();
|
|
1399
1450
|
this.requestHandlers.clear();
|
|
1400
1451
|
}
|
|
1401
|
-
handleData = (chunk) => {
|
|
1402
|
-
const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
|
|
1403
|
-
this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
|
|
1404
|
-
this.drainInputBuffer();
|
|
1405
|
-
};
|
|
1406
|
-
handleClose = () => {
|
|
1407
|
-
for (const handler of this.closeHandlers) {
|
|
1408
|
-
handler();
|
|
1409
|
-
}
|
|
1410
|
-
};
|
|
1411
|
-
handleStreamError = (error) => {
|
|
1412
|
-
this.emitError(error);
|
|
1413
|
-
};
|
|
1414
1452
|
drainInputBuffer() {
|
|
1415
1453
|
while (true) {
|
|
1416
1454
|
const headerEnd = this.inputBuffer.indexOf(HEADER_SEPARATOR2);
|
|
@@ -1510,13 +1548,13 @@ class JsonRpcConnection {
|
|
|
1510
1548
|
const payload = `Content-Length: ${Buffer.byteLength(body, "utf8")}\r
|
|
1511
1549
|
\r
|
|
1512
1550
|
${body}`;
|
|
1513
|
-
return new Promise((
|
|
1551
|
+
return new Promise((resolve, reject) => {
|
|
1514
1552
|
this.writer.write(payload, (error) => {
|
|
1515
1553
|
if (error) {
|
|
1516
1554
|
reject(error);
|
|
1517
1555
|
return;
|
|
1518
1556
|
}
|
|
1519
|
-
|
|
1557
|
+
resolve();
|
|
1520
1558
|
});
|
|
1521
1559
|
});
|
|
1522
1560
|
}
|
|
@@ -1603,9 +1641,9 @@ function validateCwd(cwd) {
|
|
|
1603
1641
|
}
|
|
1604
1642
|
}
|
|
1605
1643
|
function wrap(proc) {
|
|
1606
|
-
const exitedPromise = new Promise((
|
|
1607
|
-
proc.once("close", (code) =>
|
|
1608
|
-
proc.once("error", () =>
|
|
1644
|
+
const exitedPromise = new Promise((resolve) => {
|
|
1645
|
+
proc.once("close", (code) => resolve(code ?? 0));
|
|
1646
|
+
proc.once("error", () => resolve(1));
|
|
1609
1647
|
});
|
|
1610
1648
|
if (!proc.stdin || !proc.stdout || !proc.stderr) {
|
|
1611
1649
|
throw new LspProcessSpawnError("Spawned process is missing one of stdin/stdout/stderr pipes");
|
|
@@ -1758,33 +1796,29 @@ function isPosition(value) {
|
|
|
1758
1796
|
|
|
1759
1797
|
// ../lsp-core/src/lsp/transport.ts
|
|
1760
1798
|
class LspClientNotStartedError extends Error {
|
|
1761
|
-
serverId;
|
|
1762
|
-
root;
|
|
1763
|
-
name = "LspClientNotStartedError";
|
|
1764
1799
|
constructor(serverId, root) {
|
|
1765
1800
|
super("LSP client not started");
|
|
1766
1801
|
this.serverId = serverId;
|
|
1767
1802
|
this.root = root;
|
|
1803
|
+
this.name = "LspClientNotStartedError";
|
|
1768
1804
|
}
|
|
1769
1805
|
}
|
|
1770
1806
|
|
|
1771
1807
|
class LspClientTransport {
|
|
1772
|
-
root
|
|
1773
|
-
server;
|
|
1774
|
-
proc = null;
|
|
1775
|
-
connection = null;
|
|
1776
|
-
stderrBuffer = [];
|
|
1777
|
-
processExited = false;
|
|
1778
|
-
diagnosticsStore = new Map;
|
|
1779
|
-
requestTimeoutMs;
|
|
1780
|
-
initializeTimeoutMs;
|
|
1781
|
-
workspaceApplyEditHandler = null;
|
|
1782
|
-
diagnosticPullSupported = false;
|
|
1783
|
-
constructor(root, server2, timeouts = {}) {
|
|
1808
|
+
constructor(root, server, timeouts = {}) {
|
|
1784
1809
|
this.root = root;
|
|
1785
|
-
this.server =
|
|
1810
|
+
this.server = server;
|
|
1811
|
+
this.proc = null;
|
|
1812
|
+
this.connection = null;
|
|
1813
|
+
this.stderrBuffer = [];
|
|
1814
|
+
this.processExited = false;
|
|
1815
|
+
this.diagnosticsStore = new Map;
|
|
1816
|
+
this.workspaceApplyEditHandler = null;
|
|
1817
|
+
this.diagnosticPullSupported = false;
|
|
1818
|
+
this.documentFormattingSupported = false;
|
|
1786
1819
|
this.requestTimeoutMs = timeouts.requestTimeoutMs ?? REQUEST_TIMEOUT_MS;
|
|
1787
1820
|
this.initializeTimeoutMs = timeouts.initializeTimeoutMs ?? INIT_TIMEOUT_MS;
|
|
1821
|
+
this.timerProvider = timeouts.timerProvider ?? realTimerProvider;
|
|
1788
1822
|
}
|
|
1789
1823
|
pid() {
|
|
1790
1824
|
return this.proc?.pid;
|
|
@@ -1804,6 +1838,12 @@ class LspClientTransport {
|
|
|
1804
1838
|
isDiagnosticPullSupported() {
|
|
1805
1839
|
return this.diagnosticPullSupported;
|
|
1806
1840
|
}
|
|
1841
|
+
setDocumentFormattingSupported(supported) {
|
|
1842
|
+
this.documentFormattingSupported = supported;
|
|
1843
|
+
}
|
|
1844
|
+
isDocumentFormattingSupported() {
|
|
1845
|
+
return this.documentFormattingSupported;
|
|
1846
|
+
}
|
|
1807
1847
|
handlePublishDiagnostics(params) {
|
|
1808
1848
|
this.diagnosticsStore.set(params.uri, [...params.diagnostics]);
|
|
1809
1849
|
}
|
|
@@ -1879,7 +1919,7 @@ class LspClientTransport {
|
|
|
1879
1919
|
const options = args[1];
|
|
1880
1920
|
const timeoutMs = options?.timeoutMs ?? this.requestTimeoutMs;
|
|
1881
1921
|
const timeoutController = new AbortController;
|
|
1882
|
-
const timeoutHandle = setTimeout(() => {
|
|
1922
|
+
const timeoutHandle = this.timerProvider.setTimeout(() => {
|
|
1883
1923
|
const stderrTail = this.stderrBuffer.slice(-5).join(`
|
|
1884
1924
|
`);
|
|
1885
1925
|
timeoutController.abort(new LspRequestTimeoutError(method, stderrTail || undefined));
|
|
@@ -1898,7 +1938,7 @@ class LspClientTransport {
|
|
|
1898
1938
|
}
|
|
1899
1939
|
throw error;
|
|
1900
1940
|
} finally {
|
|
1901
|
-
clearTimeout(timeoutHandle);
|
|
1941
|
+
this.timerProvider.clearTimeout(timeoutHandle);
|
|
1902
1942
|
combinedSignal.dispose();
|
|
1903
1943
|
}
|
|
1904
1944
|
}
|
|
@@ -1949,8 +1989,8 @@ class LspClientTransport {
|
|
|
1949
1989
|
try {
|
|
1950
1990
|
proc.kill();
|
|
1951
1991
|
let timeoutId;
|
|
1952
|
-
const timeoutPromise = new Promise((
|
|
1953
|
-
timeoutId = setTimeout(
|
|
1992
|
+
const timeoutPromise = new Promise((resolve) => {
|
|
1993
|
+
timeoutId = setTimeout(resolve, STOP_HARD_KILL_TIMEOUT_MS);
|
|
1954
1994
|
});
|
|
1955
1995
|
await Promise.race([
|
|
1956
1996
|
proc.exited.then(() => {
|
|
@@ -1966,7 +2006,7 @@ class LspClientTransport {
|
|
|
1966
2006
|
proc.kill("SIGKILL");
|
|
1967
2007
|
await Promise.race([
|
|
1968
2008
|
proc.exited,
|
|
1969
|
-
new Promise((
|
|
2009
|
+
new Promise((resolve) => setTimeout(resolve, STOP_SIGKILL_GRACE_MS))
|
|
1970
2010
|
]);
|
|
1971
2011
|
} catch (error) {
|
|
1972
2012
|
reportBestEffortCleanupError("hard process kill", error instanceof Error ? error : String(error));
|
|
@@ -2017,6 +2057,14 @@ function supportsDiagnosticPull(capabilities) {
|
|
|
2017
2057
|
return false;
|
|
2018
2058
|
return Object.hasOwn(capabilities, "diagnosticProvider");
|
|
2019
2059
|
}
|
|
2060
|
+
function supportsDocumentFormatting(capabilities) {
|
|
2061
|
+
if (capabilities === undefined)
|
|
2062
|
+
return false;
|
|
2063
|
+
const provider = capabilities.documentFormattingProvider;
|
|
2064
|
+
if (provider === undefined || provider === null || provider === false)
|
|
2065
|
+
return false;
|
|
2066
|
+
return provider === true || typeof provider === "object";
|
|
2067
|
+
}
|
|
2020
2068
|
|
|
2021
2069
|
class LspClientConnection extends LspClientTransport {
|
|
2022
2070
|
async initialize() {
|
|
@@ -2033,6 +2081,7 @@ class LspClientConnection extends LspClientTransport {
|
|
|
2033
2081
|
references: {},
|
|
2034
2082
|
documentSymbol: { hierarchicalDocumentSymbolSupport: true },
|
|
2035
2083
|
publishDiagnostics: {},
|
|
2084
|
+
formatting: { dynamicRegistration: false },
|
|
2036
2085
|
rename: {
|
|
2037
2086
|
prepareSupport: true,
|
|
2038
2087
|
prepareSupportDefaultBehavior: 1
|
|
@@ -2074,6 +2123,7 @@ class LspClientConnection extends LspClientTransport {
|
|
|
2074
2123
|
initializationOptions: this.server.initialization
|
|
2075
2124
|
}, { timeoutMs: this.initializeTimeoutMs });
|
|
2076
2125
|
this.setDiagnosticPullSupported(supportsDiagnosticPull(result?.capabilities));
|
|
2126
|
+
this.setDocumentFormattingSupported(supportsDocumentFormatting(result?.capabilities));
|
|
2077
2127
|
await this.sendNotification("initialized", {});
|
|
2078
2128
|
await this.sendNotification("workspace/didChangeConfiguration", {
|
|
2079
2129
|
settings: { json: { validate: { enable: true } } }
|
|
@@ -2269,6 +2319,17 @@ function canonicalPath(filePath) {
|
|
|
2269
2319
|
return absolute;
|
|
2270
2320
|
}
|
|
2271
2321
|
}
|
|
2322
|
+
function normalizeDocumentUri(uri) {
|
|
2323
|
+
let decoded = uri;
|
|
2324
|
+
try {
|
|
2325
|
+
decoded = decodeURIComponent(uri);
|
|
2326
|
+
} catch {
|
|
2327
|
+
decoded = uri;
|
|
2328
|
+
}
|
|
2329
|
+
if (process.platform !== "win32")
|
|
2330
|
+
return decoded;
|
|
2331
|
+
return decoded.replace(/^(file:\/\/\/)([a-z]):/, (_match, prefix, drive) => `${prefix}${drive.toUpperCase()}:`);
|
|
2332
|
+
}
|
|
2272
2333
|
function isSameOrDescendant(candidate, parent) {
|
|
2273
2334
|
const suffix = relative2(parent, candidate);
|
|
2274
2335
|
return suffix === "" || !suffix.startsWith("..") && suffix !== "..";
|
|
@@ -2279,30 +2340,31 @@ function movedPath(candidate, oldPath, newPath) {
|
|
|
2279
2340
|
}
|
|
2280
2341
|
|
|
2281
2342
|
class WorkspaceDocumentState {
|
|
2282
|
-
sendNotification;
|
|
2283
|
-
clearDiagnostics;
|
|
2284
|
-
openDocuments = new Map;
|
|
2285
|
-
openByUri = new Map;
|
|
2286
|
-
openPromises = new Map;
|
|
2287
|
-
now;
|
|
2288
|
-
versionlessPublishQuiescenceMs;
|
|
2289
2343
|
constructor(sendNotification, clearDiagnostics, options = {}) {
|
|
2290
2344
|
this.sendNotification = sendNotification;
|
|
2291
2345
|
this.clearDiagnostics = clearDiagnostics;
|
|
2292
|
-
this.
|
|
2346
|
+
this.openDocuments = new Map;
|
|
2347
|
+
this.openByUri = new Map;
|
|
2348
|
+
this.openPromises = new Map;
|
|
2349
|
+
this.timerProvider = options.timerProvider ?? {
|
|
2350
|
+
now: options.now ?? (() => Date.now()),
|
|
2351
|
+
setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
|
|
2352
|
+
clearTimeout: (handle) => clearTimeout(handle)
|
|
2353
|
+
};
|
|
2354
|
+
this.now = () => this.timerProvider.now();
|
|
2293
2355
|
this.versionlessPublishQuiescenceMs = options.versionlessPublishQuiescenceMs ?? DEFAULT_VERSIONLESS_PUBLISH_QUIESCENCE_MS;
|
|
2294
2356
|
}
|
|
2295
2357
|
async openFile(filePath) {
|
|
2296
|
-
const
|
|
2297
|
-
const existingOpen = this.openPromises.get(
|
|
2358
|
+
const path = canonicalPath(filePath);
|
|
2359
|
+
const existingOpen = this.openPromises.get(path);
|
|
2298
2360
|
if (existingOpen) {
|
|
2299
2361
|
await existingOpen;
|
|
2300
|
-
return this.openFile(
|
|
2362
|
+
return this.openFile(path);
|
|
2301
2363
|
}
|
|
2302
|
-
const text = readFileSync2(
|
|
2303
|
-
const existing = this.openDocuments.get(
|
|
2364
|
+
const text = readFileSync2(path, "utf-8");
|
|
2365
|
+
const existing = this.openDocuments.get(path);
|
|
2304
2366
|
if (!existing)
|
|
2305
|
-
return this.openDocumentSingleFlight(
|
|
2367
|
+
return this.openDocumentSingleFlight(path, text);
|
|
2306
2368
|
if (existing.text === text)
|
|
2307
2369
|
return;
|
|
2308
2370
|
await this.changeDocument(existing, text);
|
|
@@ -2311,7 +2373,7 @@ class WorkspaceDocumentState {
|
|
|
2311
2373
|
return this.openDocuments.get(canonicalPath(filePath))?.version;
|
|
2312
2374
|
}
|
|
2313
2375
|
getStoredDiagnostics(uri) {
|
|
2314
|
-
const state = this.openByUri.get(uri);
|
|
2376
|
+
const state = this.openByUri.get(normalizeDocumentUri(uri));
|
|
2315
2377
|
if (!state)
|
|
2316
2378
|
return [];
|
|
2317
2379
|
return state.lastPublish?.diagnostics ?? state.pullCache?.diagnostics ?? [];
|
|
@@ -2333,13 +2395,13 @@ class WorkspaceDocumentState {
|
|
|
2333
2395
|
return state !== undefined && state.uri === snapshot.uri && state.version === snapshot.version && state.generation === snapshot.documentGeneration;
|
|
2334
2396
|
}
|
|
2335
2397
|
getPullCache(snapshot) {
|
|
2336
|
-
const state = this.openByUri.get(snapshot.uri);
|
|
2398
|
+
const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
|
|
2337
2399
|
if (!state?.pullCache || state.pullCache.documentVersion !== snapshot.version)
|
|
2338
2400
|
return null;
|
|
2339
2401
|
return state.pullCache;
|
|
2340
2402
|
}
|
|
2341
2403
|
recordPullDiagnostics(snapshot, report) {
|
|
2342
|
-
const state = this.openByUri.get(snapshot.uri);
|
|
2404
|
+
const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
|
|
2343
2405
|
if (!state)
|
|
2344
2406
|
return;
|
|
2345
2407
|
state.pullCache = {
|
|
@@ -2349,7 +2411,7 @@ class WorkspaceDocumentState {
|
|
|
2349
2411
|
};
|
|
2350
2412
|
}
|
|
2351
2413
|
recordPublishedDiagnostics(params) {
|
|
2352
|
-
const state = this.openByUri.get(params.uri);
|
|
2414
|
+
const state = this.openByUri.get(normalizeDocumentUri(params.uri));
|
|
2353
2415
|
if (!state)
|
|
2354
2416
|
return;
|
|
2355
2417
|
state.publishGeneration += 1;
|
|
@@ -2363,7 +2425,7 @@ class WorkspaceDocumentState {
|
|
|
2363
2425
|
this.notifyWaiters(state);
|
|
2364
2426
|
}
|
|
2365
2427
|
resolvePushDiagnostics(snapshot) {
|
|
2366
|
-
const state = this.openByUri.get(snapshot.uri);
|
|
2428
|
+
const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
|
|
2367
2429
|
if (!state?.lastPublish)
|
|
2368
2430
|
return { status: "missing" };
|
|
2369
2431
|
const publish = state.lastPublish;
|
|
@@ -2377,27 +2439,29 @@ class WorkspaceDocumentState {
|
|
|
2377
2439
|
return waitMs === 0 ? { status: "ready", diagnostics: publish.diagnostics } : { status: "wait", waitMs };
|
|
2378
2440
|
}
|
|
2379
2441
|
waitForDiagnosticsActivity(snapshot, timeoutMs) {
|
|
2380
|
-
const state = this.openByUri.get(snapshot.uri);
|
|
2442
|
+
const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
|
|
2381
2443
|
if (!state || timeoutMs <= 0)
|
|
2382
2444
|
return Promise.resolve();
|
|
2445
|
+
if (state.publishGeneration !== snapshot.publishGeneration)
|
|
2446
|
+
return Promise.resolve();
|
|
2383
2447
|
return new Promise((resolveActivity) => {
|
|
2384
2448
|
let settled = false;
|
|
2385
2449
|
const finish = () => {
|
|
2386
2450
|
if (settled)
|
|
2387
2451
|
return;
|
|
2388
2452
|
settled = true;
|
|
2389
|
-
clearTimeout(timer);
|
|
2453
|
+
this.timerProvider.clearTimeout(timer);
|
|
2390
2454
|
state.waiters.delete(finish);
|
|
2391
2455
|
resolveActivity();
|
|
2392
2456
|
};
|
|
2393
|
-
const timer = setTimeout(finish, timeoutMs);
|
|
2457
|
+
const timer = this.timerProvider.setTimeout(finish, timeoutMs);
|
|
2394
2458
|
if (typeof timer.unref === "function")
|
|
2395
2459
|
timer.unref();
|
|
2396
2460
|
state.waiters.add(finish);
|
|
2397
2461
|
});
|
|
2398
2462
|
}
|
|
2399
2463
|
validateVersions(operations) {
|
|
2400
|
-
const versions = new Map([...this.openDocuments].map(([
|
|
2464
|
+
const versions = new Map([...this.openDocuments].map(([path, state]) => [path, state.version]));
|
|
2401
2465
|
for (const operation of operations) {
|
|
2402
2466
|
if (operation.kind === "text") {
|
|
2403
2467
|
const current = versions.get(operation.path);
|
|
@@ -2413,17 +2477,17 @@ class WorkspaceDocumentState {
|
|
|
2413
2477
|
continue;
|
|
2414
2478
|
}
|
|
2415
2479
|
if (operation.kind === "rename") {
|
|
2416
|
-
const moved = [...versions].filter(([
|
|
2417
|
-
for (const [
|
|
2418
|
-
versions.delete(
|
|
2419
|
-
for (const [
|
|
2420
|
-
versions.set(movedPath(
|
|
2480
|
+
const moved = [...versions].filter(([path]) => isSameOrDescendant(path, operation.oldPath));
|
|
2481
|
+
for (const [path] of moved)
|
|
2482
|
+
versions.delete(path);
|
|
2483
|
+
for (const [path] of moved)
|
|
2484
|
+
versions.set(movedPath(path, operation.oldPath, operation.newPath), 1);
|
|
2421
2485
|
continue;
|
|
2422
2486
|
}
|
|
2423
2487
|
if (operation.kind === "delete") {
|
|
2424
|
-
for (const
|
|
2425
|
-
if (isSameOrDescendant(
|
|
2426
|
-
versions.delete(
|
|
2488
|
+
for (const path of [...versions.keys()]) {
|
|
2489
|
+
if (isSameOrDescendant(path, operation.path))
|
|
2490
|
+
versions.delete(path);
|
|
2427
2491
|
}
|
|
2428
2492
|
continue;
|
|
2429
2493
|
}
|
|
@@ -2467,8 +2531,8 @@ class WorkspaceDocumentState {
|
|
|
2467
2531
|
for (const state of moved)
|
|
2468
2532
|
await this.closeDocument(state);
|
|
2469
2533
|
for (const state of moved) {
|
|
2470
|
-
const
|
|
2471
|
-
await this.openDocumentSingleFlight(
|
|
2534
|
+
const path = movedPath(state.path, mutation.oldPath, mutation.newPath);
|
|
2535
|
+
await this.openDocumentSingleFlight(path, readFileSync2(path, "utf-8"));
|
|
2472
2536
|
}
|
|
2473
2537
|
if (moved.length === 0) {
|
|
2474
2538
|
watched.push({ uri: pathToFileURL2(mutation.oldPath).href, type: 3 });
|
|
@@ -2482,31 +2546,31 @@ class WorkspaceDocumentState {
|
|
|
2482
2546
|
if (removed.length === 0)
|
|
2483
2547
|
watched.push({ uri: pathToFileURL2(mutation.path).href, type: 3 });
|
|
2484
2548
|
}
|
|
2485
|
-
async openDocumentSingleFlight(
|
|
2486
|
-
const existing = this.openPromises.get(
|
|
2549
|
+
async openDocumentSingleFlight(path, text) {
|
|
2550
|
+
const existing = this.openPromises.get(path);
|
|
2487
2551
|
if (existing)
|
|
2488
2552
|
return existing;
|
|
2489
2553
|
const open = (async () => {
|
|
2490
2554
|
const state = {
|
|
2491
|
-
path
|
|
2492
|
-
uri: pathToFileURL2(
|
|
2493
|
-
languageId: getLanguageId(effectiveExtension(
|
|
2555
|
+
path,
|
|
2556
|
+
uri: pathToFileURL2(path).href,
|
|
2557
|
+
languageId: getLanguageId(effectiveExtension(path)),
|
|
2494
2558
|
text,
|
|
2495
2559
|
version: 1,
|
|
2496
2560
|
generation: 1,
|
|
2497
2561
|
publishGeneration: 0,
|
|
2498
2562
|
waiters: new Set
|
|
2499
2563
|
};
|
|
2500
|
-
this.openDocuments.set(
|
|
2501
|
-
this.openByUri.set(state.uri, state);
|
|
2564
|
+
this.openDocuments.set(path, state);
|
|
2565
|
+
this.openByUri.set(normalizeDocumentUri(state.uri), state);
|
|
2502
2566
|
this.notifyWaiters(state);
|
|
2503
2567
|
await this.sendNotification("textDocument/didOpen", {
|
|
2504
2568
|
textDocument: { uri: state.uri, languageId: state.languageId, version: state.version, text }
|
|
2505
2569
|
});
|
|
2506
2570
|
})().finally(() => {
|
|
2507
|
-
this.openPromises.delete(
|
|
2571
|
+
this.openPromises.delete(path);
|
|
2508
2572
|
});
|
|
2509
|
-
this.openPromises.set(
|
|
2573
|
+
this.openPromises.set(path, open);
|
|
2510
2574
|
return open;
|
|
2511
2575
|
}
|
|
2512
2576
|
async changeDocument(state, text) {
|
|
@@ -2523,7 +2587,7 @@ class WorkspaceDocumentState {
|
|
|
2523
2587
|
}
|
|
2524
2588
|
async closeDocument(state) {
|
|
2525
2589
|
this.openDocuments.delete(state.path);
|
|
2526
|
-
this.openByUri.delete(state.uri);
|
|
2590
|
+
this.openByUri.delete(normalizeDocumentUri(state.uri));
|
|
2527
2591
|
this.clearDiagnostics(state.uri);
|
|
2528
2592
|
this.notifyWaiters(state);
|
|
2529
2593
|
await this.sendNotification("textDocument/didClose", { textDocument: { uri: state.uri } });
|
|
@@ -2552,13 +2616,11 @@ import { dirname as dirname4, isAbsolute as isAbsolute4, relative as relative3,
|
|
|
2552
2616
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
2553
2617
|
|
|
2554
2618
|
class WorkspaceEditPathError extends Error {
|
|
2555
|
-
path
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
constructor(path2, detail) {
|
|
2559
|
-
super(`${detail}: ${path2}`);
|
|
2560
|
-
this.path = path2;
|
|
2619
|
+
constructor(path, detail) {
|
|
2620
|
+
super(`${detail}: ${path}`);
|
|
2621
|
+
this.path = path;
|
|
2561
2622
|
this.detail = detail;
|
|
2623
|
+
this.name = "WorkspaceEditPathError";
|
|
2562
2624
|
}
|
|
2563
2625
|
}
|
|
2564
2626
|
function isPathInsideWorkspace(filePath, workspaceRoot) {
|
|
@@ -2620,28 +2682,28 @@ function uriToCanonicalWorkspacePath(uri, workspaceRoot) {
|
|
|
2620
2682
|
return { success: false, error: `${requestedPath}: ${detail}` };
|
|
2621
2683
|
}
|
|
2622
2684
|
}
|
|
2623
|
-
function snapshotPath(
|
|
2624
|
-
if (!existsSync4(
|
|
2685
|
+
function snapshotPath(path, includeChildren) {
|
|
2686
|
+
if (!existsSync4(path))
|
|
2625
2687
|
return { kind: "missing" };
|
|
2626
|
-
const stats = lstatSync2(
|
|
2688
|
+
const stats = lstatSync2(path);
|
|
2627
2689
|
if (stats.isFile())
|
|
2628
|
-
return { kind: "file", content: readFileSync3(
|
|
2690
|
+
return { kind: "file", content: readFileSync3(path, "utf-8") };
|
|
2629
2691
|
if (stats.isDirectory()) {
|
|
2630
|
-
return includeChildren ? { kind: "directory", children: readdirSync(
|
|
2692
|
+
return includeChildren ? { kind: "directory", children: readdirSync(path).sort() } : { kind: "directory" };
|
|
2631
2693
|
}
|
|
2632
|
-
throw new WorkspaceEditPathError(
|
|
2694
|
+
throw new WorkspaceEditPathError(path, "unsupported filesystem entry");
|
|
2633
2695
|
}
|
|
2634
2696
|
|
|
2635
2697
|
// ../lsp-core/src/lsp/workspace-edit-commit.ts
|
|
2636
2698
|
var DEFAULT_IO = {
|
|
2637
|
-
writeFile(
|
|
2638
|
-
writeFileSync(
|
|
2699
|
+
writeFile(path, content) {
|
|
2700
|
+
writeFileSync(path, content, "utf-8");
|
|
2639
2701
|
},
|
|
2640
2702
|
rename(oldPath, newPath) {
|
|
2641
2703
|
renameSync(oldPath, newPath);
|
|
2642
2704
|
},
|
|
2643
|
-
remove(
|
|
2644
|
-
rmSync(
|
|
2705
|
+
remove(path, recursive) {
|
|
2706
|
+
rmSync(path, { recursive, force: false });
|
|
2645
2707
|
}
|
|
2646
2708
|
};
|
|
2647
2709
|
function snapshotsEqual(expected, actual) {
|
|
@@ -2654,8 +2716,8 @@ function snapshotsEqual(expected, actual) {
|
|
|
2654
2716
|
}
|
|
2655
2717
|
return true;
|
|
2656
2718
|
}
|
|
2657
|
-
function liveSnapshot(
|
|
2658
|
-
return snapshotPath(
|
|
2719
|
+
function liveSnapshot(path, expected) {
|
|
2720
|
+
return snapshotPath(path, expected.kind === "directory" && expected.children !== undefined);
|
|
2659
2721
|
}
|
|
2660
2722
|
function firstOperationIndex(plan) {
|
|
2661
2723
|
return plan.operations[0]?.changeIndex ?? 0;
|
|
@@ -2676,28 +2738,28 @@ function failedCommit(plan, failure) {
|
|
|
2676
2738
|
};
|
|
2677
2739
|
}
|
|
2678
2740
|
function verifySnapshots(plan) {
|
|
2679
|
-
for (const [
|
|
2741
|
+
for (const [path, expected] of plan.snapshots) {
|
|
2680
2742
|
let actual;
|
|
2681
2743
|
try {
|
|
2682
|
-
actual = liveSnapshot(
|
|
2744
|
+
actual = liveSnapshot(path, expected);
|
|
2683
2745
|
} catch (error) {
|
|
2684
|
-
const changeIndex = plan.firstChangeByPath.get(
|
|
2746
|
+
const changeIndex = plan.firstChangeByPath.get(path) ?? firstOperationIndex(plan);
|
|
2685
2747
|
const detail = error instanceof Error ? error.message : String(error);
|
|
2686
|
-
return failedCommit(plan, { message: `cannot verify snapshot for ${
|
|
2748
|
+
return failedCommit(plan, { message: `cannot verify snapshot for ${path}: ${detail}`, changeIndex });
|
|
2687
2749
|
}
|
|
2688
2750
|
if (!snapshotsEqual(expected, actual)) {
|
|
2689
|
-
const changeIndex = plan.firstChangeByPath.get(
|
|
2690
|
-
return failedCommit(plan, { message: `workspace state changed before commit: ${
|
|
2751
|
+
const changeIndex = plan.firstChangeByPath.get(path) ?? firstOperationIndex(plan);
|
|
2752
|
+
return failedCommit(plan, { message: `workspace state changed before commit: ${path}`, changeIndex });
|
|
2691
2753
|
}
|
|
2692
2754
|
}
|
|
2693
2755
|
return null;
|
|
2694
2756
|
}
|
|
2695
|
-
function addModifiedPath(paths,
|
|
2696
|
-
if (!paths.includes(
|
|
2697
|
-
paths.push(
|
|
2757
|
+
function addModifiedPath(paths, path) {
|
|
2758
|
+
if (!paths.includes(path))
|
|
2759
|
+
paths.push(path);
|
|
2698
2760
|
}
|
|
2699
|
-
function reportedPath(plan,
|
|
2700
|
-
return plan.reportedPathByCanonical.get(
|
|
2761
|
+
function reportedPath(plan, path) {
|
|
2762
|
+
return plan.reportedPathByCanonical.get(path) ?? path;
|
|
2701
2763
|
}
|
|
2702
2764
|
function changedPathsForMutation(mutation) {
|
|
2703
2765
|
return mutation.kind === "rename" ? [mutation.oldPath, mutation.newPath] : [mutation.path];
|
|
@@ -2705,8 +2767,8 @@ function changedPathsForMutation(mutation) {
|
|
|
2705
2767
|
function mutationDelta(operations) {
|
|
2706
2768
|
const changedPaths = new Set;
|
|
2707
2769
|
for (const operation of operations) {
|
|
2708
|
-
for (const
|
|
2709
|
-
changedPaths.add(
|
|
2770
|
+
for (const path of changedPathsForMutation(operation))
|
|
2771
|
+
changedPaths.add(path);
|
|
2710
2772
|
}
|
|
2711
2773
|
return { operations, changedPaths: [...changedPaths].sort() };
|
|
2712
2774
|
}
|
|
@@ -2850,13 +2912,11 @@ function canonicalFingerprint(operations) {
|
|
|
2850
2912
|
|
|
2851
2913
|
// ../lsp-core/src/lsp/workspace-edit-types.ts
|
|
2852
2914
|
class WorkspaceEditValidationError extends Error {
|
|
2853
|
-
changeIndex;
|
|
2854
|
-
detail;
|
|
2855
|
-
name = "WorkspaceEditValidationError";
|
|
2856
2915
|
constructor(changeIndex, detail) {
|
|
2857
2916
|
super(`change ${changeIndex}: ${detail}`);
|
|
2858
2917
|
this.changeIndex = changeIndex;
|
|
2859
2918
|
this.detail = detail;
|
|
2919
|
+
this.name = "WorkspaceEditValidationError";
|
|
2860
2920
|
}
|
|
2861
2921
|
}
|
|
2862
2922
|
|
|
@@ -2942,14 +3002,14 @@ function parseSinglePathResource(input, kind) {
|
|
|
2942
3002
|
return;
|
|
2943
3003
|
}
|
|
2944
3004
|
if (kind === "create") {
|
|
2945
|
-
const
|
|
3005
|
+
const options = parseOptions(change["options"], ["overwrite", "ignoreIfExists"], changeIndex);
|
|
2946
3006
|
target.operations.push({
|
|
2947
3007
|
kind,
|
|
2948
3008
|
changeIndex,
|
|
2949
3009
|
path: resolvedPath.path,
|
|
2950
3010
|
reportedPath: resolvedPath.requestedPath,
|
|
2951
|
-
overwrite:
|
|
2952
|
-
ignoreIfExists:
|
|
3011
|
+
overwrite: options["overwrite"] ?? false,
|
|
3012
|
+
ignoreIfExists: options["ignoreIfExists"] ?? false,
|
|
2953
3013
|
followedSymbolicLink: resolvedPath.followedSymbolicLink
|
|
2954
3014
|
});
|
|
2955
3015
|
return;
|
|
@@ -3207,12 +3267,12 @@ function isSameOrDescendant2(candidate, parent) {
|
|
|
3207
3267
|
const relativePath = relative4(parent, candidate);
|
|
3208
3268
|
return relativePath === "" || !relativePath.startsWith("..") && relativePath !== "..";
|
|
3209
3269
|
}
|
|
3210
|
-
function removeVirtualSubtree(virtual,
|
|
3270
|
+
function removeVirtualSubtree(virtual, path) {
|
|
3211
3271
|
for (const candidate of [...virtual.keys()]) {
|
|
3212
|
-
if (isSameOrDescendant2(candidate,
|
|
3272
|
+
if (isSameOrDescendant2(candidate, path))
|
|
3213
3273
|
virtual.delete(candidate);
|
|
3214
3274
|
}
|
|
3215
|
-
virtual.set(
|
|
3275
|
+
virtual.set(path, { kind: "missing" });
|
|
3216
3276
|
}
|
|
3217
3277
|
function moveVirtualSubtree(virtual, oldPath, newPath) {
|
|
3218
3278
|
const moved = [...virtual.entries()].filter(([candidate]) => isSameOrDescendant2(candidate, oldPath));
|
|
@@ -3223,16 +3283,16 @@ function moveVirtualSubtree(virtual, oldPath, newPath) {
|
|
|
3223
3283
|
virtual.set(suffix === "" ? newPath : resolve4(newPath, suffix), entry);
|
|
3224
3284
|
}
|
|
3225
3285
|
}
|
|
3226
|
-
function virtualDirectoryHasChildren(virtual,
|
|
3286
|
+
function virtualDirectoryHasChildren(virtual, path) {
|
|
3227
3287
|
for (const [candidate, entry] of virtual) {
|
|
3228
|
-
if (candidate !==
|
|
3288
|
+
if (candidate !== path && entry.kind !== "missing" && isSameOrDescendant2(candidate, path))
|
|
3229
3289
|
return true;
|
|
3230
3290
|
}
|
|
3231
3291
|
return false;
|
|
3232
3292
|
}
|
|
3233
|
-
function requireVirtualParent(virtual,
|
|
3234
|
-
if (virtual.get(dirname5(
|
|
3235
|
-
throw new WorkspaceEditValidationError(changeIndex, `parent directory does not exist for ${
|
|
3293
|
+
function requireVirtualParent(virtual, path, changeIndex) {
|
|
3294
|
+
if (virtual.get(dirname5(path))?.kind !== "directory") {
|
|
3295
|
+
throw new WorkspaceEditValidationError(changeIndex, `parent directory does not exist for ${path}`);
|
|
3236
3296
|
}
|
|
3237
3297
|
}
|
|
3238
3298
|
function simulateOperations(parsed, snapshots) {
|
|
@@ -3354,10 +3414,9 @@ function simulateDelete(operation, virtual) {
|
|
|
3354
3414
|
import { existsSync as existsSync6, lstatSync as lstatSync4, readdirSync as readdirSync2 } from "node:fs";
|
|
3355
3415
|
import { dirname as dirname6, resolve as resolve5 } from "node:path";
|
|
3356
3416
|
class WorkspaceSnapshotBuilder {
|
|
3357
|
-
workspaceRoot;
|
|
3358
|
-
snapshots = new Map;
|
|
3359
3417
|
constructor(workspaceRoot) {
|
|
3360
3418
|
this.workspaceRoot = workspaceRoot;
|
|
3419
|
+
this.snapshots = new Map;
|
|
3361
3420
|
}
|
|
3362
3421
|
build(operations) {
|
|
3363
3422
|
this.add(this.workspaceRoot, false);
|
|
@@ -3378,21 +3437,21 @@ class WorkspaceSnapshotBuilder {
|
|
|
3378
3437
|
}
|
|
3379
3438
|
return this.snapshots;
|
|
3380
3439
|
}
|
|
3381
|
-
add(
|
|
3382
|
-
let candidate =
|
|
3440
|
+
add(path, includeChildren) {
|
|
3441
|
+
let candidate = path;
|
|
3383
3442
|
while (true) {
|
|
3384
3443
|
const existing = this.snapshots.get(candidate);
|
|
3385
3444
|
if (existing === undefined || includeChildren && existing.kind === "directory" && existing.children === undefined) {
|
|
3386
|
-
this.snapshots.set(candidate, snapshotPath(candidate, includeChildren && candidate ===
|
|
3445
|
+
this.snapshots.set(candidate, snapshotPath(candidate, includeChildren && candidate === path));
|
|
3387
3446
|
}
|
|
3388
3447
|
if (candidate === this.workspaceRoot)
|
|
3389
3448
|
break;
|
|
3390
3449
|
candidate = dirname6(candidate);
|
|
3391
3450
|
}
|
|
3392
|
-
if (!includeChildren || !existsSync6(
|
|
3451
|
+
if (!includeChildren || !existsSync6(path) || !lstatSync4(path).isDirectory())
|
|
3393
3452
|
return;
|
|
3394
|
-
for (const child of readdirSync2(
|
|
3395
|
-
this.add(resolve5(
|
|
3453
|
+
for (const child of readdirSync2(path))
|
|
3454
|
+
this.add(resolve5(path, child), true);
|
|
3396
3455
|
}
|
|
3397
3456
|
}
|
|
3398
3457
|
function snapshotOperations(operations, workspaceRoot) {
|
|
@@ -3401,8 +3460,10 @@ function snapshotOperations(operations, workspaceRoot) {
|
|
|
3401
3460
|
|
|
3402
3461
|
// ../lsp-core/src/lsp/workspace-edit-plan.ts
|
|
3403
3462
|
class PlanPathIndex {
|
|
3404
|
-
|
|
3405
|
-
|
|
3463
|
+
constructor() {
|
|
3464
|
+
this.firstChangeByPath = new Map;
|
|
3465
|
+
this.reportedPathByCanonical = new Map;
|
|
3466
|
+
}
|
|
3406
3467
|
build(operations) {
|
|
3407
3468
|
for (const operation of operations) {
|
|
3408
3469
|
switch (operation.kind) {
|
|
@@ -3418,11 +3479,11 @@ class PlanPathIndex {
|
|
|
3418
3479
|
}
|
|
3419
3480
|
}
|
|
3420
3481
|
}
|
|
3421
|
-
add(
|
|
3422
|
-
if (!this.firstChangeByPath.has(
|
|
3423
|
-
this.firstChangeByPath.set(
|
|
3424
|
-
if (!this.reportedPathByCanonical.has(
|
|
3425
|
-
this.reportedPathByCanonical.set(
|
|
3482
|
+
add(path, reportedPath, changeIndex) {
|
|
3483
|
+
if (!this.firstChangeByPath.has(path))
|
|
3484
|
+
this.firstChangeByPath.set(path, changeIndex);
|
|
3485
|
+
if (!this.reportedPathByCanonical.has(path))
|
|
3486
|
+
this.reportedPathByCanonical.set(path, reportedPath);
|
|
3426
3487
|
}
|
|
3427
3488
|
}
|
|
3428
3489
|
function fingerprintWorkspaceEdit(edit, workspaceRoot) {
|
|
@@ -3491,14 +3552,11 @@ function isRecord4(value) {
|
|
|
3491
3552
|
}
|
|
3492
3553
|
|
|
3493
3554
|
class WorkspaceMutationController {
|
|
3494
|
-
workspaceRoot;
|
|
3495
|
-
documents;
|
|
3496
|
-
activeLease = null;
|
|
3497
|
-
nextLeaseId = 1;
|
|
3498
|
-
io;
|
|
3499
3555
|
constructor(workspaceRoot, documents) {
|
|
3500
3556
|
this.workspaceRoot = workspaceRoot;
|
|
3501
3557
|
this.documents = documents;
|
|
3558
|
+
this.activeLease = null;
|
|
3559
|
+
this.nextLeaseId = 1;
|
|
3502
3560
|
}
|
|
3503
3561
|
setIo(io) {
|
|
3504
3562
|
this.io = io;
|
|
@@ -3537,15 +3595,15 @@ class WorkspaceMutationController {
|
|
|
3537
3595
|
};
|
|
3538
3596
|
}
|
|
3539
3597
|
lease.phase = "applying";
|
|
3540
|
-
lease.applyCompletion = new Promise((
|
|
3541
|
-
lease.resolveApply =
|
|
3598
|
+
lease.applyCompletion = new Promise((resolve) => {
|
|
3599
|
+
lease.resolveApply = resolve;
|
|
3542
3600
|
});
|
|
3543
3601
|
const edit = isRecord4(params) ? params["edit"] : undefined;
|
|
3544
|
-
const
|
|
3545
|
-
lease.serverApply =
|
|
3602
|
+
const record = edit === undefined ? { fingerprint: null, result: failure("workspace/applyEdit params.edit is required", 0) } : await this.applyEdit(edit, lease);
|
|
3603
|
+
lease.serverApply = record;
|
|
3546
3604
|
lease.phase = "settled";
|
|
3547
3605
|
lease.resolveApply?.();
|
|
3548
|
-
return responseFor(
|
|
3606
|
+
return responseFor(record.result);
|
|
3549
3607
|
}
|
|
3550
3608
|
async reconcileRename(leaseToken, edit) {
|
|
3551
3609
|
const lease = this.requireActiveLease(leaseToken);
|
|
@@ -3561,16 +3619,16 @@ class WorkspaceMutationController {
|
|
|
3561
3619
|
const applied = await this.applyEdit(edit, lease);
|
|
3562
3620
|
return { edit, apply: applied.result };
|
|
3563
3621
|
}
|
|
3564
|
-
reconcileServerApply(
|
|
3622
|
+
reconcileServerApply(record, edit) {
|
|
3565
3623
|
if (!edit)
|
|
3566
|
-
return { edit, apply:
|
|
3624
|
+
return { edit, apply: record.result };
|
|
3567
3625
|
const fingerprint = fingerprintWorkspaceEdit(edit, this.workspaceRoot);
|
|
3568
|
-
if (fingerprint.success &&
|
|
3569
|
-
return { edit, apply:
|
|
3626
|
+
if (fingerprint.success && record.fingerprint !== null && fingerprint.fingerprint === record.fingerprint) {
|
|
3627
|
+
return { edit, apply: record.result };
|
|
3570
3628
|
}
|
|
3571
3629
|
return {
|
|
3572
3630
|
edit,
|
|
3573
|
-
apply: failure("rename result conflicts with server-applied workspace edit", 0,
|
|
3631
|
+
apply: failure("rename result conflicts with server-applied workspace edit", 0, record.result)
|
|
3574
3632
|
};
|
|
3575
3633
|
}
|
|
3576
3634
|
async applyEdit(edit, lease) {
|
|
@@ -3611,14 +3669,12 @@ var DIAGNOSTICS_FRESHNESS_TIMEOUT_MS = 3000;
|
|
|
3611
3669
|
var VERSIONLESS_PUBLISH_QUIESCENCE_MS = 250;
|
|
3612
3670
|
|
|
3613
3671
|
class LspClient extends LspClientConnection {
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
|
|
3617
|
-
diagnosticsFreshnessTimeoutMs;
|
|
3618
|
-
constructor(root, server2, options = {}) {
|
|
3619
|
-
super(root, server2, options);
|
|
3672
|
+
constructor(root, server, options = {}) {
|
|
3673
|
+
super(root, server, options);
|
|
3674
|
+
this.diagnosticPullErrors = [];
|
|
3620
3675
|
this.diagnosticsFreshnessTimeoutMs = options.diagnosticsFreshnessTimeoutMs ?? DIAGNOSTICS_FRESHNESS_TIMEOUT_MS;
|
|
3621
3676
|
this.documents = new WorkspaceDocumentState((method, params) => this.sendNotification(method, params), (uri) => this.diagnosticsStore.delete(uri), {
|
|
3677
|
+
timerProvider: this.timerProvider,
|
|
3622
3678
|
versionlessPublishQuiescenceMs: options.versionlessPublishQuiescenceMs ?? VERSIONLESS_PUBLISH_QUIESCENCE_MS
|
|
3623
3679
|
});
|
|
3624
3680
|
this.workspaceMutations = new WorkspaceMutationController(root, this.documents);
|
|
@@ -3671,6 +3727,18 @@ class LspClient extends LspClientConnection {
|
|
|
3671
3727
|
textDocument: { uri: pathToFileURL3(absPath).href }
|
|
3672
3728
|
}, options);
|
|
3673
3729
|
}
|
|
3730
|
+
async formatDocument(filePath, options, signal) {
|
|
3731
|
+
if (!this.isDocumentFormattingSupported())
|
|
3732
|
+
return null;
|
|
3733
|
+
const absPath = this.resolveWorkspacePath(filePath);
|
|
3734
|
+
await this.openFile(absPath);
|
|
3735
|
+
const requestOptions = signal === undefined ? {} : { signal };
|
|
3736
|
+
const edits = await this.sendRequest("textDocument/formatting", {
|
|
3737
|
+
textDocument: { uri: pathToFileURL3(absPath).href },
|
|
3738
|
+
options
|
|
3739
|
+
}, requestOptions);
|
|
3740
|
+
return edits ?? [];
|
|
3741
|
+
}
|
|
3674
3742
|
async workspaceSymbols(query, signal) {
|
|
3675
3743
|
const options = signal === undefined ? {} : { signal };
|
|
3676
3744
|
return this.sendRequest("workspace/symbol", { query }, options);
|
|
@@ -3710,7 +3778,7 @@ class LspClient extends LspClientConnection {
|
|
|
3710
3778
|
const absPath = this.resolveWorkspacePath(filePath);
|
|
3711
3779
|
const uri = pathToFileURL3(absPath).href;
|
|
3712
3780
|
await this.openFile(absPath);
|
|
3713
|
-
const deadlineAt =
|
|
3781
|
+
const deadlineAt = this.timerProvider.now() + this.diagnosticsFreshnessTimeoutMs;
|
|
3714
3782
|
for (;; ) {
|
|
3715
3783
|
signal?.throwIfAborted();
|
|
3716
3784
|
const snapshot = this.documents.captureDiagnosticSnapshot(absPath);
|
|
@@ -3723,13 +3791,13 @@ class LspClient extends LspClientConnection {
|
|
|
3723
3791
|
if (!pushFallbackOnly) {
|
|
3724
3792
|
const cached = this.documents.getPullCache(snapshot);
|
|
3725
3793
|
try {
|
|
3726
|
-
const
|
|
3727
|
-
if (
|
|
3794
|
+
const remainingMs = deadlineAt - this.timerProvider.now();
|
|
3795
|
+
if (remainingMs <= 0)
|
|
3728
3796
|
return this.freshnessTimeout(absPath);
|
|
3729
3797
|
const result = await this.sendRequest("textDocument/diagnostic", {
|
|
3730
3798
|
textDocument: { uri },
|
|
3731
3799
|
...cached?.resultId === undefined ? {} : { previousResultId: cached.resultId }
|
|
3732
|
-
}, { timeoutMs:
|
|
3800
|
+
}, { timeoutMs: remainingMs, ...signal === undefined ? {} : { signal } });
|
|
3733
3801
|
if (!this.documents.isCurrentSnapshot(snapshot))
|
|
3734
3802
|
continue;
|
|
3735
3803
|
const report = this.parseDiagnosticPullReport(result);
|
|
@@ -3758,7 +3826,7 @@ class LspClient extends LspClientConnection {
|
|
|
3758
3826
|
}
|
|
3759
3827
|
if (!pushFallbackOnly)
|
|
3760
3828
|
continue;
|
|
3761
|
-
const remainingMs = deadlineAt -
|
|
3829
|
+
const remainingMs = deadlineAt - this.timerProvider.now();
|
|
3762
3830
|
if (remainingMs <= 0) {
|
|
3763
3831
|
if (!this.isDiagnosticPullSupported() && snapshot.publishGeneration === 0) {
|
|
3764
3832
|
const cached = this.documents.getPullCache(snapshot);
|
|
@@ -3810,7 +3878,7 @@ function waitForDiagnosticsActivity(wait, signal) {
|
|
|
3810
3878
|
return wait;
|
|
3811
3879
|
if (signal.aborted)
|
|
3812
3880
|
return Promise.reject(abortError3(signal));
|
|
3813
|
-
return new Promise((
|
|
3881
|
+
return new Promise((resolve, reject) => {
|
|
3814
3882
|
const onAbort = () => {
|
|
3815
3883
|
signal.removeEventListener("abort", onAbort);
|
|
3816
3884
|
reject(abortError3(signal));
|
|
@@ -3818,7 +3886,7 @@ function waitForDiagnosticsActivity(wait, signal) {
|
|
|
3818
3886
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
3819
3887
|
wait.then(() => {
|
|
3820
3888
|
signal.removeEventListener("abort", onAbort);
|
|
3821
|
-
|
|
3889
|
+
resolve();
|
|
3822
3890
|
}, (error) => {
|
|
3823
3891
|
signal.removeEventListener("abort", onAbort);
|
|
3824
3892
|
reject(error);
|
|
@@ -3886,7 +3954,7 @@ async function stopClientBestEffort(client) {
|
|
|
3886
3954
|
function awaitWithSignal2(promise, signal) {
|
|
3887
3955
|
if (!signal)
|
|
3888
3956
|
return promise;
|
|
3889
|
-
return new Promise((
|
|
3957
|
+
return new Promise((resolve, reject) => {
|
|
3890
3958
|
let settled = false;
|
|
3891
3959
|
const onAbort = () => {
|
|
3892
3960
|
if (settled)
|
|
@@ -3904,7 +3972,7 @@ function awaitWithSignal2(promise, signal) {
|
|
|
3904
3972
|
return;
|
|
3905
3973
|
settled = true;
|
|
3906
3974
|
signal.removeEventListener("abort", onAbort);
|
|
3907
|
-
|
|
3975
|
+
resolve(value);
|
|
3908
3976
|
}, (err) => {
|
|
3909
3977
|
if (settled)
|
|
3910
3978
|
return;
|
|
@@ -3916,20 +3984,18 @@ function awaitWithSignal2(promise, signal) {
|
|
|
3916
3984
|
}
|
|
3917
3985
|
|
|
3918
3986
|
class LspManager {
|
|
3919
|
-
clients = new Map;
|
|
3920
|
-
reaperHandle = null;
|
|
3921
|
-
signalDisposer = null;
|
|
3922
|
-
disposed = false;
|
|
3923
|
-
idleTimeoutMs;
|
|
3924
|
-
initTimeoutMs;
|
|
3925
|
-
reaperIntervalMs;
|
|
3926
|
-
clientFactory;
|
|
3927
|
-
now;
|
|
3928
3987
|
constructor(options = {}) {
|
|
3988
|
+
this.clients = new Map;
|
|
3989
|
+
this.pendingStops = new Map;
|
|
3990
|
+
this.respawnBudgets = new Map;
|
|
3991
|
+
this.reaperHandle = null;
|
|
3992
|
+
this.signalDisposer = null;
|
|
3993
|
+
this.disposed = false;
|
|
3929
3994
|
this.idleTimeoutMs = options.idleTimeoutMs ?? IDLE_TIMEOUT_MS;
|
|
3930
3995
|
this.initTimeoutMs = options.initTimeoutMs ?? INIT_TIMEOUT_MS;
|
|
3996
|
+
this.maxResidentClients = options.maxResidentClients ?? MAX_RESIDENT_CLIENTS;
|
|
3931
3997
|
this.reaperIntervalMs = options.reaperIntervalMs ?? REAPER_INTERVAL_MS;
|
|
3932
|
-
this.clientFactory = options.clientFactory ?? ((root,
|
|
3998
|
+
this.clientFactory = options.clientFactory ?? ((root, server) => new LspClient(root, server));
|
|
3933
3999
|
this.now = options.now ?? (() => Date.now());
|
|
3934
4000
|
this.startReaper();
|
|
3935
4001
|
this.signalDisposer = installProcessSignalCleanup(() => this.stopAll());
|
|
@@ -3947,38 +4013,103 @@ class LspManager {
|
|
|
3947
4013
|
getKey(root, serverId) {
|
|
3948
4014
|
return `${root}::${serverId}`;
|
|
3949
4015
|
}
|
|
4016
|
+
tombstoneStop(key, client) {
|
|
4017
|
+
const stop = stopClientBestEffort(client);
|
|
4018
|
+
this.pendingStops.set(key, stop);
|
|
4019
|
+
stop.finally(() => {
|
|
4020
|
+
if (this.pendingStops.get(key) === stop) {
|
|
4021
|
+
this.pendingStops.delete(key);
|
|
4022
|
+
}
|
|
4023
|
+
});
|
|
4024
|
+
return stop;
|
|
4025
|
+
}
|
|
4026
|
+
recordDeadGeneration(key) {
|
|
4027
|
+
let budget = this.respawnBudgets.get(key);
|
|
4028
|
+
if (budget === undefined) {
|
|
4029
|
+
budget = { deadGenerations: 0, exhaustedAt: null };
|
|
4030
|
+
this.respawnBudgets.set(key, budget);
|
|
4031
|
+
}
|
|
4032
|
+
budget.deadGenerations += 1;
|
|
4033
|
+
}
|
|
4034
|
+
markHealthyGeneration(key) {
|
|
4035
|
+
this.respawnBudgets.delete(key);
|
|
4036
|
+
}
|
|
4037
|
+
ensureRespawnAllowed(key, root, serverId) {
|
|
4038
|
+
const budget = this.respawnBudgets.get(key);
|
|
4039
|
+
if (budget === undefined || budget.deadGenerations < CLIENT_RESPAWN_RETRY_LIMIT)
|
|
4040
|
+
return;
|
|
4041
|
+
if (budget.exhaustedAt === null) {
|
|
4042
|
+
budget.exhaustedAt = this.now();
|
|
4043
|
+
throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
|
|
4044
|
+
}
|
|
4045
|
+
if (this.now() - budget.exhaustedAt < CLIENT_RESPAWN_COOLDOWN_MS) {
|
|
4046
|
+
throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
|
|
4047
|
+
}
|
|
4048
|
+
budget.deadGenerations = 0;
|
|
4049
|
+
budget.exhaustedAt = null;
|
|
4050
|
+
}
|
|
3950
4051
|
reapStale() {
|
|
3951
4052
|
const t = this.now();
|
|
3952
4053
|
for (const [key, managed] of this.clients) {
|
|
3953
4054
|
if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
|
|
3954
|
-
stopClientBestEffort(managed.client);
|
|
3955
4055
|
this.clients.delete(key);
|
|
4056
|
+
this.tombstoneStop(key, managed.client);
|
|
3956
4057
|
continue;
|
|
3957
4058
|
}
|
|
3958
4059
|
if (!managed.isInitializing && managed.refCount === 0 && managed.pendingWaiters === 0 && t - managed.lastUsedAt > this.idleTimeoutMs) {
|
|
3959
|
-
stopClientBestEffort(managed.client);
|
|
3960
4060
|
this.clients.delete(key);
|
|
4061
|
+
this.tombstoneStop(key, managed.client);
|
|
4062
|
+
}
|
|
4063
|
+
}
|
|
4064
|
+
}
|
|
4065
|
+
evictForAdmission() {
|
|
4066
|
+
while (this.clients.size >= this.maxResidentClients) {
|
|
4067
|
+
const victim = this.leastRecentlyUsedIdleClient();
|
|
4068
|
+
if (!victim)
|
|
4069
|
+
return;
|
|
4070
|
+
this.clients.delete(victim.key);
|
|
4071
|
+
this.tombstoneStop(victim.key, victim.managed.client);
|
|
4072
|
+
}
|
|
4073
|
+
}
|
|
4074
|
+
leastRecentlyUsedIdleClient() {
|
|
4075
|
+
let candidate = null;
|
|
4076
|
+
for (const [key, managed] of this.clients) {
|
|
4077
|
+
if (managed.refCount > 0 || managed.pendingWaiters > 0 || managed.isInitializing)
|
|
4078
|
+
continue;
|
|
4079
|
+
if (candidate === null || managed.lastUsedAt < candidate.managed.lastUsedAt) {
|
|
4080
|
+
candidate = { key, managed };
|
|
3961
4081
|
}
|
|
3962
4082
|
}
|
|
4083
|
+
return candidate;
|
|
3963
4084
|
}
|
|
3964
4085
|
async tryDeleteIfOrphaned(key, managed) {
|
|
3965
4086
|
if (managed.refCount === 0 && managed.pendingWaiters === 0 && !managed.isInitializing && this.clients.get(key) === managed) {
|
|
3966
4087
|
this.clients.delete(key);
|
|
3967
|
-
await
|
|
4088
|
+
await this.tombstoneStop(key, managed.client);
|
|
3968
4089
|
}
|
|
3969
4090
|
}
|
|
3970
|
-
async getClient(root,
|
|
4091
|
+
async getClient(root, server, signal) {
|
|
3971
4092
|
if (this.disposed) {
|
|
3972
4093
|
throw new Error("LspManager has been disposed");
|
|
3973
4094
|
}
|
|
3974
4095
|
signal?.throwIfAborted();
|
|
3975
|
-
const key = this.getKey(root,
|
|
4096
|
+
const key = this.getKey(root, server.id);
|
|
4097
|
+
for (;; ) {
|
|
4098
|
+
const pendingStop = this.pendingStops.get(key);
|
|
4099
|
+
if (pendingStop === undefined)
|
|
4100
|
+
break;
|
|
4101
|
+
await awaitWithSignal2(pendingStop, signal);
|
|
4102
|
+
signal?.throwIfAborted();
|
|
4103
|
+
}
|
|
4104
|
+
if (this.disposed) {
|
|
4105
|
+
throw new Error("LspManager has been disposed");
|
|
4106
|
+
}
|
|
3976
4107
|
let managed = this.clients.get(key);
|
|
3977
4108
|
if (managed) {
|
|
3978
4109
|
const t = this.now();
|
|
3979
4110
|
if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
|
|
3980
|
-
await stopClientBestEffort(managed.client);
|
|
3981
4111
|
this.clients.delete(key);
|
|
4112
|
+
await this.tombstoneStop(key, managed.client);
|
|
3982
4113
|
managed = undefined;
|
|
3983
4114
|
}
|
|
3984
4115
|
}
|
|
@@ -3999,15 +4130,21 @@ class LspManager {
|
|
|
3999
4130
|
signal.throwIfAborted();
|
|
4000
4131
|
}
|
|
4001
4132
|
if (!managed.client.isAlive()) {
|
|
4002
|
-
|
|
4003
|
-
this.clients.
|
|
4004
|
-
|
|
4133
|
+
this.recordDeadGeneration(key);
|
|
4134
|
+
if (this.clients.get(key) === managed) {
|
|
4135
|
+
this.clients.delete(key);
|
|
4136
|
+
}
|
|
4137
|
+
await this.tombstoneStop(key, managed.client);
|
|
4138
|
+
return this.getClient(root, server, signal);
|
|
4005
4139
|
}
|
|
4140
|
+
this.markHealthyGeneration(key);
|
|
4006
4141
|
managed.refCount++;
|
|
4007
4142
|
managed.lastUsedAt = this.now();
|
|
4008
4143
|
return managed.client;
|
|
4009
4144
|
}
|
|
4010
|
-
|
|
4145
|
+
this.evictForAdmission();
|
|
4146
|
+
this.ensureRespawnAllowed(key, root, server.id);
|
|
4147
|
+
const client = this.clientFactory(root, server);
|
|
4011
4148
|
const initStartedAt = this.now();
|
|
4012
4149
|
const initPromise = (async () => {
|
|
4013
4150
|
await client.start();
|
|
@@ -4030,7 +4167,7 @@ class LspManager {
|
|
|
4030
4167
|
if (this.clients.get(key) === newManaged) {
|
|
4031
4168
|
this.clients.delete(key);
|
|
4032
4169
|
}
|
|
4033
|
-
await
|
|
4170
|
+
await this.tombstoneStop(key, client);
|
|
4034
4171
|
throw err;
|
|
4035
4172
|
}
|
|
4036
4173
|
newManaged.pendingWaiters--;
|
|
@@ -4041,6 +4178,15 @@ class LspManager {
|
|
|
4041
4178
|
await this.tryDeleteIfOrphaned(key, newManaged);
|
|
4042
4179
|
signal.throwIfAborted();
|
|
4043
4180
|
}
|
|
4181
|
+
if (!client.isAlive()) {
|
|
4182
|
+
this.recordDeadGeneration(key);
|
|
4183
|
+
if (this.clients.get(key) === newManaged) {
|
|
4184
|
+
this.clients.delete(key);
|
|
4185
|
+
}
|
|
4186
|
+
await this.tombstoneStop(key, client);
|
|
4187
|
+
return this.getClient(root, server, signal);
|
|
4188
|
+
}
|
|
4189
|
+
this.markHealthyGeneration(key);
|
|
4044
4190
|
newManaged.refCount++;
|
|
4045
4191
|
newManaged.lastUsedAt = this.now();
|
|
4046
4192
|
return client;
|
|
@@ -4061,15 +4207,21 @@ class LspManager {
|
|
|
4061
4207
|
if (client && managed.client !== client)
|
|
4062
4208
|
return;
|
|
4063
4209
|
this.clients.delete(key);
|
|
4064
|
-
|
|
4210
|
+
this.tombstoneStop(key, managed.client);
|
|
4065
4211
|
}
|
|
4066
|
-
warmupClient(root,
|
|
4212
|
+
warmupClient(root, server) {
|
|
4067
4213
|
if (this.disposed)
|
|
4068
4214
|
return;
|
|
4069
|
-
const key = this.getKey(root,
|
|
4070
|
-
if (this.clients.has(key))
|
|
4215
|
+
const key = this.getKey(root, server.id);
|
|
4216
|
+
if (this.clients.has(key) || this.pendingStops.has(key))
|
|
4217
|
+
return;
|
|
4218
|
+
this.evictForAdmission();
|
|
4219
|
+
try {
|
|
4220
|
+
this.ensureRespawnAllowed(key, root, server.id);
|
|
4221
|
+
} catch {
|
|
4071
4222
|
return;
|
|
4072
|
-
|
|
4223
|
+
}
|
|
4224
|
+
const client = this.clientFactory(root, server);
|
|
4073
4225
|
const initStartedAt = this.now();
|
|
4074
4226
|
const initPromise = (async () => {
|
|
4075
4227
|
await client.start();
|
|
@@ -4094,7 +4246,7 @@ class LspManager {
|
|
|
4094
4246
|
if (this.clients.get(key) === managed) {
|
|
4095
4247
|
this.clients.delete(key);
|
|
4096
4248
|
}
|
|
4097
|
-
|
|
4249
|
+
this.tombstoneStop(key, client);
|
|
4098
4250
|
});
|
|
4099
4251
|
}
|
|
4100
4252
|
isServerInitializing(root, serverId) {
|
|
@@ -4138,8 +4290,11 @@ class LspManager {
|
|
|
4138
4290
|
for (const managed of this.clients.values()) {
|
|
4139
4291
|
stopPromises.push(stopClientBestEffort(managed.client));
|
|
4140
4292
|
}
|
|
4293
|
+
const tombstonedStops = [...this.pendingStops.values()];
|
|
4141
4294
|
this.clients.clear();
|
|
4142
|
-
|
|
4295
|
+
this.respawnBudgets.clear();
|
|
4296
|
+
await Promise.allSettled([...stopPromises, ...tombstonedStops]);
|
|
4297
|
+
this.pendingStops.clear();
|
|
4143
4298
|
}
|
|
4144
4299
|
}
|
|
4145
4300
|
var _defaultInstance = null;
|
|
@@ -4157,57 +4312,52 @@ async function disposeDefaultLspManager() {
|
|
|
4157
4312
|
}
|
|
4158
4313
|
}
|
|
4159
4314
|
|
|
4160
|
-
// ../lsp-core/src/lsp/
|
|
4161
|
-
import { existsSync as existsSync7,
|
|
4162
|
-
import { dirname as dirname7 } from "node:path";
|
|
4163
|
-
|
|
4164
|
-
|
|
4165
|
-
|
|
4166
|
-
|
|
4167
|
-
|
|
4168
|
-
|
|
4169
|
-
|
|
4170
|
-
|
|
4171
|
-
|
|
4172
|
-
|
|
4173
|
-
|
|
4174
|
-
|
|
4315
|
+
// ../lsp-core/src/lsp/outside-context-workspace.ts
|
|
4316
|
+
import { existsSync as existsSync7, realpathSync as realpathSync4 } from "node:fs";
|
|
4317
|
+
import { dirname as dirname7, join as join3 } from "node:path";
|
|
4318
|
+
|
|
4319
|
+
// ../lsp-core/src/lsp/workspace-markers.ts
|
|
4320
|
+
var GIT_WORKSPACE_MARKER = ".git";
|
|
4321
|
+
var PROJECT_WORKSPACE_MARKERS = [
|
|
4322
|
+
"package.json",
|
|
4323
|
+
"pyproject.toml",
|
|
4324
|
+
"Cargo.toml",
|
|
4325
|
+
"go.mod",
|
|
4326
|
+
"pom.xml",
|
|
4327
|
+
"build.gradle"
|
|
4328
|
+
];
|
|
4329
|
+
var WORKSPACE_MARKERS = [GIT_WORKSPACE_MARKER, ...PROJECT_WORKSPACE_MARKERS];
|
|
4330
|
+
|
|
4331
|
+
// ../lsp-core/src/lsp/outside-context-workspace.ts
|
|
4332
|
+
function findWorkspaceRootOutsideContext(directory) {
|
|
4333
|
+
const marked = nearestMarkedAncestor(directory);
|
|
4334
|
+
if (marked !== undefined)
|
|
4335
|
+
return marked;
|
|
4336
|
+
return realpathSync4(nearestExistingAncestor(directory));
|
|
4337
|
+
}
|
|
4338
|
+
function nearestMarkedAncestor(directory) {
|
|
4339
|
+
let current = directory;
|
|
4340
|
+
for (;; ) {
|
|
4341
|
+
if (existsSync7(current) && WORKSPACE_MARKERS.some((marker) => existsSync7(join3(current, marker)))) {
|
|
4342
|
+
return realpathSync4(current);
|
|
4343
|
+
}
|
|
4344
|
+
const parent = dirname7(current);
|
|
4345
|
+
if (parent === current)
|
|
4346
|
+
return;
|
|
4347
|
+
current = parent;
|
|
4175
4348
|
}
|
|
4176
4349
|
}
|
|
4177
|
-
function
|
|
4178
|
-
|
|
4179
|
-
|
|
4180
|
-
|
|
4181
|
-
|
|
4182
|
-
|
|
4183
|
-
|
|
4184
|
-
}
|
|
4185
|
-
|
|
4186
|
-
return value === "declined" || value === "allowed";
|
|
4187
|
-
}
|
|
4188
|
-
function writeInstallDecisions(decisions) {
|
|
4189
|
-
const path2 = getInstallDecisionsPath();
|
|
4190
|
-
mkdirSync3(dirname7(path2), { recursive: true });
|
|
4191
|
-
const tmpPath = `${path2}.tmp`;
|
|
4192
|
-
writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
|
|
4193
|
-
`, "utf8");
|
|
4194
|
-
renameSync2(tmpPath, path2);
|
|
4195
|
-
}
|
|
4196
|
-
function isInstallDecisions(value) {
|
|
4197
|
-
return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
|
|
4198
|
-
}
|
|
4199
|
-
function isInstallDecisionRecord(value) {
|
|
4200
|
-
if (!isRecord5(value))
|
|
4201
|
-
return false;
|
|
4202
|
-
return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
|
|
4203
|
-
}
|
|
4204
|
-
function isRecord5(value) {
|
|
4205
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4350
|
+
function nearestExistingAncestor(directory) {
|
|
4351
|
+
let current = directory;
|
|
4352
|
+
while (!existsSync7(current)) {
|
|
4353
|
+
const parent = dirname7(current);
|
|
4354
|
+
if (parent === current)
|
|
4355
|
+
return current;
|
|
4356
|
+
current = parent;
|
|
4357
|
+
}
|
|
4358
|
+
return current;
|
|
4206
4359
|
}
|
|
4207
4360
|
|
|
4208
|
-
// ../lsp-core/src/lsp/config-loader.ts
|
|
4209
|
-
import { existsSync as existsSync8, readFileSync as readFileSync5 } from "node:fs";
|
|
4210
|
-
|
|
4211
4361
|
// ../lsp-core/src/lsp/server-definitions.ts
|
|
4212
4362
|
var LSP_INSTALL_HINTS = {
|
|
4213
4363
|
typescript: "npm install -g typescript-language-server typescript",
|
|
@@ -4253,6 +4403,26 @@ var LSP_INSTALL_HINTS = {
|
|
|
4253
4403
|
julials: `julia -e 'using Pkg; Pkg.add("LanguageServer")'`,
|
|
4254
4404
|
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"
|
|
4255
4405
|
};
|
|
4406
|
+
var LSP_LOCAL_INSTALL_HINTS = {
|
|
4407
|
+
typescript: "bun add -d typescript-language-server typescript",
|
|
4408
|
+
vue: "bun add -d @vue/language-server",
|
|
4409
|
+
eslint: "bun add -d vscode-langservers-extracted",
|
|
4410
|
+
oxlint: "bun add -d oxlint",
|
|
4411
|
+
biome: "bun add -d @biomejs/biome",
|
|
4412
|
+
svelte: "bun add -d svelte-language-server",
|
|
4413
|
+
astro: "bun add -d @astrojs/language-server",
|
|
4414
|
+
bash: "bun add -d bash-language-server",
|
|
4415
|
+
"bash-ls": "bun add -d bash-language-server",
|
|
4416
|
+
"yaml-ls": "bun add -d yaml-language-server",
|
|
4417
|
+
php: "bun add -d intelephense",
|
|
4418
|
+
prisma: "bun add -d prisma",
|
|
4419
|
+
dockerfile: "bun add -d dockerfile-language-server-nodejs",
|
|
4420
|
+
pyright: "uv add --dev pyright",
|
|
4421
|
+
basedpyright: "uv add --dev basedpyright",
|
|
4422
|
+
ruff: "uv add --dev ruff",
|
|
4423
|
+
ty: "uv add --dev ty",
|
|
4424
|
+
"ruby-lsp": "bundle add ruby-lsp --group development"
|
|
4425
|
+
};
|
|
4256
4426
|
var BUILTIN_SERVERS = {
|
|
4257
4427
|
typescript: {
|
|
4258
4428
|
command: ["typescript-language-server", "--stdio"],
|
|
@@ -4355,18 +4525,67 @@ var BUILTIN_SERVERS = {
|
|
|
4355
4525
|
}
|
|
4356
4526
|
};
|
|
4357
4527
|
|
|
4528
|
+
// ../lsp-core/src/lsp/server-install-state.ts
|
|
4529
|
+
import { existsSync as existsSync8, mkdirSync as mkdirSync3, readFileSync as readFileSync4, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
4530
|
+
import { dirname as dirname8 } from "node:path";
|
|
4531
|
+
function getInstallDecisionsPath() {
|
|
4532
|
+
return lspRequestContext().installDecisionsPath;
|
|
4533
|
+
}
|
|
4534
|
+
function loadInstallDecisions() {
|
|
4535
|
+
const path = getInstallDecisionsPath();
|
|
4536
|
+
if (!existsSync8(path))
|
|
4537
|
+
return {};
|
|
4538
|
+
try {
|
|
4539
|
+
const parsed = JSON.parse(readFileSync4(path, "utf8"));
|
|
4540
|
+
return isInstallDecisions(parsed) ? parsed : {};
|
|
4541
|
+
} catch {
|
|
4542
|
+
return {};
|
|
4543
|
+
}
|
|
4544
|
+
}
|
|
4545
|
+
function loadInstallDecision(serverId) {
|
|
4546
|
+
return loadInstallDecisions()[serverId];
|
|
4547
|
+
}
|
|
4548
|
+
function recordInstallDecision(serverId, decision, decidedAt = new Date().toISOString()) {
|
|
4549
|
+
const decisions = loadInstallDecisions();
|
|
4550
|
+
decisions[serverId] = { decision, decidedAt };
|
|
4551
|
+
writeInstallDecisions(decisions);
|
|
4552
|
+
}
|
|
4553
|
+
function isInstallDecision(value) {
|
|
4554
|
+
return value === "declined" || value === "allowed";
|
|
4555
|
+
}
|
|
4556
|
+
function writeInstallDecisions(decisions) {
|
|
4557
|
+
const path = getInstallDecisionsPath();
|
|
4558
|
+
mkdirSync3(dirname8(path), { recursive: true });
|
|
4559
|
+
const tmpPath = `${path}.tmp`;
|
|
4560
|
+
writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
|
|
4561
|
+
`, "utf8");
|
|
4562
|
+
renameSync2(tmpPath, path);
|
|
4563
|
+
}
|
|
4564
|
+
function isInstallDecisions(value) {
|
|
4565
|
+
return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
|
|
4566
|
+
}
|
|
4567
|
+
function isInstallDecisionRecord(value) {
|
|
4568
|
+
if (!isRecord5(value))
|
|
4569
|
+
return false;
|
|
4570
|
+
return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
|
|
4571
|
+
}
|
|
4572
|
+
function isRecord5(value) {
|
|
4573
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4574
|
+
}
|
|
4575
|
+
|
|
4358
4576
|
// ../lsp-core/src/lsp/config-loader.ts
|
|
4577
|
+
import { existsSync as existsSync9, readFileSync as readFileSync5 } from "node:fs";
|
|
4359
4578
|
function getProjectConfigPaths() {
|
|
4360
4579
|
return lspRequestContext().projectConfigPaths;
|
|
4361
4580
|
}
|
|
4362
4581
|
function getUserConfigPath() {
|
|
4363
4582
|
return lspRequestContext().userConfigPath;
|
|
4364
4583
|
}
|
|
4365
|
-
function loadJsonFile(
|
|
4366
|
-
if (!
|
|
4584
|
+
function loadJsonFile(path) {
|
|
4585
|
+
if (!existsSync9(path))
|
|
4367
4586
|
return null;
|
|
4368
4587
|
try {
|
|
4369
|
-
const parsed = JSON.parse(readFileSync5(
|
|
4588
|
+
const parsed = JSON.parse(readFileSync5(path, "utf-8"));
|
|
4370
4589
|
return isConfigJson(parsed) ? parsed : null;
|
|
4371
4590
|
} catch {
|
|
4372
4591
|
return null;
|
|
@@ -4383,8 +4602,8 @@ function loadAllConfigs() {
|
|
|
4383
4602
|
return configs;
|
|
4384
4603
|
}
|
|
4385
4604
|
function loadFirstJsonFile(paths) {
|
|
4386
|
-
for (const
|
|
4387
|
-
const config = loadJsonFile(
|
|
4605
|
+
for (const path of paths) {
|
|
4606
|
+
const config = loadJsonFile(path);
|
|
4388
4607
|
if (config)
|
|
4389
4608
|
return config;
|
|
4390
4609
|
}
|
|
@@ -4410,10 +4629,10 @@ function getMergedServers() {
|
|
|
4410
4629
|
}
|
|
4411
4630
|
if (seen.has(id))
|
|
4412
4631
|
continue;
|
|
4413
|
-
const
|
|
4414
|
-
if (!
|
|
4632
|
+
const server = createServerFromEntry(id, entry, source);
|
|
4633
|
+
if (!server)
|
|
4415
4634
|
continue;
|
|
4416
|
-
servers.push(
|
|
4635
|
+
servers.push(server);
|
|
4417
4636
|
seen.add(id);
|
|
4418
4637
|
}
|
|
4419
4638
|
}
|
|
@@ -4445,7 +4664,7 @@ function createServerFromEntry(id, entry, source) {
|
|
|
4445
4664
|
if (source === "project") {
|
|
4446
4665
|
if (!builtin)
|
|
4447
4666
|
return null;
|
|
4448
|
-
const
|
|
4667
|
+
const server = createServer({
|
|
4449
4668
|
id,
|
|
4450
4669
|
command: builtin.command,
|
|
4451
4670
|
extensions: entry.extensions ?? builtin.extensions,
|
|
@@ -4453,35 +4672,35 @@ function createServerFromEntry(id, entry, source) {
|
|
|
4453
4672
|
source
|
|
4454
4673
|
});
|
|
4455
4674
|
if (entry.initialization !== undefined) {
|
|
4456
|
-
|
|
4675
|
+
server.initialization = entry.initialization;
|
|
4457
4676
|
}
|
|
4458
|
-
return
|
|
4677
|
+
return server;
|
|
4459
4678
|
}
|
|
4460
4679
|
if (entry.command && entry.extensions) {
|
|
4461
|
-
const
|
|
4680
|
+
const server = createServer({
|
|
4462
4681
|
id,
|
|
4463
4682
|
command: entry.command,
|
|
4464
4683
|
extensions: entry.extensions,
|
|
4465
4684
|
priority: entry.priority ?? 0,
|
|
4466
4685
|
source
|
|
4467
4686
|
});
|
|
4468
|
-
applyOptionalServerFields(
|
|
4469
|
-
return
|
|
4687
|
+
applyOptionalServerFields(server, entry);
|
|
4688
|
+
return server;
|
|
4470
4689
|
}
|
|
4471
4690
|
if (!builtin)
|
|
4472
4691
|
return null;
|
|
4473
|
-
const
|
|
4692
|
+
const server = createServer({
|
|
4474
4693
|
id,
|
|
4475
4694
|
command: entry.command ?? builtin.command,
|
|
4476
4695
|
extensions: entry.extensions ?? builtin.extensions,
|
|
4477
4696
|
priority: entry.priority ?? 0,
|
|
4478
4697
|
source
|
|
4479
4698
|
});
|
|
4480
|
-
applyOptionalServerFields(
|
|
4481
|
-
return
|
|
4699
|
+
applyOptionalServerFields(server, entry);
|
|
4700
|
+
return server;
|
|
4482
4701
|
}
|
|
4483
4702
|
function createServer(input) {
|
|
4484
|
-
const
|
|
4703
|
+
const server = {
|
|
4485
4704
|
id: input.id,
|
|
4486
4705
|
command: input.command,
|
|
4487
4706
|
extensions: input.extensions,
|
|
@@ -4489,19 +4708,19 @@ function createServer(input) {
|
|
|
4489
4708
|
source: input.source
|
|
4490
4709
|
};
|
|
4491
4710
|
if (input.env !== undefined) {
|
|
4492
|
-
|
|
4711
|
+
server.env = input.env;
|
|
4493
4712
|
}
|
|
4494
4713
|
if (input.initialization !== undefined) {
|
|
4495
|
-
|
|
4714
|
+
server.initialization = input.initialization;
|
|
4496
4715
|
}
|
|
4497
|
-
return
|
|
4716
|
+
return server;
|
|
4498
4717
|
}
|
|
4499
|
-
function applyOptionalServerFields(
|
|
4718
|
+
function applyOptionalServerFields(server, entry) {
|
|
4500
4719
|
if (entry.env !== undefined) {
|
|
4501
|
-
|
|
4720
|
+
server.env = entry.env;
|
|
4502
4721
|
}
|
|
4503
4722
|
if (entry.initialization !== undefined) {
|
|
4504
|
-
|
|
4723
|
+
server.initialization = entry.initialization;
|
|
4505
4724
|
}
|
|
4506
4725
|
}
|
|
4507
4726
|
function isConfigJson(value) {
|
|
@@ -4551,64 +4770,165 @@ function getDisabledServerIds() {
|
|
|
4551
4770
|
}
|
|
4552
4771
|
|
|
4553
4772
|
// ../lsp-core/src/lsp/server-installation.ts
|
|
4554
|
-
import { existsSync as
|
|
4555
|
-
import { delimiter as delimiter3, join as
|
|
4556
|
-
|
|
4557
|
-
|
|
4558
|
-
|
|
4559
|
-
|
|
4560
|
-
|
|
4561
|
-
|
|
4562
|
-
|
|
4563
|
-
|
|
4564
|
-
|
|
4773
|
+
import { existsSync as existsSync10 } from "node:fs";
|
|
4774
|
+
import { delimiter as delimiter3, dirname as dirname9, isAbsolute as isAbsolute5, join as join4, resolve as resolve7 } from "node:path";
|
|
4775
|
+
var LOCAL_BIN_RULES = [
|
|
4776
|
+
{
|
|
4777
|
+
markers: ["package.json", "bun.lock", "bun.lockb", "package-lock.json", "yarn.lock", "pnpm-lock.yaml"],
|
|
4778
|
+
binDirs: [join4("node_modules", ".bin")]
|
|
4779
|
+
},
|
|
4780
|
+
{
|
|
4781
|
+
markers: [
|
|
4782
|
+
"pyproject.toml",
|
|
4783
|
+
"ty.toml",
|
|
4784
|
+
"requirements.txt",
|
|
4785
|
+
"setup.py",
|
|
4786
|
+
"setup.cfg",
|
|
4787
|
+
"Pipfile",
|
|
4788
|
+
"pyrightconfig.json",
|
|
4789
|
+
"ruff.toml",
|
|
4790
|
+
".ruff.toml"
|
|
4791
|
+
],
|
|
4792
|
+
binDirs: [
|
|
4793
|
+
join4(".venv", "bin"),
|
|
4794
|
+
join4(".venv", "Scripts"),
|
|
4795
|
+
join4("venv", "bin"),
|
|
4796
|
+
join4("venv", "Scripts"),
|
|
4797
|
+
join4(".env", "bin"),
|
|
4798
|
+
join4(".env", "Scripts")
|
|
4799
|
+
]
|
|
4800
|
+
},
|
|
4801
|
+
{
|
|
4802
|
+
markers: ["Gemfile", "Gemfile.lock"],
|
|
4803
|
+
binDirs: [join4("vendor", "bundle", "bin"), "bin"]
|
|
4804
|
+
},
|
|
4805
|
+
{
|
|
4806
|
+
markers: ["go.mod", "go.sum", "go.work"],
|
|
4807
|
+
binDirs: ["bin"]
|
|
4808
|
+
}
|
|
4809
|
+
];
|
|
4810
|
+
var resolutionCache = new Map;
|
|
4811
|
+
var probeCount = 0;
|
|
4812
|
+
function probe(path) {
|
|
4813
|
+
probeCount += 1;
|
|
4814
|
+
return existsSync10(path);
|
|
4815
|
+
}
|
|
4816
|
+
function executableSuffixes(platform, pathExt) {
|
|
4817
|
+
if (platform !== "win32")
|
|
4818
|
+
return [""];
|
|
4819
|
+
const configured = pathExt ?? process.env["PATHEXT"] ?? "";
|
|
4820
|
+
const systemExts = configured.split(";").filter((entry) => entry.length > 0).map((entry) => entry.toLowerCase());
|
|
4821
|
+
return [...new Set(["", ...systemExts, ".exe", ".cmd", ".bat", ".ps1"])];
|
|
4822
|
+
}
|
|
4823
|
+
function probeWithSuffixes(directory, command, suffixes) {
|
|
4824
|
+
for (const suffix of suffixes) {
|
|
4825
|
+
const candidate = join4(directory, command + suffix);
|
|
4826
|
+
if (probe(candidate))
|
|
4827
|
+
return candidate;
|
|
4565
4828
|
}
|
|
4566
|
-
|
|
4567
|
-
|
|
4568
|
-
|
|
4569
|
-
|
|
4570
|
-
|
|
4571
|
-
|
|
4572
|
-
|
|
4573
|
-
|
|
4574
|
-
|
|
4829
|
+
return null;
|
|
4830
|
+
}
|
|
4831
|
+
function resolveLocal(command, workingDirectory, suffixes, stopAt) {
|
|
4832
|
+
const boundary = stopAt === undefined ? undefined : resolve7(stopAt);
|
|
4833
|
+
let current = resolve7(workingDirectory);
|
|
4834
|
+
while (true) {
|
|
4835
|
+
for (const rule of LOCAL_BIN_RULES) {
|
|
4836
|
+
if (!rule.markers.some((marker) => probe(join4(current, marker))))
|
|
4837
|
+
continue;
|
|
4838
|
+
for (const binDir of rule.binDirs) {
|
|
4839
|
+
const found = probeWithSuffixes(join4(current, binDir), command, suffixes);
|
|
4840
|
+
if (found !== null)
|
|
4841
|
+
return found;
|
|
4842
|
+
}
|
|
4575
4843
|
}
|
|
4844
|
+
if (probe(join4(current, ".git")))
|
|
4845
|
+
return null;
|
|
4846
|
+
if (boundary !== undefined && current === boundary)
|
|
4847
|
+
return null;
|
|
4848
|
+
const parent = dirname9(current);
|
|
4849
|
+
if (parent === current)
|
|
4850
|
+
return null;
|
|
4851
|
+
current = parent;
|
|
4576
4852
|
}
|
|
4577
|
-
|
|
4578
|
-
|
|
4853
|
+
}
|
|
4854
|
+
function resolveFromPath(command, suffixes, platform, pathEnvOverride) {
|
|
4855
|
+
let pathEnv = pathEnvOverride ?? process.env["PATH"] ?? "";
|
|
4856
|
+
if (platform === "win32" && !pathEnv) {
|
|
4579
4857
|
pathEnv = process.env["Path"] ?? "";
|
|
4580
4858
|
}
|
|
4581
|
-
const
|
|
4582
|
-
|
|
4583
|
-
|
|
4584
|
-
|
|
4585
|
-
|
|
4586
|
-
|
|
4587
|
-
}
|
|
4859
|
+
for (const entry of pathEnv.split(delimiter3)) {
|
|
4860
|
+
if (entry.length === 0)
|
|
4861
|
+
continue;
|
|
4862
|
+
const found = probeWithSuffixes(entry, command, suffixes);
|
|
4863
|
+
if (found !== null)
|
|
4864
|
+
return found;
|
|
4588
4865
|
}
|
|
4589
|
-
|
|
4590
|
-
|
|
4591
|
-
|
|
4866
|
+
return null;
|
|
4867
|
+
}
|
|
4868
|
+
function resolveServerBinary(command, workingDirectory, options = {}) {
|
|
4869
|
+
if (command.length === 0)
|
|
4870
|
+
return null;
|
|
4871
|
+
const [cmd] = command;
|
|
4872
|
+
if (cmd === undefined || cmd.length === 0)
|
|
4873
|
+
return null;
|
|
4874
|
+
const platform = options.platform ?? process.platform;
|
|
4875
|
+
const suffixes = executableSuffixes(platform, options.pathExt);
|
|
4876
|
+
if (cmd.includes("/") || cmd.includes("\\")) {
|
|
4877
|
+
const explicit = isAbsolute5(cmd) ? cmd : resolve7(workingDirectory ?? process.cwd(), cmd);
|
|
4878
|
+
return probe(explicit) ? explicit : null;
|
|
4879
|
+
}
|
|
4880
|
+
const cacheKey = JSON.stringify([
|
|
4881
|
+
workingDirectory ?? "",
|
|
4882
|
+
cmd,
|
|
4883
|
+
platform,
|
|
4884
|
+
options.stopAt ?? "",
|
|
4885
|
+
options.pathExt ?? "",
|
|
4886
|
+
options.pathEnv ?? process.env["PATH"] ?? ""
|
|
4887
|
+
]);
|
|
4888
|
+
const cached = resolutionCache.get(cacheKey);
|
|
4889
|
+
if (cached !== undefined)
|
|
4890
|
+
return cached;
|
|
4891
|
+
let resolved = null;
|
|
4892
|
+
if (workingDirectory !== undefined && workingDirectory.length > 0) {
|
|
4893
|
+
resolved = resolveLocal(cmd, workingDirectory, suffixes, options.stopAt);
|
|
4894
|
+
}
|
|
4895
|
+
resolved ??= resolveFromPath(cmd, suffixes, platform, options.pathEnv);
|
|
4896
|
+
if (resolved === null && cmd === "node")
|
|
4897
|
+
resolved = cmd;
|
|
4898
|
+
resolutionCache.set(cacheKey, resolved);
|
|
4899
|
+
return resolved;
|
|
4900
|
+
}
|
|
4901
|
+
function isServerInstalled(command, workingDirectory, options = {}) {
|
|
4902
|
+
if (command.length === 0)
|
|
4903
|
+
return false;
|
|
4904
|
+
return resolveServerBinary(command, workingDirectory, options) !== null;
|
|
4592
4905
|
}
|
|
4593
4906
|
|
|
4594
4907
|
// ../lsp-core/src/lsp/server-resolution.ts
|
|
4908
|
+
function withResolvedCommand(command, binaryPath) {
|
|
4909
|
+
return [binaryPath, ...command.slice(1)];
|
|
4910
|
+
}
|
|
4595
4911
|
function findServerForExtension(ext) {
|
|
4596
4912
|
const servers = getMergedServers();
|
|
4597
|
-
|
|
4598
|
-
|
|
4913
|
+
const workingDirectory = contextCwd();
|
|
4914
|
+
for (const server of servers) {
|
|
4915
|
+
if (!server.extensions.includes(ext))
|
|
4916
|
+
continue;
|
|
4917
|
+
const binaryPath = resolveServerBinary(server.command, workingDirectory);
|
|
4918
|
+
if (binaryPath !== null) {
|
|
4599
4919
|
const resolvedServer = {
|
|
4600
|
-
id:
|
|
4601
|
-
command:
|
|
4602
|
-
extensions:
|
|
4603
|
-
priority:
|
|
4920
|
+
id: server.id,
|
|
4921
|
+
command: withResolvedCommand(server.command, binaryPath),
|
|
4922
|
+
extensions: server.extensions,
|
|
4923
|
+
priority: server.priority
|
|
4604
4924
|
};
|
|
4605
|
-
if (
|
|
4925
|
+
if (server.env !== undefined) {
|
|
4606
4926
|
return {
|
|
4607
4927
|
status: "found",
|
|
4608
4928
|
server: {
|
|
4609
4929
|
...resolvedServer,
|
|
4610
|
-
env:
|
|
4611
|
-
...
|
|
4930
|
+
env: server.env,
|
|
4931
|
+
...server.initialization === undefined ? {} : { initialization: server.initialization }
|
|
4612
4932
|
}
|
|
4613
4933
|
};
|
|
4614
4934
|
}
|
|
@@ -4616,20 +4936,20 @@ function findServerForExtension(ext) {
|
|
|
4616
4936
|
status: "found",
|
|
4617
4937
|
server: {
|
|
4618
4938
|
...resolvedServer,
|
|
4619
|
-
...
|
|
4939
|
+
...server.initialization === undefined ? {} : { initialization: server.initialization }
|
|
4620
4940
|
}
|
|
4621
4941
|
};
|
|
4622
4942
|
}
|
|
4623
4943
|
}
|
|
4624
|
-
for (const
|
|
4625
|
-
if (
|
|
4626
|
-
const installHint = LSP_INSTALL_HINTS[
|
|
4944
|
+
for (const server of servers) {
|
|
4945
|
+
if (server.extensions.includes(ext)) {
|
|
4946
|
+
const installHint = LSP_INSTALL_HINTS[server.id] ?? `Install '${server.command[0]}' and ensure it's in your PATH`;
|
|
4627
4947
|
return {
|
|
4628
4948
|
status: "not_installed",
|
|
4629
4949
|
server: {
|
|
4630
|
-
id:
|
|
4631
|
-
command:
|
|
4632
|
-
extensions:
|
|
4950
|
+
id: server.id,
|
|
4951
|
+
command: server.command,
|
|
4952
|
+
extensions: server.extensions
|
|
4633
4953
|
},
|
|
4634
4954
|
installHint
|
|
4635
4955
|
};
|
|
@@ -4645,20 +4965,21 @@ function findServerForExtension(ext) {
|
|
|
4645
4965
|
function getAllServers() {
|
|
4646
4966
|
const servers = getMergedServers();
|
|
4647
4967
|
const disabled = getDisabledServerIds();
|
|
4968
|
+
const workingDirectory = contextCwd();
|
|
4648
4969
|
const result = [];
|
|
4649
4970
|
const seen = new Set;
|
|
4650
|
-
for (const
|
|
4651
|
-
if (seen.has(
|
|
4971
|
+
for (const server of servers) {
|
|
4972
|
+
if (seen.has(server.id))
|
|
4652
4973
|
continue;
|
|
4653
4974
|
result.push({
|
|
4654
|
-
id:
|
|
4655
|
-
installed: isServerInstalled(
|
|
4656
|
-
extensions:
|
|
4975
|
+
id: server.id,
|
|
4976
|
+
installed: isServerInstalled(server.command, workingDirectory),
|
|
4977
|
+
extensions: server.extensions,
|
|
4657
4978
|
disabled: false,
|
|
4658
|
-
source:
|
|
4659
|
-
priority:
|
|
4979
|
+
source: server.source,
|
|
4980
|
+
priority: server.priority
|
|
4660
4981
|
});
|
|
4661
|
-
seen.add(
|
|
4982
|
+
seen.add(server.id);
|
|
4662
4983
|
}
|
|
4663
4984
|
for (const id of disabled) {
|
|
4664
4985
|
if (seen.has(id))
|
|
@@ -4666,7 +4987,7 @@ function getAllServers() {
|
|
|
4666
4987
|
const builtin = BUILTIN_SERVERS[id];
|
|
4667
4988
|
result.push({
|
|
4668
4989
|
id,
|
|
4669
|
-
installed: builtin ? isServerInstalled(builtin.command) : false,
|
|
4990
|
+
installed: builtin ? isServerInstalled(builtin.command, workingDirectory) : false,
|
|
4670
4991
|
extensions: builtin?.extensions ?? [],
|
|
4671
4992
|
disabled: true,
|
|
4672
4993
|
source: "disabled",
|
|
@@ -4677,7 +4998,6 @@ function getAllServers() {
|
|
|
4677
4998
|
}
|
|
4678
4999
|
|
|
4679
5000
|
// ../lsp-core/src/lsp/client-wrapper.ts
|
|
4680
|
-
var WORKSPACE_MARKERS = [".git", "package.json", "pyproject.toml", "Cargo.toml", "go.mod", "pom.xml", "build.gradle"];
|
|
4681
5001
|
function isDirectoryPath(filePath) {
|
|
4682
5002
|
try {
|
|
4683
5003
|
return statSync4(filePath).isDirectory();
|
|
@@ -4690,36 +5010,40 @@ function findWorkspaceRoot(filePath) {
|
|
|
4690
5010
|
const abs = resolveReadablePathInsideContext(filePath);
|
|
4691
5011
|
let dir = abs;
|
|
4692
5012
|
if (!isDirectoryPath(dir)) {
|
|
4693
|
-
dir =
|
|
5013
|
+
dir = dirname10(dir);
|
|
4694
5014
|
}
|
|
5015
|
+
if (!isPathInside(cwd, abs))
|
|
5016
|
+
return findWorkspaceRootOutsideContext(dir);
|
|
4695
5017
|
const fallbackRoot = nearestExistingDirectoryInsideContext(dir, cwd) ?? cwd;
|
|
5018
|
+
let nearestPackageRoot;
|
|
4696
5019
|
while (isPathInside(cwd, dir)) {
|
|
4697
5020
|
const canonicalDir = existingDirectoryInsideContext(dir, cwd);
|
|
4698
5021
|
if (canonicalDir !== undefined) {
|
|
4699
|
-
|
|
4700
|
-
|
|
4701
|
-
|
|
4702
|
-
|
|
5022
|
+
if (existsSync11(join5(dir, GIT_WORKSPACE_MARKER))) {
|
|
5023
|
+
return canonicalDir;
|
|
5024
|
+
}
|
|
5025
|
+
if (nearestPackageRoot === undefined && hasProjectWorkspaceMarker(dir)) {
|
|
5026
|
+
nearestPackageRoot = canonicalDir;
|
|
4703
5027
|
}
|
|
4704
5028
|
}
|
|
4705
5029
|
if (dir === cwd)
|
|
4706
5030
|
break;
|
|
4707
|
-
dir =
|
|
5031
|
+
dir = dirname10(dir);
|
|
4708
5032
|
}
|
|
4709
|
-
return fallbackRoot;
|
|
5033
|
+
return nearestPackageRoot ?? fallbackRoot;
|
|
5034
|
+
}
|
|
5035
|
+
function hasProjectWorkspaceMarker(directory) {
|
|
5036
|
+
return PROJECT_WORKSPACE_MARKERS.some((marker) => existsSync11(join5(directory, marker)));
|
|
4710
5037
|
}
|
|
4711
5038
|
function resolveReadablePathInsideContext(filePath) {
|
|
4712
5039
|
const cwd = contextCwd();
|
|
4713
|
-
const abs =
|
|
5040
|
+
const abs = resolve8(cwd, filePath);
|
|
4714
5041
|
if (isPathInside(cwd, abs))
|
|
4715
5042
|
return abs;
|
|
4716
5043
|
const rebased = rebaseThroughCanonicalAncestor(abs, cwd);
|
|
4717
5044
|
if (rebased !== undefined)
|
|
4718
5045
|
return rebased;
|
|
4719
|
-
|
|
4720
|
-
if (isPathInside(cwd, canonical))
|
|
4721
|
-
return canonical;
|
|
4722
|
-
throw new LspInvalidPathError(`LSP file path must be inside request cwd: ${filePath}`);
|
|
5046
|
+
return canonicalizeExistingOrNearestAncestor(abs);
|
|
4723
5047
|
}
|
|
4724
5048
|
function resolvePathInsideContext(filePath) {
|
|
4725
5049
|
const cwd = contextCwd();
|
|
@@ -4730,16 +5054,16 @@ function resolvePathInsideContext(filePath) {
|
|
|
4730
5054
|
}
|
|
4731
5055
|
return canonical;
|
|
4732
5056
|
}
|
|
4733
|
-
function rebaseThroughCanonicalAncestor(
|
|
4734
|
-
let current =
|
|
5057
|
+
function rebaseThroughCanonicalAncestor(path, cwd) {
|
|
5058
|
+
let current = path;
|
|
4735
5059
|
const suffix = [];
|
|
4736
5060
|
while (true) {
|
|
4737
|
-
if (
|
|
4738
|
-
const canonical =
|
|
5061
|
+
if (existsSync11(current)) {
|
|
5062
|
+
const canonical = realpathSync5(current);
|
|
4739
5063
|
if (isPathInside(cwd, canonical))
|
|
4740
|
-
return suffix.length === 0 ? canonical :
|
|
5064
|
+
return suffix.length === 0 ? canonical : join5(canonical, ...suffix);
|
|
4741
5065
|
}
|
|
4742
|
-
const parent =
|
|
5066
|
+
const parent = dirname10(current);
|
|
4743
5067
|
if (parent === current)
|
|
4744
5068
|
return;
|
|
4745
5069
|
suffix.unshift(basename3(current));
|
|
@@ -4747,9 +5071,9 @@ function rebaseThroughCanonicalAncestor(path2, cwd) {
|
|
|
4747
5071
|
}
|
|
4748
5072
|
}
|
|
4749
5073
|
function existingDirectoryInsideContext(directory, cwd) {
|
|
4750
|
-
if (!
|
|
5074
|
+
if (!existsSync11(directory))
|
|
4751
5075
|
return;
|
|
4752
|
-
const canonical =
|
|
5076
|
+
const canonical = realpathSync5(directory);
|
|
4753
5077
|
if (!statSync4(canonical).isDirectory())
|
|
4754
5078
|
return;
|
|
4755
5079
|
return isPathInside(cwd, canonical) ? canonical : undefined;
|
|
@@ -4762,7 +5086,7 @@ function nearestExistingDirectoryInsideContext(directory, cwd) {
|
|
|
4762
5086
|
return canonical;
|
|
4763
5087
|
if (current === cwd)
|
|
4764
5088
|
return;
|
|
4765
|
-
current =
|
|
5089
|
+
current = dirname10(current);
|
|
4766
5090
|
}
|
|
4767
5091
|
return;
|
|
4768
5092
|
}
|
|
@@ -4789,33 +5113,46 @@ function formatServerLookupError(result) {
|
|
|
4789
5113
|
].join(`
|
|
4790
5114
|
`);
|
|
4791
5115
|
}
|
|
5116
|
+
function formatInstallOptions(serverId, installHint) {
|
|
5117
|
+
const localHint = LSP_LOCAL_INSTALL_HINTS[serverId];
|
|
5118
|
+
if (localHint === undefined) {
|
|
5119
|
+
return ["To install, run:", ` ${installHint}`];
|
|
5120
|
+
}
|
|
5121
|
+
return [
|
|
5122
|
+
"To install in THIS repository (preferred — no global install needed):",
|
|
5123
|
+
` ${localHint}`,
|
|
5124
|
+
"",
|
|
5125
|
+
"Or install it globally:",
|
|
5126
|
+
` ${installHint}`
|
|
5127
|
+
];
|
|
5128
|
+
}
|
|
4792
5129
|
function formatNotInstalled(result) {
|
|
4793
|
-
const { server
|
|
4794
|
-
const extensions =
|
|
4795
|
-
const decision = loadInstallDecision(
|
|
5130
|
+
const { server, installHint } = result;
|
|
5131
|
+
const extensions = server.extensions.join(", ");
|
|
5132
|
+
const decision = loadInstallDecision(server.id)?.decision;
|
|
4796
5133
|
const context = lspRequestContext();
|
|
4797
5134
|
if (decision === "declined") {
|
|
4798
|
-
return `LSP server '${
|
|
5135
|
+
return `LSP server '${server.id}' (${extensions}) is NOT INSTALLED; user previously declined installation — proceed without LSP.`;
|
|
4799
5136
|
}
|
|
4800
5137
|
const header = [
|
|
4801
|
-
`LSP server '${
|
|
5138
|
+
`LSP server '${server.id}' for ${extensions} is NOT INSTALLED.`,
|
|
4802
5139
|
"",
|
|
4803
|
-
`Command not found: ${
|
|
5140
|
+
`Command not found: ${server.command[0]}`,
|
|
4804
5141
|
""
|
|
4805
5142
|
];
|
|
5143
|
+
const installOptions = formatInstallOptions(server.id, installHint);
|
|
4806
5144
|
if (decision === "allowed") {
|
|
4807
5145
|
return [
|
|
4808
5146
|
...header,
|
|
4809
5147
|
"The user has pre-authorized LSP installation. Run the install command, then retry this tool:",
|
|
4810
|
-
|
|
5148
|
+
...installOptions.slice(1)
|
|
4811
5149
|
].join(`
|
|
4812
5150
|
`);
|
|
4813
5151
|
}
|
|
4814
5152
|
if (!context.capabilities.installDecisionTool) {
|
|
4815
5153
|
return [
|
|
4816
5154
|
...header,
|
|
4817
|
-
|
|
4818
|
-
` ${installHint}`,
|
|
5155
|
+
...installOptions,
|
|
4819
5156
|
"",
|
|
4820
5157
|
"ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
|
|
4821
5158
|
"Install-decision recording is unavailable in this harness; proceed without LSP if the user declines."
|
|
@@ -4824,13 +5161,12 @@ function formatNotInstalled(result) {
|
|
|
4824
5161
|
}
|
|
4825
5162
|
return [
|
|
4826
5163
|
...header,
|
|
4827
|
-
|
|
4828
|
-
` ${installHint}`,
|
|
5164
|
+
...installOptions,
|
|
4829
5165
|
"",
|
|
4830
5166
|
"ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
|
|
4831
5167
|
"- If the user agrees: run the install command above, then retry this tool.",
|
|
4832
5168
|
"- If the user declines, OR has NOT explicitly asked for LSP installation:",
|
|
4833
|
-
` call lsp_install_decision { server_id: "${
|
|
5169
|
+
` call lsp_install_decision { server_id: "${server.id}", decision: "declined" },`,
|
|
4834
5170
|
` which writes to ${context.installDecisionsPath},`,
|
|
4835
5171
|
" then ignore this message and proceed WITHOUT LSP."
|
|
4836
5172
|
].join(`
|
|
@@ -4854,34 +5190,34 @@ async function withLspClient(filePath, fn, toolName, options = {}) {
|
|
|
4854
5190
|
if (result.status !== "found") {
|
|
4855
5191
|
throw new LspServerLookupError(formatServerLookupError(result), result);
|
|
4856
5192
|
}
|
|
4857
|
-
const
|
|
5193
|
+
const server = result.server;
|
|
4858
5194
|
const root = findWorkspaceRoot(absPath);
|
|
4859
5195
|
const manager = options.manager ?? getLspManager();
|
|
4860
5196
|
const acquireAndCall = async (allowRetry) => {
|
|
4861
|
-
const client = await manager.getClient(root,
|
|
5197
|
+
const client = await manager.getClient(root, server, options.signal);
|
|
4862
5198
|
try {
|
|
4863
5199
|
return await fn(client, root, absPath);
|
|
4864
5200
|
} catch (err) {
|
|
4865
5201
|
if (allowRetry && READ_ONLY_TOOLS.has(toolName) && isLspDeadConnectionError(err)) {
|
|
4866
|
-
manager.invalidateClient(root,
|
|
5202
|
+
manager.invalidateClient(root, server.id, client);
|
|
4867
5203
|
return acquireAndCall(false);
|
|
4868
5204
|
}
|
|
4869
5205
|
if (err instanceof LspRequestTimeoutError) {
|
|
4870
|
-
if (manager.isServerInitializing(root,
|
|
5206
|
+
if (manager.isServerInitializing(root, server.id)) {
|
|
4871
5207
|
throw new LspServerInitializingError(err);
|
|
4872
5208
|
}
|
|
4873
5209
|
}
|
|
4874
5210
|
throw err;
|
|
4875
5211
|
} finally {
|
|
4876
|
-
manager.releaseClient(root,
|
|
5212
|
+
manager.releaseClient(root, server.id);
|
|
4877
5213
|
}
|
|
4878
5214
|
};
|
|
4879
5215
|
return acquireAndCall(true);
|
|
4880
5216
|
}
|
|
4881
5217
|
|
|
4882
5218
|
// ../lsp-core/src/lsp/directory-diagnostics.ts
|
|
4883
|
-
import { existsSync as
|
|
4884
|
-
import { join as
|
|
5219
|
+
import { existsSync as existsSync12, lstatSync as lstatSync5, readdirSync as readdirSync3 } from "node:fs";
|
|
5220
|
+
import { join as join6, resolve as resolve9 } from "node:path";
|
|
4885
5221
|
|
|
4886
5222
|
// ../lsp-core/src/lsp/formatters.ts
|
|
4887
5223
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
@@ -4896,10 +5232,10 @@ function uriToPath(uri) {
|
|
|
4896
5232
|
}
|
|
4897
5233
|
function formatLocation(loc) {
|
|
4898
5234
|
if ("targetUri" in loc) {
|
|
4899
|
-
const
|
|
4900
|
-
const
|
|
4901
|
-
const
|
|
4902
|
-
return `${
|
|
5235
|
+
const uri = uriToPath(loc.targetUri);
|
|
5236
|
+
const line = loc.targetRange.start.line + 1;
|
|
5237
|
+
const char = loc.targetRange.start.character;
|
|
5238
|
+
return `${uri}:${line}:${char}`;
|
|
4903
5239
|
}
|
|
4904
5240
|
const uri = uriToPath(loc.uri);
|
|
4905
5241
|
const line = loc.range.start.line + 1;
|
|
@@ -5011,7 +5347,7 @@ function collectFilesWithExtension(dir, extension, maxFiles) {
|
|
|
5011
5347
|
for (const entry of entries) {
|
|
5012
5348
|
if (files.length >= maxFiles)
|
|
5013
5349
|
return;
|
|
5014
|
-
const fullPath =
|
|
5350
|
+
const fullPath = join6(currentDir, entry);
|
|
5015
5351
|
let stat;
|
|
5016
5352
|
try {
|
|
5017
5353
|
stat = lstatSync5(fullPath);
|
|
@@ -5036,15 +5372,15 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
|
|
|
5036
5372
|
if (!extension.startsWith(".")) {
|
|
5037
5373
|
throw new LspInvalidPathError(`Extension must start with a dot (e.g., ".ts", not "${extension}"). Use ".${extension}" instead.`);
|
|
5038
5374
|
}
|
|
5039
|
-
const absDir =
|
|
5040
|
-
if (!
|
|
5375
|
+
const absDir = resolve9(options.workspaceRoot ?? contextCwd(), directory);
|
|
5376
|
+
if (!existsSync12(absDir)) {
|
|
5041
5377
|
throw new LspInvalidPathError(`Directory does not exist: ${absDir}`);
|
|
5042
5378
|
}
|
|
5043
5379
|
const serverResult = options.server === undefined ? findServerForExtension(extension) : { status: "found", server: options.server };
|
|
5044
5380
|
if (serverResult.status !== "found") {
|
|
5045
5381
|
throw new LspServerLookupError(formatServerLookupError(serverResult));
|
|
5046
5382
|
}
|
|
5047
|
-
const
|
|
5383
|
+
const server = serverResult.server;
|
|
5048
5384
|
const allFiles = (options.listFiles ?? collectFilesWithExtension)(absDir, extension, maxFiles + 1);
|
|
5049
5385
|
const wasCapped = allFiles.length > maxFiles;
|
|
5050
5386
|
const filesToProcess = allFiles.slice(0, maxFiles);
|
|
@@ -5064,7 +5400,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
|
|
|
5064
5400
|
const fileErrors = [];
|
|
5065
5401
|
const maxConcurrency = Math.max(1, options.maxConcurrency ?? DIRECTORY_DIAGNOSTICS_MAX_CONCURRENCY);
|
|
5066
5402
|
options.signal?.throwIfAborted();
|
|
5067
|
-
const client = await manager.getClient(root,
|
|
5403
|
+
const client = await manager.getClient(root, server, options.signal);
|
|
5068
5404
|
try {
|
|
5069
5405
|
let nextIndex = 0;
|
|
5070
5406
|
const workers = Array.from({ length: Math.min(maxConcurrency, filesToProcess.length) }, async () => {
|
|
@@ -5092,7 +5428,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
|
|
|
5092
5428
|
});
|
|
5093
5429
|
await Promise.all(workers);
|
|
5094
5430
|
} finally {
|
|
5095
|
-
manager.releaseClient(root,
|
|
5431
|
+
manager.releaseClient(root, server.id);
|
|
5096
5432
|
}
|
|
5097
5433
|
const displayDiagnostics = allDiagnostics.slice(0, DEFAULT_MAX_DIAGNOSTICS);
|
|
5098
5434
|
const wasDiagCapped = allDiagnostics.length > DEFAULT_MAX_DIAGNOSTICS;
|
|
@@ -5124,7 +5460,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
|
|
|
5124
5460
|
|
|
5125
5461
|
// ../lsp-core/src/lsp/infer-extension.ts
|
|
5126
5462
|
import { lstatSync as lstatSync6, readdirSync as readdirSync4 } from "node:fs";
|
|
5127
|
-
import { join as
|
|
5463
|
+
import { join as join7 } from "node:path";
|
|
5128
5464
|
var SKIP_DIRECTORIES2 = new Set(["node_modules", ".git", "dist", "build", ".next", "out"]);
|
|
5129
5465
|
var MAX_SCAN_ENTRIES = 500;
|
|
5130
5466
|
function inferExtensionFromDirectory(directory) {
|
|
@@ -5142,7 +5478,7 @@ function inferExtensionFromDirectory(directory) {
|
|
|
5142
5478
|
for (const entry of entries) {
|
|
5143
5479
|
if (scanned >= MAX_SCAN_ENTRIES)
|
|
5144
5480
|
return;
|
|
5145
|
-
const fullPath =
|
|
5481
|
+
const fullPath = join7(dir, entry);
|
|
5146
5482
|
let stat;
|
|
5147
5483
|
try {
|
|
5148
5484
|
stat = lstatSync6(fullPath);
|
|
@@ -5301,8 +5637,8 @@ function clientOptions(signal) {
|
|
|
5301
5637
|
}
|
|
5302
5638
|
|
|
5303
5639
|
// ../lsp-core/src/tools/result.ts
|
|
5304
|
-
function text(
|
|
5305
|
-
return { content: [{ type: "text", text
|
|
5640
|
+
function text(text, details, isError = false) {
|
|
5641
|
+
return { content: [{ type: "text", text }], details, isError };
|
|
5306
5642
|
}
|
|
5307
5643
|
|
|
5308
5644
|
// ../lsp-core/src/tools/diagnostics.ts
|
|
@@ -5322,7 +5658,7 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
5322
5658
|
const extension = inferExtensionFromDirectory(absPath);
|
|
5323
5659
|
if (!extension) {
|
|
5324
5660
|
const message = `No supported source files found in directory: ${absPath}`;
|
|
5325
|
-
const
|
|
5661
|
+
const details = {
|
|
5326
5662
|
filePath,
|
|
5327
5663
|
severity,
|
|
5328
5664
|
mode: "directory",
|
|
@@ -5332,24 +5668,24 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
5332
5668
|
error: message,
|
|
5333
5669
|
errorKind: "no_files"
|
|
5334
5670
|
};
|
|
5335
|
-
return text(message,
|
|
5671
|
+
return text(message, details);
|
|
5336
5672
|
}
|
|
5337
|
-
const
|
|
5338
|
-
const
|
|
5673
|
+
const output = await aggregateDiagnosticsForDirectory(absPath, extension, severity, undefined, signal === undefined ? {} : { signal });
|
|
5674
|
+
const details = {
|
|
5339
5675
|
filePath,
|
|
5340
5676
|
severity,
|
|
5341
5677
|
mode: "directory",
|
|
5342
5678
|
diagnostics: [],
|
|
5343
|
-
totalDiagnostics:
|
|
5679
|
+
totalDiagnostics: output.totalDiagnostics,
|
|
5344
5680
|
truncated: false,
|
|
5345
|
-
fileFailures: [...
|
|
5681
|
+
fileFailures: [...output.fileFailures]
|
|
5346
5682
|
};
|
|
5347
|
-
return text(
|
|
5683
|
+
return text(output.output, details);
|
|
5348
5684
|
}
|
|
5349
5685
|
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.diagnostics(resolvedFilePath, signal), "diagnostics", clientOptions(signal));
|
|
5350
5686
|
if (result.transientError) {
|
|
5351
5687
|
const message = result.transientError.message;
|
|
5352
|
-
const
|
|
5688
|
+
const details = {
|
|
5353
5689
|
filePath,
|
|
5354
5690
|
severity,
|
|
5355
5691
|
mode: "file",
|
|
@@ -5359,7 +5695,7 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
5359
5695
|
error: message,
|
|
5360
5696
|
errorKind: result.transientError.kind
|
|
5361
5697
|
};
|
|
5362
|
-
return text(message,
|
|
5698
|
+
return text(message, details, true);
|
|
5363
5699
|
}
|
|
5364
5700
|
const diagnostics = filterDiagnosticsBySeverity(asDiagnosticArray(result), severity);
|
|
5365
5701
|
const total = diagnostics.length;
|
|
@@ -5393,6 +5729,96 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
5393
5729
|
throw error;
|
|
5394
5730
|
}
|
|
5395
5731
|
}
|
|
5732
|
+
// ../lsp-core/src/lsp/format-document.ts
|
|
5733
|
+
import { readFileSync as readFileSync6, renameSync as renameSync3, unlinkSync as unlinkSync2, writeFileSync as writeFileSync3 } from "node:fs";
|
|
5734
|
+
var DEFAULT_FORMATTING_OPTIONS = {
|
|
5735
|
+
tabSize: 4,
|
|
5736
|
+
insertSpaces: false,
|
|
5737
|
+
trimTrailingWhitespace: true,
|
|
5738
|
+
insertFinalNewline: true,
|
|
5739
|
+
trimFinalNewlines: true
|
|
5740
|
+
};
|
|
5741
|
+
var UNCHANGED = { status: "unchanged", linesAdded: 0, linesRemoved: 0 };
|
|
5742
|
+
async function formatDocumentWithClient(client, filePath, options = {}) {
|
|
5743
|
+
const edits = await client.formatDocument(filePath, options.formattingOptions ?? DEFAULT_FORMATTING_OPTIONS, options.signal);
|
|
5744
|
+
if (edits === null)
|
|
5745
|
+
return { status: "unavailable", reason: "capability_not_advertised" };
|
|
5746
|
+
if (edits.length === 0)
|
|
5747
|
+
return UNCHANGED;
|
|
5748
|
+
const before = readFileSync6(filePath, "utf-8");
|
|
5749
|
+
const normalized = normalizeTextEdits(before, edits, 0);
|
|
5750
|
+
if (normalized.text === before)
|
|
5751
|
+
return UNCHANGED;
|
|
5752
|
+
writeAtomically(filePath, normalized.text);
|
|
5753
|
+
await client.openFile(filePath);
|
|
5754
|
+
return {
|
|
5755
|
+
status: "formatted",
|
|
5756
|
+
...lineDelta(normalized.edits)
|
|
5757
|
+
};
|
|
5758
|
+
}
|
|
5759
|
+
function lineDelta(edits) {
|
|
5760
|
+
let linesAdded = 0;
|
|
5761
|
+
let linesRemoved = 0;
|
|
5762
|
+
for (const edit of edits) {
|
|
5763
|
+
linesRemoved += edit.range.end.line - edit.range.start.line + 1;
|
|
5764
|
+
linesAdded += edit.newText.split(`
|
|
5765
|
+
`).length;
|
|
5766
|
+
}
|
|
5767
|
+
return { linesAdded, linesRemoved };
|
|
5768
|
+
}
|
|
5769
|
+
function writeAtomically(filePath, content) {
|
|
5770
|
+
const tempPath = `${filePath}.omo-format.tmp`;
|
|
5771
|
+
writeFileSync3(tempPath, content, "utf-8");
|
|
5772
|
+
try {
|
|
5773
|
+
renameSync3(tempPath, filePath);
|
|
5774
|
+
} catch (error) {
|
|
5775
|
+
try {
|
|
5776
|
+
unlinkSync2(tempPath);
|
|
5777
|
+
} catch {}
|
|
5778
|
+
throw error;
|
|
5779
|
+
}
|
|
5780
|
+
}
|
|
5781
|
+
|
|
5782
|
+
// ../lsp-core/src/tools/format.ts
|
|
5783
|
+
async function executeLspFormat(params, signal) {
|
|
5784
|
+
const filePath = requireString(params, "filePath");
|
|
5785
|
+
try {
|
|
5786
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => formatDocumentWithClient(client, resolvedFilePath, signal === undefined ? {} : { signal }), "format", clientOptions(signal));
|
|
5787
|
+
return text(describeResult(filePath, result), formatDetails(filePath, result));
|
|
5788
|
+
} catch (error) {
|
|
5789
|
+
const missingDependency = missingDependencyResult(error, {
|
|
5790
|
+
filePath,
|
|
5791
|
+
status: "unavailable",
|
|
5792
|
+
reason: "server_unavailable",
|
|
5793
|
+
linesAdded: 0,
|
|
5794
|
+
linesRemoved: 0
|
|
5795
|
+
});
|
|
5796
|
+
if (missingDependency)
|
|
5797
|
+
return missingDependency;
|
|
5798
|
+
throw error;
|
|
5799
|
+
}
|
|
5800
|
+
}
|
|
5801
|
+
function formatDetails(filePath, result) {
|
|
5802
|
+
if (result.status === "unavailable") {
|
|
5803
|
+
return { filePath, status: "unavailable", reason: result.reason, linesAdded: 0, linesRemoved: 0 };
|
|
5804
|
+
}
|
|
5805
|
+
return {
|
|
5806
|
+
filePath,
|
|
5807
|
+
status: result.status,
|
|
5808
|
+
linesAdded: result.linesAdded,
|
|
5809
|
+
linesRemoved: result.linesRemoved
|
|
5810
|
+
};
|
|
5811
|
+
}
|
|
5812
|
+
function describeResult(filePath, result) {
|
|
5813
|
+
if (result.status === "unavailable") {
|
|
5814
|
+
return `Formatting unavailable for ${filePath}: the language server does not advertise documentFormattingProvider.`;
|
|
5815
|
+
}
|
|
5816
|
+
if (result.status === "unchanged") {
|
|
5817
|
+
return `Already formatted: ${filePath}`;
|
|
5818
|
+
}
|
|
5819
|
+
return `Formatted ${filePath} (+${result.linesAdded}/-${result.linesRemoved} lines)`;
|
|
5820
|
+
}
|
|
5821
|
+
|
|
5396
5822
|
// ../lsp-core/src/tools/install-decision.ts
|
|
5397
5823
|
async function executeLspInstallDecision(params) {
|
|
5398
5824
|
const serverId = requireString(params, "server_id");
|
|
@@ -5400,7 +5826,7 @@ async function executeLspInstallDecision(params) {
|
|
|
5400
5826
|
if (!isInstallDecision(decision)) {
|
|
5401
5827
|
return text(`Invalid decision '${String(decision)}'. Expected "declined" or "allowed".`, { serverId, errorKind: "invalid_decision" }, true);
|
|
5402
5828
|
}
|
|
5403
|
-
const serverIds = [...new Set(getMergedServers().map((
|
|
5829
|
+
const serverIds = [...new Set(getMergedServers().map((server) => server.id))];
|
|
5404
5830
|
if (!serverIds.includes(serverId)) {
|
|
5405
5831
|
const preview = serverIds.slice(0, 20).join(", ");
|
|
5406
5832
|
return text(`Unknown LSP server '${serverId}'. Known servers: ${preview}${serverIds.length > 20 ? "..." : ""}`, { serverId, errorKind: "unknown_server" }, true);
|
|
@@ -5540,10 +5966,10 @@ function objectSchema(properties, required = []) {
|
|
|
5540
5966
|
async function executeLspStatus() {
|
|
5541
5967
|
const servers = getAllServers();
|
|
5542
5968
|
const snapshots = getLspManager().getSnapshot();
|
|
5543
|
-
const installed = servers.filter((
|
|
5544
|
-
const configuredLines = servers.map((
|
|
5545
|
-
const state =
|
|
5546
|
-
return `- ${
|
|
5969
|
+
const installed = servers.filter((server) => server.installed && !server.disabled);
|
|
5970
|
+
const configuredLines = servers.map((server) => {
|
|
5971
|
+
const state = server.disabled ? "disabled" : server.installed ? "installed" : "missing";
|
|
5972
|
+
return `- ${server.id}: ${state}; source=${server.source}; extensions=${server.extensions.join(", ")}`;
|
|
5547
5973
|
});
|
|
5548
5974
|
const activeLines = snapshots.map((snapshot) => {
|
|
5549
5975
|
const state = snapshot.alive ? snapshot.isInitializing ? "initializing" : "alive" : "dead";
|
|
@@ -5586,8 +6012,8 @@ async function executeLspSymbols(params, signal) {
|
|
|
5586
6012
|
errorKind: "missing_query"
|
|
5587
6013
|
});
|
|
5588
6014
|
}
|
|
5589
|
-
const
|
|
5590
|
-
return formatSymbolsResult(filePath, scope,
|
|
6015
|
+
const symbols = await withLspClient(filePath, async (client) => client.workspaceSymbols(query, signal), "workspaceSymbols", clientOptions(signal));
|
|
6016
|
+
return formatSymbolsResult(filePath, scope, symbols, limit, query);
|
|
5591
6017
|
}
|
|
5592
6018
|
const symbols = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.documentSymbols(resolvedFilePath, signal), "documentSymbols", clientOptions(signal));
|
|
5593
6019
|
return formatSymbolsResult(filePath, scope, symbols, limit);
|
|
@@ -5725,6 +6151,16 @@ var LSP_MCP_TOOLS = [
|
|
|
5725
6151
|
}, ["filePath", "line", "character", "newName"]),
|
|
5726
6152
|
execute: executeLspRename
|
|
5727
6153
|
},
|
|
6154
|
+
{
|
|
6155
|
+
name: "format",
|
|
6156
|
+
aliases: ["lsp_format"],
|
|
6157
|
+
title: "LSP Format",
|
|
6158
|
+
description: "Format a source file with its language server and write the returned edits to disk.",
|
|
6159
|
+
inputSchema: objectSchema({
|
|
6160
|
+
filePath: { type: "string", description: "Source file path to format." }
|
|
6161
|
+
}, ["filePath"]),
|
|
6162
|
+
execute: executeLspFormat
|
|
6163
|
+
},
|
|
5728
6164
|
{
|
|
5729
6165
|
name: "install_decision",
|
|
5730
6166
|
aliases: ["lsp_install_decision"],
|
|
@@ -5825,7 +6261,10 @@ function requestedProtocolVersion(params) {
|
|
|
5825
6261
|
var CONTEXT_KEY = "_context";
|
|
5826
6262
|
|
|
5827
6263
|
class InvalidDaemonRequestError extends Error {
|
|
5828
|
-
|
|
6264
|
+
constructor() {
|
|
6265
|
+
super(...arguments);
|
|
6266
|
+
this.name = "InvalidDaemonRequestError";
|
|
6267
|
+
}
|
|
5829
6268
|
}
|
|
5830
6269
|
function extractRequestContext(raw) {
|
|
5831
6270
|
if (!isPlainRecord(raw) || raw["method"] !== "tools/call")
|
|
@@ -5907,6 +6346,7 @@ function parseContext(value) {
|
|
|
5907
6346
|
|
|
5908
6347
|
// src/daemon-client.ts
|
|
5909
6348
|
var DEFAULT_REQUEST_TIMEOUT_MS = 30000;
|
|
6349
|
+
var STARTUP_BACKOFF_MS = [0, 100, 300];
|
|
5910
6350
|
var nextProxyRequestId = 1;
|
|
5911
6351
|
async function callToolViaDaemon(name, args, options) {
|
|
5912
6352
|
const context = requireContext(options.context);
|
|
@@ -5914,17 +6354,31 @@ async function callToolViaDaemon(name, args, options) {
|
|
|
5914
6354
|
const ensure = options.ensure ?? ((ensurePaths, signal) => ensureDaemonRunning(ensurePaths, undefined, signal === undefined ? {} : { signal }));
|
|
5915
6355
|
const timeoutMs = options.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
|
|
5916
6356
|
const requestArgs = withContext(args, context);
|
|
6357
|
+
const probe = options.probe ?? ((probePaths, signal) => probeDaemon(probePaths, undefined, signal));
|
|
6358
|
+
const sleep = options.sleep ?? ((ms, signal) => delay(ms, undefined, { signal }));
|
|
5917
6359
|
let lastError;
|
|
5918
6360
|
let authRefreshUsed = false;
|
|
5919
|
-
for (
|
|
6361
|
+
for (const [attempt, backoffMs] of STARTUP_BACKOFF_MS.entries()) {
|
|
5920
6362
|
try {
|
|
5921
|
-
|
|
6363
|
+
if (backoffMs > 0)
|
|
6364
|
+
await sleep(backoffMs, options.signal);
|
|
6365
|
+
if (options.signal?.aborted)
|
|
6366
|
+
throw new DaemonRequestCancelledError(false);
|
|
6367
|
+
if (attempt === 0) {
|
|
6368
|
+
await ensureDaemonAvailable(paths, ensure, options.signal);
|
|
6369
|
+
} else if (!await probe(paths, options.signal)) {
|
|
6370
|
+
throw new DaemonUnreachableError(paths.socket);
|
|
6371
|
+
}
|
|
5922
6372
|
const token = readAuthToken(paths);
|
|
5923
6373
|
if (!token)
|
|
5924
6374
|
throw new DaemonRequestError("daemon auth token missing", false);
|
|
5925
6375
|
const sendOptions = options.signal === undefined ? { timeoutMs } : { timeoutMs, signal: options.signal };
|
|
5926
6376
|
return await sendToolCall(paths, token, name, requestArgs, sendOptions);
|
|
5927
6377
|
} catch (error) {
|
|
6378
|
+
if (options.signal?.aborted) {
|
|
6379
|
+
lastError = new DaemonRequestCancelledError(false);
|
|
6380
|
+
break;
|
|
6381
|
+
}
|
|
5928
6382
|
lastError = error;
|
|
5929
6383
|
if (error instanceof DaemonAuthenticationRejectedError && !authRefreshUsed) {
|
|
5930
6384
|
authRefreshUsed = true;
|
|
@@ -5941,14 +6395,17 @@ async function callToolViaDaemon(name, args, options) {
|
|
|
5941
6395
|
function callDiagnosticsViaDaemon(filePath, options) {
|
|
5942
6396
|
return callToolViaDaemon("diagnostics", { filePath, severity: "error" }, options);
|
|
5943
6397
|
}
|
|
6398
|
+
function callFormatViaDaemon(filePath, options) {
|
|
6399
|
+
return callToolViaDaemon("format", { filePath }, options);
|
|
6400
|
+
}
|
|
5944
6401
|
function currentRequestContext(env = process.env) {
|
|
5945
6402
|
const cwd = process.cwd();
|
|
5946
6403
|
const home = env["HOME"] ?? homedir3();
|
|
5947
6404
|
return parseLspRequestContext({
|
|
5948
6405
|
cwd,
|
|
5949
|
-
projectConfigPaths: [
|
|
5950
|
-
userConfigPath:
|
|
5951
|
-
installDecisionsPath:
|
|
6406
|
+
projectConfigPaths: [join8(cwd, ".codex", "lsp-client.json")],
|
|
6407
|
+
userConfigPath: join8(home, ".codex", "lsp-client.json"),
|
|
6408
|
+
installDecisionsPath: join8(home, ".codex", "lsp-install-decisions.json"),
|
|
5952
6409
|
capabilities: { installDecisionTool: true }
|
|
5953
6410
|
});
|
|
5954
6411
|
}
|
|
@@ -5963,7 +6420,7 @@ function withContext(args, context) {
|
|
|
5963
6420
|
function ensureDaemonAvailable(paths, ensure, signal) {
|
|
5964
6421
|
if (!signal)
|
|
5965
6422
|
return ensure(paths);
|
|
5966
|
-
return new Promise((
|
|
6423
|
+
return new Promise((resolve, reject) => {
|
|
5967
6424
|
let settled = false;
|
|
5968
6425
|
const finish = (run) => {
|
|
5969
6426
|
if (settled)
|
|
@@ -5978,11 +6435,11 @@ function ensureDaemonAvailable(paths, ensure, signal) {
|
|
|
5978
6435
|
return;
|
|
5979
6436
|
}
|
|
5980
6437
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
5981
|
-
Promise.resolve().then(() => ensure(paths, signal)).then(() => finish(() =>
|
|
6438
|
+
Promise.resolve().then(() => ensure(paths, signal)).then(() => finish(() => resolve()), (error) => finish(() => reject(signal.aborted ? new DaemonRequestCancelledError(false) : error)));
|
|
5982
6439
|
});
|
|
5983
6440
|
}
|
|
5984
6441
|
function sendToolCall(paths, token, name, args, options) {
|
|
5985
|
-
return new Promise((
|
|
6442
|
+
return new Promise((resolve, reject) => {
|
|
5986
6443
|
const socket = connect(paths.socket);
|
|
5987
6444
|
const requestId = allocateProxyRequestId();
|
|
5988
6445
|
let settled = false;
|
|
@@ -6035,7 +6492,7 @@ function sendToolCall(paths, token, name, args, options) {
|
|
|
6035
6492
|
}
|
|
6036
6493
|
const result = toToolResult(message, requestId);
|
|
6037
6494
|
if (result)
|
|
6038
|
-
finish(() =>
|
|
6495
|
+
finish(() => resolve(result));
|
|
6039
6496
|
else
|
|
6040
6497
|
finish(() => reject(new DaemonRequestError("invalid daemon response", requestWritten)));
|
|
6041
6498
|
});
|
|
@@ -6081,18 +6538,15 @@ function isRetryableTool(name) {
|
|
|
6081
6538
|
}
|
|
6082
6539
|
|
|
6083
6540
|
// src/client.ts
|
|
6084
|
-
import { statSync as statSync5 } from "node:fs";
|
|
6085
|
-
import { isAbsolute as isAbsolute5 } from "node:path";
|
|
6086
6541
|
var OMO_LSP_DAEMON_DIR2 = "OMO_LSP_DAEMON_DIR";
|
|
6087
6542
|
var OMO_LSP_DAEMON_CLI2 = "OMO_LSP_DAEMON_CLI";
|
|
6088
6543
|
var OMO_LSP_DAEMON_VERSION2 = "OMO_LSP_DAEMON_VERSION";
|
|
6089
6544
|
var DAEMON_VERSION_PATTERN2 = /^[A-Za-z0-9][A-Za-z0-9._+-]{0,127}$/;
|
|
6090
6545
|
|
|
6091
6546
|
class InvalidRuntimeOverrideError2 extends Error {
|
|
6092
|
-
code = "invalid_runtime_override";
|
|
6093
|
-
reason;
|
|
6094
6547
|
constructor(reason, message) {
|
|
6095
6548
|
super(message);
|
|
6549
|
+
this.code = "invalid_runtime_override";
|
|
6096
6550
|
this.name = "InvalidRuntimeOverrideError";
|
|
6097
6551
|
this.reason = reason;
|
|
6098
6552
|
}
|
|
@@ -6112,12 +6566,12 @@ function resolveDaemonRuntime2(env, defaults) {
|
|
|
6112
6566
|
throw new InvalidRuntimeOverrideError2("paired_values_required", `${OMO_LSP_DAEMON_CLI2} and ${OMO_LSP_DAEMON_VERSION2} must be set together`);
|
|
6113
6567
|
}
|
|
6114
6568
|
if (!hasCliOverride || !hasVersionOverride) {
|
|
6115
|
-
if (!
|
|
6569
|
+
if (!isAbsolute6(defaults.cliPath)) {
|
|
6116
6570
|
throw new InvalidRuntimeOverrideError2("packaged_cli_must_be_absolute", "Packaged LSP daemon CLI path must be absolute");
|
|
6117
6571
|
}
|
|
6118
6572
|
return { cliPath: defaults.cliPath, version: validateDaemonVersion2(defaults.version) };
|
|
6119
6573
|
}
|
|
6120
|
-
if (!
|
|
6574
|
+
if (!isAbsolute6(cliOverride)) {
|
|
6121
6575
|
throw new InvalidRuntimeOverrideError2("cli_must_be_absolute", `${OMO_LSP_DAEMON_CLI2} must be an absolute path to an existing regular file`);
|
|
6122
6576
|
}
|
|
6123
6577
|
const stat = statSync5(cliOverride, { throwIfNoEntry: false });
|
|
@@ -6135,17 +6589,21 @@ function callToolViaDaemon2(name, args, options) {
|
|
|
6135
6589
|
function callDiagnosticsViaDaemon2(filePath, options) {
|
|
6136
6590
|
return callDiagnosticsViaDaemon(filePath, options);
|
|
6137
6591
|
}
|
|
6592
|
+
function callFormatViaDaemon2(filePath, options) {
|
|
6593
|
+
return callFormatViaDaemon(filePath, options);
|
|
6594
|
+
}
|
|
6138
6595
|
function currentRequestContext2(env = process.env) {
|
|
6139
6596
|
return currentRequestContext(env);
|
|
6140
6597
|
}
|
|
6141
6598
|
export {
|
|
6142
|
-
|
|
6143
|
-
resolveDaemonRuntime2 as resolveDaemonRuntime,
|
|
6144
|
-
currentRequestContext2 as currentRequestContext,
|
|
6145
|
-
callToolViaDaemon2 as callToolViaDaemon,
|
|
6146
|
-
callDiagnosticsViaDaemon2 as callDiagnosticsViaDaemon,
|
|
6147
|
-
OMO_LSP_DAEMON_VERSION2 as OMO_LSP_DAEMON_VERSION,
|
|
6148
|
-
OMO_LSP_DAEMON_DIR2 as OMO_LSP_DAEMON_DIR,
|
|
6599
|
+
InvalidRuntimeOverrideError2 as InvalidRuntimeOverrideError,
|
|
6149
6600
|
OMO_LSP_DAEMON_CLI2 as OMO_LSP_DAEMON_CLI,
|
|
6150
|
-
|
|
6601
|
+
OMO_LSP_DAEMON_DIR2 as OMO_LSP_DAEMON_DIR,
|
|
6602
|
+
OMO_LSP_DAEMON_VERSION2 as OMO_LSP_DAEMON_VERSION,
|
|
6603
|
+
callDiagnosticsViaDaemon2 as callDiagnosticsViaDaemon,
|
|
6604
|
+
callFormatViaDaemon2 as callFormatViaDaemon,
|
|
6605
|
+
callToolViaDaemon2 as callToolViaDaemon,
|
|
6606
|
+
currentRequestContext2 as currentRequestContext,
|
|
6607
|
+
resolveDaemonRuntime2 as resolveDaemonRuntime,
|
|
6608
|
+
validateDaemonVersion2 as validateDaemonVersion
|
|
6151
6609
|
};
|