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
|
@@ -13,7 +13,10 @@ import { homedir as homedir3 } from "node:os";
|
|
|
13
13
|
import { join as join11, resolve as resolve11 } from "node:path";
|
|
14
14
|
|
|
15
15
|
// ../../../../lsp-daemon/dist/client.js
|
|
16
|
+
import { statSync as statSync5 } from "node:fs";
|
|
17
|
+
import { isAbsolute as isAbsolute6 } from "node:path";
|
|
16
18
|
import { connect } from "node:net";
|
|
19
|
+
import { setTimeout as delay } from "node:timers/promises";
|
|
17
20
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
18
21
|
import { existsSync, realpathSync, statSync } from "node:fs";
|
|
19
22
|
import { basename, delimiter, dirname, isAbsolute, join, relative, resolve } from "node:path";
|
|
@@ -42,8 +45,8 @@ import * as path from "node:path";
|
|
|
42
45
|
import { fileURLToPath } from "node:url";
|
|
43
46
|
import { statSync as statSync2 } from "node:fs";
|
|
44
47
|
import { isAbsolute as isAbsolute2 } from "node:path";
|
|
45
|
-
import { existsSync as
|
|
46
|
-
import { basename as basename3, dirname as
|
|
48
|
+
import { existsSync as existsSync11, realpathSync as realpathSync5, statSync as statSync4 } from "node:fs";
|
|
49
|
+
import { basename as basename3, dirname as dirname10, join as join5, resolve as resolve8 } from "node:path";
|
|
47
50
|
import { basename as basename2, extname } from "node:path";
|
|
48
51
|
import { resolve as resolve6 } from "node:path";
|
|
49
52
|
import { pathToFileURL as pathToFileURL3 } from "node:url";
|
|
@@ -62,32 +65,32 @@ import { createHash as createHash2 } from "node:crypto";
|
|
|
62
65
|
import { dirname as dirname5, relative as relative4, resolve as resolve4 } from "node:path";
|
|
63
66
|
import { existsSync as existsSync6, lstatSync as lstatSync4, readdirSync as readdirSync2 } from "node:fs";
|
|
64
67
|
import { dirname as dirname6, resolve as resolve5 } from "node:path";
|
|
65
|
-
import { existsSync as existsSync7,
|
|
66
|
-
import { dirname as dirname7 } from "node:path";
|
|
67
|
-
import { existsSync as existsSync8, readFileSync as
|
|
68
|
-
import {
|
|
69
|
-
import {
|
|
70
|
-
import { existsSync as
|
|
71
|
-
import { join as
|
|
68
|
+
import { existsSync as existsSync7, realpathSync as realpathSync4 } from "node:fs";
|
|
69
|
+
import { dirname as dirname7, join as join3 } from "node:path";
|
|
70
|
+
import { existsSync as existsSync8, mkdirSync as mkdirSync3, readFileSync as readFileSync4, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
71
|
+
import { dirname as dirname8 } from "node:path";
|
|
72
|
+
import { existsSync as existsSync9, readFileSync as readFileSync5 } from "node:fs";
|
|
73
|
+
import { existsSync as existsSync10 } from "node:fs";
|
|
74
|
+
import { delimiter as delimiter3, dirname as dirname9, isAbsolute as isAbsolute5, join as join4, resolve as resolve7 } from "node:path";
|
|
75
|
+
import { existsSync as existsSync12, lstatSync as lstatSync5, readdirSync as readdirSync3 } from "node:fs";
|
|
76
|
+
import { join as join6, resolve as resolve9 } from "node:path";
|
|
72
77
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
73
78
|
import { lstatSync as lstatSync6, readdirSync as readdirSync4 } from "node:fs";
|
|
74
|
-
import { join as
|
|
75
|
-
import {
|
|
76
|
-
import { isAbsolute as isAbsolute5 } from "node:path";
|
|
79
|
+
import { join as join7 } from "node:path";
|
|
80
|
+
import { readFileSync as readFileSync6, renameSync as renameSync3, unlinkSync as unlinkSync2, writeFileSync as writeFileSync3 } from "node:fs";
|
|
77
81
|
|
|
78
82
|
class LspRequestContextParseError extends Error {
|
|
79
|
-
code;
|
|
80
|
-
name = "LspRequestContextParseError";
|
|
81
83
|
constructor(code, message) {
|
|
82
84
|
super(message);
|
|
83
85
|
this.code = code;
|
|
86
|
+
this.name = "LspRequestContextParseError";
|
|
84
87
|
}
|
|
85
88
|
}
|
|
86
89
|
|
|
87
90
|
class LspRequestContextUnavailableError extends Error {
|
|
88
|
-
name = "LspRequestContextUnavailableError";
|
|
89
91
|
constructor() {
|
|
90
92
|
super("LSP request context is required. Standalone MCP startup must install one with runWithRequestContext(createStandaloneMcpRequestContext()).");
|
|
93
|
+
this.name = "LspRequestContextUnavailableError";
|
|
91
94
|
}
|
|
92
95
|
}
|
|
93
96
|
var storage = new AsyncLocalStorage;
|
|
@@ -113,18 +116,18 @@ function parseLspRequestContext(value) {
|
|
|
113
116
|
const installDecisionsPath = stringField(value, "installDecisionsPath");
|
|
114
117
|
const capabilities = capabilitiesField(value["capabilities"]);
|
|
115
118
|
const canonical = canonicalCwd(cwd);
|
|
116
|
-
for (const
|
|
117
|
-
requireAbsolutePath(
|
|
118
|
-
const projectPath = canonicalizeExistingOrNearestAncestor(
|
|
119
|
+
for (const path of projectConfigPaths) {
|
|
120
|
+
requireAbsolutePath(path, "projectConfigPaths");
|
|
121
|
+
const projectPath = canonicalizeExistingOrNearestAncestor(path);
|
|
119
122
|
if (!isPathInside(canonical, projectPath)) {
|
|
120
|
-
throw new LspRequestContextParseError("project_config_outside_cwd", `Project LSP config path must be inside cwd: ${
|
|
123
|
+
throw new LspRequestContextParseError("project_config_outside_cwd", `Project LSP config path must be inside cwd: ${path}`);
|
|
121
124
|
}
|
|
122
125
|
}
|
|
123
126
|
requireAbsolutePath(userConfigPath, "userConfigPath");
|
|
124
127
|
requireAbsolutePath(installDecisionsPath, "installDecisionsPath");
|
|
125
128
|
return {
|
|
126
129
|
cwd: canonical,
|
|
127
|
-
projectConfigPaths: projectConfigPaths.map((
|
|
130
|
+
projectConfigPaths: projectConfigPaths.map((path) => canonicalizeExistingOrNearestAncestor(path)),
|
|
128
131
|
userConfigPath,
|
|
129
132
|
installDecisionsPath,
|
|
130
133
|
capabilities
|
|
@@ -137,8 +140,8 @@ function canonicalCwd(cwd) {
|
|
|
137
140
|
}
|
|
138
141
|
return realpathSync(resolved);
|
|
139
142
|
}
|
|
140
|
-
function canonicalizeExistingOrNearestAncestor(
|
|
141
|
-
let current = resolve(
|
|
143
|
+
function canonicalizeExistingOrNearestAncestor(path) {
|
|
144
|
+
let current = resolve(path);
|
|
142
145
|
const suffix = [];
|
|
143
146
|
while (true) {
|
|
144
147
|
try {
|
|
@@ -180,9 +183,9 @@ function stringArrayField(value, field) {
|
|
|
180
183
|
}
|
|
181
184
|
return fieldValue;
|
|
182
185
|
}
|
|
183
|
-
function requireAbsolutePath(
|
|
184
|
-
if (!isAbsolute(
|
|
185
|
-
throw new LspRequestContextParseError("relative_path", `LSP request context.${field} must be absolute: ${
|
|
186
|
+
function requireAbsolutePath(path, field) {
|
|
187
|
+
if (!isAbsolute(path)) {
|
|
188
|
+
throw new LspRequestContextParseError("relative_path", `LSP request context.${field} must be absolute: ${path}`);
|
|
186
189
|
}
|
|
187
190
|
}
|
|
188
191
|
function isPathInside(parent, child) {
|
|
@@ -214,7 +217,6 @@ function isPlainRecord(value) {
|
|
|
214
217
|
}
|
|
215
218
|
|
|
216
219
|
class DaemonRequestError extends Error {
|
|
217
|
-
requestWritten;
|
|
218
220
|
constructor(message, requestWritten) {
|
|
219
221
|
super(message);
|
|
220
222
|
this.name = "DaemonRequestError";
|
|
@@ -237,7 +239,6 @@ class DaemonRequestCancelledError extends DaemonRequestError {
|
|
|
237
239
|
}
|
|
238
240
|
|
|
239
241
|
class DaemonRequestTimedOutError extends DaemonRequestError {
|
|
240
|
-
timeoutMs;
|
|
241
242
|
constructor(requestWritten, timeoutMs) {
|
|
242
243
|
super("daemon request timed out", requestWritten);
|
|
243
244
|
this.name = "DaemonRequestTimedOutError";
|
|
@@ -314,20 +315,18 @@ var OMO_LSP_DAEMON_VERSION = "OMO_LSP_DAEMON_VERSION";
|
|
|
314
315
|
var DAEMON_VERSION_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._+-]{0,127}$/;
|
|
315
316
|
|
|
316
317
|
class InvalidRuntimeOverrideError extends Error {
|
|
317
|
-
code = "invalid_runtime_override";
|
|
318
|
-
reason;
|
|
319
318
|
constructor(reason, message) {
|
|
320
319
|
super(message);
|
|
320
|
+
this.code = "invalid_runtime_override";
|
|
321
321
|
this.name = "InvalidRuntimeOverrideError";
|
|
322
322
|
this.reason = reason;
|
|
323
323
|
}
|
|
324
324
|
}
|
|
325
325
|
|
|
326
326
|
class InvalidDaemonVersionError extends Error {
|
|
327
|
-
code = "invalid_daemon_version";
|
|
328
|
-
version;
|
|
329
327
|
constructor(version) {
|
|
330
328
|
super("LSP daemon version must match [A-Za-z0-9][A-Za-z0-9._+-]{0,127}");
|
|
329
|
+
this.code = "invalid_daemon_version";
|
|
331
330
|
this.name = "InvalidDaemonVersionError";
|
|
332
331
|
this.version = version;
|
|
333
332
|
}
|
|
@@ -371,10 +370,9 @@ var requireFromHere = createRequire(import.meta.url);
|
|
|
371
370
|
var MAX_SOCKET_PATH_LENGTH = 100;
|
|
372
371
|
|
|
373
372
|
class InvalidDaemonDirectoryError extends Error {
|
|
374
|
-
code = "invalid_daemon_directory";
|
|
375
|
-
directory;
|
|
376
373
|
constructor(directory) {
|
|
377
374
|
super(`${OMO_LSP_DAEMON_DIR} must be an absolute path`);
|
|
375
|
+
this.code = "invalid_daemon_directory";
|
|
378
376
|
this.name = "InvalidDaemonDirectoryError";
|
|
379
377
|
this.directory = directory;
|
|
380
378
|
}
|
|
@@ -485,9 +483,11 @@ function createLineDecoder(onMessage, onParseError) {
|
|
|
485
483
|
}
|
|
486
484
|
};
|
|
487
485
|
}
|
|
488
|
-
var PROBE_TIMEOUT_MS =
|
|
486
|
+
var PROBE_TIMEOUT_MS = 2000;
|
|
489
487
|
var DEFAULT_READY_TIMEOUT_MS = 5000;
|
|
490
488
|
var DEFAULT_POLL_INTERVAL_MS = 100;
|
|
489
|
+
var FAILED_SPAWN_COOLDOWN_MS = 5000;
|
|
490
|
+
var failedSpawnUntil = new Map;
|
|
491
491
|
|
|
492
492
|
class DaemonUnreachableError extends Error {
|
|
493
493
|
constructor(socketPath) {
|
|
@@ -500,11 +500,22 @@ async function ensureDaemonRunning(paths, deps = defaultEnsureDaemonDeps(), opti
|
|
|
500
500
|
const pollIntervalMs = options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;
|
|
501
501
|
const signal = options.signal;
|
|
502
502
|
throwIfAborted(signal);
|
|
503
|
-
if (await awaitWithSignal(deps.probe(paths, signal), signal))
|
|
503
|
+
if (await awaitWithSignal(deps.probe(paths, signal), signal)) {
|
|
504
|
+
failedSpawnUntil.delete(paths.socket);
|
|
504
505
|
return;
|
|
506
|
+
}
|
|
505
507
|
throwIfAborted(signal);
|
|
508
|
+
const retryAt = failedSpawnUntil.get(paths.socket);
|
|
509
|
+
if (retryAt !== undefined && deps.now() < retryAt)
|
|
510
|
+
throw new DaemonUnreachableError(paths.socket);
|
|
511
|
+
failedSpawnUntil.delete(paths.socket);
|
|
506
512
|
deps.spawnDaemon(paths);
|
|
507
|
-
|
|
513
|
+
try {
|
|
514
|
+
await waitUntilReachable(paths, deps, readyTimeoutMs, pollIntervalMs, signal);
|
|
515
|
+
} catch (error) {
|
|
516
|
+
failedSpawnUntil.set(paths.socket, deps.now() + FAILED_SPAWN_COOLDOWN_MS);
|
|
517
|
+
throw error;
|
|
518
|
+
}
|
|
508
519
|
}
|
|
509
520
|
async function waitUntilReachable(paths, deps, readyTimeoutMs, pollIntervalMs, signal) {
|
|
510
521
|
const deadline = deps.now() + readyTimeoutMs;
|
|
@@ -524,7 +535,7 @@ async function probeDaemon(paths, timeoutMs = PROBE_TIMEOUT_MS, signal) {
|
|
|
524
535
|
return await pingDaemon(paths, token, timeoutMs, signal) !== null;
|
|
525
536
|
}
|
|
526
537
|
function pingDaemon(paths, token, timeoutMs = PROBE_TIMEOUT_MS, signal) {
|
|
527
|
-
return new Promise((
|
|
538
|
+
return new Promise((resolve) => {
|
|
528
539
|
const socket = new Socket;
|
|
529
540
|
let settled = false;
|
|
530
541
|
let timer;
|
|
@@ -536,7 +547,7 @@ function pingDaemon(paths, token, timeoutMs = PROBE_TIMEOUT_MS, signal) {
|
|
|
536
547
|
clearTimeout(timer);
|
|
537
548
|
signal?.removeEventListener("abort", onAbort);
|
|
538
549
|
socket.destroy();
|
|
539
|
-
|
|
550
|
+
resolve(value);
|
|
540
551
|
};
|
|
541
552
|
const onAbort = () => finish(null);
|
|
542
553
|
const decoder = createLineDecoder((message) => {
|
|
@@ -559,13 +570,17 @@ function pingDaemon(paths, token, timeoutMs = PROBE_TIMEOUT_MS, signal) {
|
|
|
559
570
|
socket.connect(paths.socket);
|
|
560
571
|
});
|
|
561
572
|
}
|
|
562
|
-
function spawnDaemonProcess(paths) {
|
|
573
|
+
function spawnDaemonProcess(paths, deps = {}) {
|
|
563
574
|
mkdirSync2(dirname3(paths.log), { recursive: true });
|
|
564
575
|
const logFd = openSync2(paths.log, "a");
|
|
565
576
|
try {
|
|
566
|
-
const
|
|
577
|
+
const spawnDaemonChild = deps.spawn ?? spawn;
|
|
578
|
+
const executable = deps.resolveExecutable?.() ?? resolveDaemonNodeExecutable();
|
|
579
|
+
const child = spawnDaemonChild(executable, [paths.cliPath, "daemon"], {
|
|
567
580
|
detached: true,
|
|
568
|
-
stdio: ["ignore", logFd, logFd]
|
|
581
|
+
stdio: ["ignore", logFd, logFd],
|
|
582
|
+
windowsHide: true,
|
|
583
|
+
env: { ...process.env, BUN_BE_BUN: "1" }
|
|
569
584
|
});
|
|
570
585
|
child.once("spawn", () => closeSync2(logFd));
|
|
571
586
|
child.once("error", (error) => {
|
|
@@ -595,7 +610,7 @@ function defaultEnsureDaemonDeps() {
|
|
|
595
610
|
};
|
|
596
611
|
}
|
|
597
612
|
function sleepWithSignal(ms, signal) {
|
|
598
|
-
return new Promise((
|
|
613
|
+
return new Promise((resolve) => {
|
|
599
614
|
let settled = false;
|
|
600
615
|
const finish = () => {
|
|
601
616
|
if (settled)
|
|
@@ -603,7 +618,7 @@ function sleepWithSignal(ms, signal) {
|
|
|
603
618
|
settled = true;
|
|
604
619
|
clearTimeout(timer);
|
|
605
620
|
signal?.removeEventListener("abort", finish);
|
|
606
|
-
|
|
621
|
+
resolve();
|
|
607
622
|
};
|
|
608
623
|
const timer = setTimeout(finish, ms);
|
|
609
624
|
if (signal?.aborted) {
|
|
@@ -618,7 +633,7 @@ function awaitWithSignal(promise, signal) {
|
|
|
618
633
|
return promise;
|
|
619
634
|
if (signal.aborted)
|
|
620
635
|
return Promise.reject(abortError(signal));
|
|
621
|
-
return new Promise((
|
|
636
|
+
return new Promise((resolve, reject) => {
|
|
622
637
|
let settled = false;
|
|
623
638
|
const finish = (run) => {
|
|
624
639
|
if (settled)
|
|
@@ -629,7 +644,7 @@ function awaitWithSignal(promise, signal) {
|
|
|
629
644
|
};
|
|
630
645
|
const onAbort = () => finish(() => reject(abortError(signal)));
|
|
631
646
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
632
|
-
promise.then((value) => finish(() =>
|
|
647
|
+
promise.then((value) => finish(() => resolve(value)), (error) => finish(() => reject(error)));
|
|
633
648
|
});
|
|
634
649
|
}
|
|
635
650
|
function throwIfAborted(signal) {
|
|
@@ -658,18 +673,18 @@ function parsePingResponse(message) {
|
|
|
658
673
|
return null;
|
|
659
674
|
if (!endpoint || typeof endpoint !== "object" || Array.isArray(endpoint))
|
|
660
675
|
return null;
|
|
661
|
-
const
|
|
676
|
+
const path = Reflect.get(endpoint, "path");
|
|
662
677
|
const kind = Reflect.get(endpoint, "kind");
|
|
663
|
-
if (typeof
|
|
678
|
+
if (typeof path !== "string")
|
|
664
679
|
return null;
|
|
665
680
|
if (kind === "windows")
|
|
666
|
-
return { pid, nonce, startedAt, endpoint: { kind, path
|
|
681
|
+
return { pid, nonce, startedAt, endpoint: { kind, path } };
|
|
667
682
|
if (kind === "missing")
|
|
668
|
-
return { pid, nonce, startedAt, endpoint: { kind, path
|
|
683
|
+
return { pid, nonce, startedAt, endpoint: { kind, path } };
|
|
669
684
|
const dev = Reflect.get(endpoint, "dev");
|
|
670
685
|
const ino = Reflect.get(endpoint, "ino");
|
|
671
686
|
if (kind === "unix" && typeof dev === "number" && typeof ino === "number") {
|
|
672
|
-
return { pid, nonce, startedAt, endpoint: { kind, path
|
|
687
|
+
return { pid, nonce, startedAt, endpoint: { kind, path, dev, ino } };
|
|
673
688
|
}
|
|
674
689
|
return null;
|
|
675
690
|
}
|
|
@@ -686,22 +701,15 @@ function effectiveExtension(filePath) {
|
|
|
686
701
|
}
|
|
687
702
|
|
|
688
703
|
class LspConnectionClosedError extends Error {
|
|
689
|
-
serverId;
|
|
690
|
-
root;
|
|
691
|
-
name = "LspConnectionClosedError";
|
|
692
704
|
constructor(serverId, root, message) {
|
|
693
705
|
super(message ?? `LSP connection closed for ${serverId} at ${root}`);
|
|
694
706
|
this.serverId = serverId;
|
|
695
707
|
this.root = root;
|
|
708
|
+
this.name = "LspConnectionClosedError";
|
|
696
709
|
}
|
|
697
710
|
}
|
|
698
711
|
|
|
699
712
|
class LspProcessExitedError extends Error {
|
|
700
|
-
serverId;
|
|
701
|
-
root;
|
|
702
|
-
exitCode;
|
|
703
|
-
stderrTail;
|
|
704
|
-
name = "LspProcessExitedError";
|
|
705
713
|
constructor(serverId, root, exitCode, stderrTail) {
|
|
706
714
|
const stderrSuffix = stderrTail ? `
|
|
707
715
|
stderr tail: ${stderrTail}` : "";
|
|
@@ -710,46 +718,59 @@ stderr tail: ${stderrTail}` : "";
|
|
|
710
718
|
this.root = root;
|
|
711
719
|
this.exitCode = exitCode;
|
|
712
720
|
this.stderrTail = stderrTail;
|
|
721
|
+
this.name = "LspProcessExitedError";
|
|
713
722
|
}
|
|
714
723
|
}
|
|
715
724
|
|
|
716
725
|
class LspRequestTimeoutError extends Error {
|
|
717
|
-
method;
|
|
718
|
-
stderrTail;
|
|
719
|
-
name = "LspRequestTimeoutError";
|
|
720
726
|
constructor(method, stderrTail) {
|
|
721
727
|
const stderrSuffix = stderrTail ? `
|
|
722
728
|
recent stderr: ${stderrTail}` : "";
|
|
723
729
|
super(`LSP request timeout (method: ${method})${stderrSuffix}`);
|
|
724
730
|
this.method = method;
|
|
725
731
|
this.stderrTail = stderrTail;
|
|
732
|
+
this.name = "LspRequestTimeoutError";
|
|
726
733
|
}
|
|
727
734
|
}
|
|
728
735
|
|
|
729
736
|
class LspInvalidPathError extends Error {
|
|
730
|
-
|
|
737
|
+
constructor() {
|
|
738
|
+
super(...arguments);
|
|
739
|
+
this.name = "LspInvalidPathError";
|
|
740
|
+
}
|
|
731
741
|
}
|
|
732
742
|
|
|
733
743
|
class LspServerLookupError extends Error {
|
|
734
|
-
lookup;
|
|
735
|
-
name = "LspServerLookupError";
|
|
736
744
|
constructor(message, lookup) {
|
|
737
745
|
super(message);
|
|
738
746
|
this.lookup = lookup;
|
|
747
|
+
this.name = "LspServerLookupError";
|
|
739
748
|
}
|
|
740
749
|
}
|
|
741
750
|
|
|
742
751
|
class LspServerInitializingError extends Error {
|
|
743
|
-
originalError;
|
|
744
|
-
name = "LspServerInitializingError";
|
|
745
752
|
constructor(originalError) {
|
|
746
753
|
super(`LSP server is still initializing. Please retry in a few seconds. Original error: ${originalError.message}`);
|
|
747
754
|
this.originalError = originalError;
|
|
755
|
+
this.name = "LspServerInitializingError";
|
|
748
756
|
}
|
|
749
757
|
}
|
|
750
758
|
|
|
751
759
|
class LspProcessSpawnError extends Error {
|
|
752
|
-
|
|
760
|
+
constructor() {
|
|
761
|
+
super(...arguments);
|
|
762
|
+
this.name = "LspProcessSpawnError";
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
class LspClientRespawnBudgetExceededError extends Error {
|
|
767
|
+
constructor(serverId, root, retryLimit) {
|
|
768
|
+
super(`LSP server ${serverId} at ${root} failed to stay alive; respawn budget exhausted ` + `(${retryLimit} consecutive dead generations). Retrying after the cooldown may succeed.`);
|
|
769
|
+
this.serverId = serverId;
|
|
770
|
+
this.root = root;
|
|
771
|
+
this.retryLimit = retryLimit;
|
|
772
|
+
this.name = "LspClientRespawnBudgetExceededError";
|
|
773
|
+
}
|
|
753
774
|
}
|
|
754
775
|
function isLspDeadConnectionError(err) {
|
|
755
776
|
return err instanceof LspConnectionClosedError || err instanceof LspProcessExitedError;
|
|
@@ -762,6 +783,11 @@ function reportBestEffortCleanupError(operation, error, logger = writeCleanupErr
|
|
|
762
783
|
const message = error instanceof Error ? error.message : String(error);
|
|
763
784
|
logger(`[lsp] ignored ${operation} failure during cleanup: ${message}`);
|
|
764
785
|
}
|
|
786
|
+
var realTimerProvider = {
|
|
787
|
+
now: () => Date.now(),
|
|
788
|
+
setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
|
|
789
|
+
clearTimeout: (handle) => clearTimeout(handle)
|
|
790
|
+
};
|
|
765
791
|
var DEFAULT_MAX_REFERENCES = 200;
|
|
766
792
|
var DEFAULT_MAX_SYMBOLS = 200;
|
|
767
793
|
var DEFAULT_MAX_DIAGNOSTICS = 200;
|
|
@@ -769,9 +795,12 @@ var DEFAULT_MAX_DIRECTORY_FILES = 50;
|
|
|
769
795
|
var REQUEST_TIMEOUT_MS = 15000;
|
|
770
796
|
var INIT_TIMEOUT_MS = 60000;
|
|
771
797
|
var IDLE_TIMEOUT_MS = 5 * 60000;
|
|
798
|
+
var MAX_RESIDENT_CLIENTS = 6;
|
|
772
799
|
var REAPER_INTERVAL_MS = 60000;
|
|
773
800
|
var STOP_HARD_KILL_TIMEOUT_MS = 5000;
|
|
774
801
|
var STOP_SIGKILL_GRACE_MS = 1000;
|
|
802
|
+
var CLIENT_RESPAWN_RETRY_LIMIT = 2;
|
|
803
|
+
var CLIENT_RESPAWN_COOLDOWN_MS = 60000;
|
|
775
804
|
var HEADER_SEPARATOR2 = `\r
|
|
776
805
|
\r
|
|
777
806
|
`;
|
|
@@ -781,20 +810,31 @@ var METHOD_NOT_FOUND = -32601;
|
|
|
781
810
|
var INTERNAL_ERROR = -32603;
|
|
782
811
|
|
|
783
812
|
class JsonRpcConnection {
|
|
784
|
-
reader;
|
|
785
|
-
writer;
|
|
786
|
-
pendingRequests = new Map;
|
|
787
|
-
notificationHandlers = new Map;
|
|
788
|
-
requestHandlers = new Map;
|
|
789
|
-
closeHandlers = [];
|
|
790
|
-
errorHandlers = [];
|
|
791
|
-
inputBuffer = Buffer.alloc(0);
|
|
792
|
-
nextRequestId = 1;
|
|
793
|
-
listening = false;
|
|
794
|
-
disposed = false;
|
|
795
813
|
constructor(reader, writer) {
|
|
796
814
|
this.reader = reader;
|
|
797
815
|
this.writer = writer;
|
|
816
|
+
this.pendingRequests = new Map;
|
|
817
|
+
this.notificationHandlers = new Map;
|
|
818
|
+
this.requestHandlers = new Map;
|
|
819
|
+
this.closeHandlers = [];
|
|
820
|
+
this.errorHandlers = [];
|
|
821
|
+
this.inputBuffer = Buffer.alloc(0);
|
|
822
|
+
this.nextRequestId = 1;
|
|
823
|
+
this.listening = false;
|
|
824
|
+
this.disposed = false;
|
|
825
|
+
this.handleData = (chunk) => {
|
|
826
|
+
const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
|
|
827
|
+
this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
|
|
828
|
+
this.drainInputBuffer();
|
|
829
|
+
};
|
|
830
|
+
this.handleClose = () => {
|
|
831
|
+
for (const handler of this.closeHandlers) {
|
|
832
|
+
handler();
|
|
833
|
+
}
|
|
834
|
+
};
|
|
835
|
+
this.handleStreamError = (error) => {
|
|
836
|
+
this.emitError(error);
|
|
837
|
+
};
|
|
798
838
|
}
|
|
799
839
|
listen() {
|
|
800
840
|
if (this.listening)
|
|
@@ -829,7 +869,8 @@ class JsonRpcConnection {
|
|
|
829
869
|
let cancelAfterWrite = false;
|
|
830
870
|
let settled = false;
|
|
831
871
|
const writeCancel = () => this.writeMessage({ jsonrpc: "2.0", method: "$/cancelRequest", params: { id } });
|
|
832
|
-
|
|
872
|
+
let rejectAfterCancelWrite;
|
|
873
|
+
const responsePromise = new Promise((resolve, reject) => {
|
|
833
874
|
const cleanup = () => {
|
|
834
875
|
options.signal?.removeEventListener("abort", onAbort);
|
|
835
876
|
};
|
|
@@ -840,22 +881,26 @@ class JsonRpcConnection {
|
|
|
840
881
|
this.pendingRequests.delete(key);
|
|
841
882
|
cleanup();
|
|
842
883
|
const rejectCancelled = () => reject(abortError2(options.signal));
|
|
884
|
+
rejectAfterCancelWrite = async () => {
|
|
885
|
+
try {
|
|
886
|
+
await writeCancel();
|
|
887
|
+
} catch (error) {
|
|
888
|
+
this.emitError(toError(error));
|
|
889
|
+
}
|
|
890
|
+
rejectCancelled();
|
|
891
|
+
};
|
|
843
892
|
if (!requestWritten) {
|
|
844
893
|
cancelAfterWrite = true;
|
|
845
|
-
rejectCancelled();
|
|
846
894
|
return;
|
|
847
895
|
}
|
|
848
|
-
|
|
849
|
-
this.emitError(toError(error));
|
|
850
|
-
rejectCancelled();
|
|
851
|
-
});
|
|
896
|
+
rejectAfterCancelWrite();
|
|
852
897
|
};
|
|
853
898
|
const onAbort = () => settleCancel();
|
|
854
899
|
this.pendingRequests.set(key, {
|
|
855
900
|
resolve(result) {
|
|
856
901
|
settled = true;
|
|
857
902
|
cleanup();
|
|
858
|
-
|
|
903
|
+
resolve(result);
|
|
859
904
|
},
|
|
860
905
|
reject(error) {
|
|
861
906
|
settled = true;
|
|
@@ -876,7 +921,7 @@ class JsonRpcConnection {
|
|
|
876
921
|
await this.writeMessage(message);
|
|
877
922
|
requestWritten = true;
|
|
878
923
|
if (cancelAfterWrite)
|
|
879
|
-
await
|
|
924
|
+
await rejectAfterCancelWrite?.();
|
|
880
925
|
} catch (error) {
|
|
881
926
|
if (settled)
|
|
882
927
|
return responsePromise;
|
|
@@ -915,19 +960,6 @@ class JsonRpcConnection {
|
|
|
915
960
|
this.notificationHandlers.clear();
|
|
916
961
|
this.requestHandlers.clear();
|
|
917
962
|
}
|
|
918
|
-
handleData = (chunk) => {
|
|
919
|
-
const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
|
|
920
|
-
this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
|
|
921
|
-
this.drainInputBuffer();
|
|
922
|
-
};
|
|
923
|
-
handleClose = () => {
|
|
924
|
-
for (const handler of this.closeHandlers) {
|
|
925
|
-
handler();
|
|
926
|
-
}
|
|
927
|
-
};
|
|
928
|
-
handleStreamError = (error) => {
|
|
929
|
-
this.emitError(error);
|
|
930
|
-
};
|
|
931
963
|
drainInputBuffer() {
|
|
932
964
|
while (true) {
|
|
933
965
|
const headerEnd = this.inputBuffer.indexOf(HEADER_SEPARATOR2);
|
|
@@ -1027,13 +1059,13 @@ class JsonRpcConnection {
|
|
|
1027
1059
|
const payload = `Content-Length: ${Buffer.byteLength(body, "utf8")}\r
|
|
1028
1060
|
\r
|
|
1029
1061
|
${body}`;
|
|
1030
|
-
return new Promise((
|
|
1062
|
+
return new Promise((resolve, reject) => {
|
|
1031
1063
|
this.writer.write(payload, (error) => {
|
|
1032
1064
|
if (error) {
|
|
1033
1065
|
reject(error);
|
|
1034
1066
|
return;
|
|
1035
1067
|
}
|
|
1036
|
-
|
|
1068
|
+
resolve();
|
|
1037
1069
|
});
|
|
1038
1070
|
});
|
|
1039
1071
|
}
|
|
@@ -1115,9 +1147,9 @@ function validateCwd(cwd) {
|
|
|
1115
1147
|
}
|
|
1116
1148
|
}
|
|
1117
1149
|
function wrap(proc) {
|
|
1118
|
-
const exitedPromise = new Promise((
|
|
1119
|
-
proc.once("close", (code) =>
|
|
1120
|
-
proc.once("error", () =>
|
|
1150
|
+
const exitedPromise = new Promise((resolve) => {
|
|
1151
|
+
proc.once("close", (code) => resolve(code ?? 0));
|
|
1152
|
+
proc.once("error", () => resolve(1));
|
|
1121
1153
|
});
|
|
1122
1154
|
if (!proc.stdin || !proc.stdout || !proc.stderr) {
|
|
1123
1155
|
throw new LspProcessSpawnError("Spawned process is missing one of stdin/stdout/stderr pipes");
|
|
@@ -1267,33 +1299,29 @@ function isPosition(value) {
|
|
|
1267
1299
|
}
|
|
1268
1300
|
|
|
1269
1301
|
class LspClientNotStartedError extends Error {
|
|
1270
|
-
serverId;
|
|
1271
|
-
root;
|
|
1272
|
-
name = "LspClientNotStartedError";
|
|
1273
1302
|
constructor(serverId, root) {
|
|
1274
1303
|
super("LSP client not started");
|
|
1275
1304
|
this.serverId = serverId;
|
|
1276
1305
|
this.root = root;
|
|
1306
|
+
this.name = "LspClientNotStartedError";
|
|
1277
1307
|
}
|
|
1278
1308
|
}
|
|
1279
1309
|
|
|
1280
1310
|
class LspClientTransport {
|
|
1281
|
-
root
|
|
1282
|
-
server;
|
|
1283
|
-
proc = null;
|
|
1284
|
-
connection = null;
|
|
1285
|
-
stderrBuffer = [];
|
|
1286
|
-
processExited = false;
|
|
1287
|
-
diagnosticsStore = new Map;
|
|
1288
|
-
requestTimeoutMs;
|
|
1289
|
-
initializeTimeoutMs;
|
|
1290
|
-
workspaceApplyEditHandler = null;
|
|
1291
|
-
diagnosticPullSupported = false;
|
|
1292
|
-
constructor(root, server2, timeouts = {}) {
|
|
1311
|
+
constructor(root, server, timeouts = {}) {
|
|
1293
1312
|
this.root = root;
|
|
1294
|
-
this.server =
|
|
1313
|
+
this.server = server;
|
|
1314
|
+
this.proc = null;
|
|
1315
|
+
this.connection = null;
|
|
1316
|
+
this.stderrBuffer = [];
|
|
1317
|
+
this.processExited = false;
|
|
1318
|
+
this.diagnosticsStore = new Map;
|
|
1319
|
+
this.workspaceApplyEditHandler = null;
|
|
1320
|
+
this.diagnosticPullSupported = false;
|
|
1321
|
+
this.documentFormattingSupported = false;
|
|
1295
1322
|
this.requestTimeoutMs = timeouts.requestTimeoutMs ?? REQUEST_TIMEOUT_MS;
|
|
1296
1323
|
this.initializeTimeoutMs = timeouts.initializeTimeoutMs ?? INIT_TIMEOUT_MS;
|
|
1324
|
+
this.timerProvider = timeouts.timerProvider ?? realTimerProvider;
|
|
1297
1325
|
}
|
|
1298
1326
|
pid() {
|
|
1299
1327
|
return this.proc?.pid;
|
|
@@ -1313,6 +1341,12 @@ class LspClientTransport {
|
|
|
1313
1341
|
isDiagnosticPullSupported() {
|
|
1314
1342
|
return this.diagnosticPullSupported;
|
|
1315
1343
|
}
|
|
1344
|
+
setDocumentFormattingSupported(supported) {
|
|
1345
|
+
this.documentFormattingSupported = supported;
|
|
1346
|
+
}
|
|
1347
|
+
isDocumentFormattingSupported() {
|
|
1348
|
+
return this.documentFormattingSupported;
|
|
1349
|
+
}
|
|
1316
1350
|
handlePublishDiagnostics(params) {
|
|
1317
1351
|
this.diagnosticsStore.set(params.uri, [...params.diagnostics]);
|
|
1318
1352
|
}
|
|
@@ -1388,7 +1422,7 @@ class LspClientTransport {
|
|
|
1388
1422
|
const options = args[1];
|
|
1389
1423
|
const timeoutMs = options?.timeoutMs ?? this.requestTimeoutMs;
|
|
1390
1424
|
const timeoutController = new AbortController;
|
|
1391
|
-
const timeoutHandle = setTimeout(() => {
|
|
1425
|
+
const timeoutHandle = this.timerProvider.setTimeout(() => {
|
|
1392
1426
|
const stderrTail = this.stderrBuffer.slice(-5).join(`
|
|
1393
1427
|
`);
|
|
1394
1428
|
timeoutController.abort(new LspRequestTimeoutError(method, stderrTail || undefined));
|
|
@@ -1407,7 +1441,7 @@ class LspClientTransport {
|
|
|
1407
1441
|
}
|
|
1408
1442
|
throw error;
|
|
1409
1443
|
} finally {
|
|
1410
|
-
clearTimeout(timeoutHandle);
|
|
1444
|
+
this.timerProvider.clearTimeout(timeoutHandle);
|
|
1411
1445
|
combinedSignal.dispose();
|
|
1412
1446
|
}
|
|
1413
1447
|
}
|
|
@@ -1458,8 +1492,8 @@ class LspClientTransport {
|
|
|
1458
1492
|
try {
|
|
1459
1493
|
proc.kill();
|
|
1460
1494
|
let timeoutId;
|
|
1461
|
-
const timeoutPromise = new Promise((
|
|
1462
|
-
timeoutId = setTimeout(
|
|
1495
|
+
const timeoutPromise = new Promise((resolve) => {
|
|
1496
|
+
timeoutId = setTimeout(resolve, STOP_HARD_KILL_TIMEOUT_MS);
|
|
1463
1497
|
});
|
|
1464
1498
|
await Promise.race([
|
|
1465
1499
|
proc.exited.then(() => {
|
|
@@ -1475,7 +1509,7 @@ class LspClientTransport {
|
|
|
1475
1509
|
proc.kill("SIGKILL");
|
|
1476
1510
|
await Promise.race([
|
|
1477
1511
|
proc.exited,
|
|
1478
|
-
new Promise((
|
|
1512
|
+
new Promise((resolve) => setTimeout(resolve, STOP_SIGKILL_GRACE_MS))
|
|
1479
1513
|
]);
|
|
1480
1514
|
} catch (error) {
|
|
1481
1515
|
reportBestEffortCleanupError("hard process kill", error instanceof Error ? error : String(error));
|
|
@@ -1524,6 +1558,14 @@ function supportsDiagnosticPull(capabilities) {
|
|
|
1524
1558
|
return false;
|
|
1525
1559
|
return Object.hasOwn(capabilities, "diagnosticProvider");
|
|
1526
1560
|
}
|
|
1561
|
+
function supportsDocumentFormatting(capabilities) {
|
|
1562
|
+
if (capabilities === undefined)
|
|
1563
|
+
return false;
|
|
1564
|
+
const provider = capabilities.documentFormattingProvider;
|
|
1565
|
+
if (provider === undefined || provider === null || provider === false)
|
|
1566
|
+
return false;
|
|
1567
|
+
return provider === true || typeof provider === "object";
|
|
1568
|
+
}
|
|
1527
1569
|
|
|
1528
1570
|
class LspClientConnection extends LspClientTransport {
|
|
1529
1571
|
async initialize() {
|
|
@@ -1540,6 +1582,7 @@ class LspClientConnection extends LspClientTransport {
|
|
|
1540
1582
|
references: {},
|
|
1541
1583
|
documentSymbol: { hierarchicalDocumentSymbolSupport: true },
|
|
1542
1584
|
publishDiagnostics: {},
|
|
1585
|
+
formatting: { dynamicRegistration: false },
|
|
1543
1586
|
rename: {
|
|
1544
1587
|
prepareSupport: true,
|
|
1545
1588
|
prepareSupportDefaultBehavior: 1
|
|
@@ -1581,6 +1624,7 @@ class LspClientConnection extends LspClientTransport {
|
|
|
1581
1624
|
initializationOptions: this.server.initialization
|
|
1582
1625
|
}, { timeoutMs: this.initializeTimeoutMs });
|
|
1583
1626
|
this.setDiagnosticPullSupported(supportsDiagnosticPull(result?.capabilities));
|
|
1627
|
+
this.setDocumentFormattingSupported(supportsDocumentFormatting(result?.capabilities));
|
|
1584
1628
|
await this.sendNotification("initialized", {});
|
|
1585
1629
|
await this.sendNotification("workspace/didChangeConfiguration", {
|
|
1586
1630
|
settings: { json: { validate: { enable: true } } }
|
|
@@ -1767,6 +1811,17 @@ function canonicalPath(filePath) {
|
|
|
1767
1811
|
return absolute;
|
|
1768
1812
|
}
|
|
1769
1813
|
}
|
|
1814
|
+
function normalizeDocumentUri(uri) {
|
|
1815
|
+
let decoded = uri;
|
|
1816
|
+
try {
|
|
1817
|
+
decoded = decodeURIComponent(uri);
|
|
1818
|
+
} catch {
|
|
1819
|
+
decoded = uri;
|
|
1820
|
+
}
|
|
1821
|
+
if (process.platform !== "win32")
|
|
1822
|
+
return decoded;
|
|
1823
|
+
return decoded.replace(/^(file:\/\/\/)([a-z]):/, (_match, prefix, drive) => `${prefix}${drive.toUpperCase()}:`);
|
|
1824
|
+
}
|
|
1770
1825
|
function isSameOrDescendant(candidate, parent) {
|
|
1771
1826
|
const suffix = relative2(parent, candidate);
|
|
1772
1827
|
return suffix === "" || !suffix.startsWith("..") && suffix !== "..";
|
|
@@ -1777,30 +1832,31 @@ function movedPath(candidate, oldPath, newPath) {
|
|
|
1777
1832
|
}
|
|
1778
1833
|
|
|
1779
1834
|
class WorkspaceDocumentState {
|
|
1780
|
-
sendNotification;
|
|
1781
|
-
clearDiagnostics;
|
|
1782
|
-
openDocuments = new Map;
|
|
1783
|
-
openByUri = new Map;
|
|
1784
|
-
openPromises = new Map;
|
|
1785
|
-
now;
|
|
1786
|
-
versionlessPublishQuiescenceMs;
|
|
1787
1835
|
constructor(sendNotification, clearDiagnostics, options = {}) {
|
|
1788
1836
|
this.sendNotification = sendNotification;
|
|
1789
1837
|
this.clearDiagnostics = clearDiagnostics;
|
|
1790
|
-
this.
|
|
1838
|
+
this.openDocuments = new Map;
|
|
1839
|
+
this.openByUri = new Map;
|
|
1840
|
+
this.openPromises = new Map;
|
|
1841
|
+
this.timerProvider = options.timerProvider ?? {
|
|
1842
|
+
now: options.now ?? (() => Date.now()),
|
|
1843
|
+
setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
|
|
1844
|
+
clearTimeout: (handle) => clearTimeout(handle)
|
|
1845
|
+
};
|
|
1846
|
+
this.now = () => this.timerProvider.now();
|
|
1791
1847
|
this.versionlessPublishQuiescenceMs = options.versionlessPublishQuiescenceMs ?? DEFAULT_VERSIONLESS_PUBLISH_QUIESCENCE_MS;
|
|
1792
1848
|
}
|
|
1793
1849
|
async openFile(filePath) {
|
|
1794
|
-
const
|
|
1795
|
-
const existingOpen = this.openPromises.get(
|
|
1850
|
+
const path = canonicalPath(filePath);
|
|
1851
|
+
const existingOpen = this.openPromises.get(path);
|
|
1796
1852
|
if (existingOpen) {
|
|
1797
1853
|
await existingOpen;
|
|
1798
|
-
return this.openFile(
|
|
1854
|
+
return this.openFile(path);
|
|
1799
1855
|
}
|
|
1800
|
-
const text = readFileSync2(
|
|
1801
|
-
const existing = this.openDocuments.get(
|
|
1856
|
+
const text = readFileSync2(path, "utf-8");
|
|
1857
|
+
const existing = this.openDocuments.get(path);
|
|
1802
1858
|
if (!existing)
|
|
1803
|
-
return this.openDocumentSingleFlight(
|
|
1859
|
+
return this.openDocumentSingleFlight(path, text);
|
|
1804
1860
|
if (existing.text === text)
|
|
1805
1861
|
return;
|
|
1806
1862
|
await this.changeDocument(existing, text);
|
|
@@ -1809,7 +1865,7 @@ class WorkspaceDocumentState {
|
|
|
1809
1865
|
return this.openDocuments.get(canonicalPath(filePath))?.version;
|
|
1810
1866
|
}
|
|
1811
1867
|
getStoredDiagnostics(uri) {
|
|
1812
|
-
const state = this.openByUri.get(uri);
|
|
1868
|
+
const state = this.openByUri.get(normalizeDocumentUri(uri));
|
|
1813
1869
|
if (!state)
|
|
1814
1870
|
return [];
|
|
1815
1871
|
return state.lastPublish?.diagnostics ?? state.pullCache?.diagnostics ?? [];
|
|
@@ -1831,13 +1887,13 @@ class WorkspaceDocumentState {
|
|
|
1831
1887
|
return state !== undefined && state.uri === snapshot.uri && state.version === snapshot.version && state.generation === snapshot.documentGeneration;
|
|
1832
1888
|
}
|
|
1833
1889
|
getPullCache(snapshot) {
|
|
1834
|
-
const state = this.openByUri.get(snapshot.uri);
|
|
1890
|
+
const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
|
|
1835
1891
|
if (!state?.pullCache || state.pullCache.documentVersion !== snapshot.version)
|
|
1836
1892
|
return null;
|
|
1837
1893
|
return state.pullCache;
|
|
1838
1894
|
}
|
|
1839
1895
|
recordPullDiagnostics(snapshot, report) {
|
|
1840
|
-
const state = this.openByUri.get(snapshot.uri);
|
|
1896
|
+
const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
|
|
1841
1897
|
if (!state)
|
|
1842
1898
|
return;
|
|
1843
1899
|
state.pullCache = {
|
|
@@ -1847,7 +1903,7 @@ class WorkspaceDocumentState {
|
|
|
1847
1903
|
};
|
|
1848
1904
|
}
|
|
1849
1905
|
recordPublishedDiagnostics(params) {
|
|
1850
|
-
const state = this.openByUri.get(params.uri);
|
|
1906
|
+
const state = this.openByUri.get(normalizeDocumentUri(params.uri));
|
|
1851
1907
|
if (!state)
|
|
1852
1908
|
return;
|
|
1853
1909
|
state.publishGeneration += 1;
|
|
@@ -1861,7 +1917,7 @@ class WorkspaceDocumentState {
|
|
|
1861
1917
|
this.notifyWaiters(state);
|
|
1862
1918
|
}
|
|
1863
1919
|
resolvePushDiagnostics(snapshot) {
|
|
1864
|
-
const state = this.openByUri.get(snapshot.uri);
|
|
1920
|
+
const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
|
|
1865
1921
|
if (!state?.lastPublish)
|
|
1866
1922
|
return { status: "missing" };
|
|
1867
1923
|
const publish = state.lastPublish;
|
|
@@ -1875,27 +1931,29 @@ class WorkspaceDocumentState {
|
|
|
1875
1931
|
return waitMs === 0 ? { status: "ready", diagnostics: publish.diagnostics } : { status: "wait", waitMs };
|
|
1876
1932
|
}
|
|
1877
1933
|
waitForDiagnosticsActivity(snapshot, timeoutMs) {
|
|
1878
|
-
const state = this.openByUri.get(snapshot.uri);
|
|
1934
|
+
const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
|
|
1879
1935
|
if (!state || timeoutMs <= 0)
|
|
1880
1936
|
return Promise.resolve();
|
|
1937
|
+
if (state.publishGeneration !== snapshot.publishGeneration)
|
|
1938
|
+
return Promise.resolve();
|
|
1881
1939
|
return new Promise((resolveActivity) => {
|
|
1882
1940
|
let settled = false;
|
|
1883
1941
|
const finish = () => {
|
|
1884
1942
|
if (settled)
|
|
1885
1943
|
return;
|
|
1886
1944
|
settled = true;
|
|
1887
|
-
clearTimeout(timer);
|
|
1945
|
+
this.timerProvider.clearTimeout(timer);
|
|
1888
1946
|
state.waiters.delete(finish);
|
|
1889
1947
|
resolveActivity();
|
|
1890
1948
|
};
|
|
1891
|
-
const timer = setTimeout(finish, timeoutMs);
|
|
1949
|
+
const timer = this.timerProvider.setTimeout(finish, timeoutMs);
|
|
1892
1950
|
if (typeof timer.unref === "function")
|
|
1893
1951
|
timer.unref();
|
|
1894
1952
|
state.waiters.add(finish);
|
|
1895
1953
|
});
|
|
1896
1954
|
}
|
|
1897
1955
|
validateVersions(operations) {
|
|
1898
|
-
const versions = new Map([...this.openDocuments].map(([
|
|
1956
|
+
const versions = new Map([...this.openDocuments].map(([path, state]) => [path, state.version]));
|
|
1899
1957
|
for (const operation of operations) {
|
|
1900
1958
|
if (operation.kind === "text") {
|
|
1901
1959
|
const current = versions.get(operation.path);
|
|
@@ -1911,17 +1969,17 @@ class WorkspaceDocumentState {
|
|
|
1911
1969
|
continue;
|
|
1912
1970
|
}
|
|
1913
1971
|
if (operation.kind === "rename") {
|
|
1914
|
-
const moved = [...versions].filter(([
|
|
1915
|
-
for (const [
|
|
1916
|
-
versions.delete(
|
|
1917
|
-
for (const [
|
|
1918
|
-
versions.set(movedPath(
|
|
1972
|
+
const moved = [...versions].filter(([path]) => isSameOrDescendant(path, operation.oldPath));
|
|
1973
|
+
for (const [path] of moved)
|
|
1974
|
+
versions.delete(path);
|
|
1975
|
+
for (const [path] of moved)
|
|
1976
|
+
versions.set(movedPath(path, operation.oldPath, operation.newPath), 1);
|
|
1919
1977
|
continue;
|
|
1920
1978
|
}
|
|
1921
1979
|
if (operation.kind === "delete") {
|
|
1922
|
-
for (const
|
|
1923
|
-
if (isSameOrDescendant(
|
|
1924
|
-
versions.delete(
|
|
1980
|
+
for (const path of [...versions.keys()]) {
|
|
1981
|
+
if (isSameOrDescendant(path, operation.path))
|
|
1982
|
+
versions.delete(path);
|
|
1925
1983
|
}
|
|
1926
1984
|
continue;
|
|
1927
1985
|
}
|
|
@@ -1965,8 +2023,8 @@ class WorkspaceDocumentState {
|
|
|
1965
2023
|
for (const state of moved)
|
|
1966
2024
|
await this.closeDocument(state);
|
|
1967
2025
|
for (const state of moved) {
|
|
1968
|
-
const
|
|
1969
|
-
await this.openDocumentSingleFlight(
|
|
2026
|
+
const path = movedPath(state.path, mutation.oldPath, mutation.newPath);
|
|
2027
|
+
await this.openDocumentSingleFlight(path, readFileSync2(path, "utf-8"));
|
|
1970
2028
|
}
|
|
1971
2029
|
if (moved.length === 0) {
|
|
1972
2030
|
watched.push({ uri: pathToFileURL2(mutation.oldPath).href, type: 3 });
|
|
@@ -1980,31 +2038,31 @@ class WorkspaceDocumentState {
|
|
|
1980
2038
|
if (removed.length === 0)
|
|
1981
2039
|
watched.push({ uri: pathToFileURL2(mutation.path).href, type: 3 });
|
|
1982
2040
|
}
|
|
1983
|
-
async openDocumentSingleFlight(
|
|
1984
|
-
const existing = this.openPromises.get(
|
|
2041
|
+
async openDocumentSingleFlight(path, text) {
|
|
2042
|
+
const existing = this.openPromises.get(path);
|
|
1985
2043
|
if (existing)
|
|
1986
2044
|
return existing;
|
|
1987
2045
|
const open = (async () => {
|
|
1988
2046
|
const state = {
|
|
1989
|
-
path
|
|
1990
|
-
uri: pathToFileURL2(
|
|
1991
|
-
languageId: getLanguageId(effectiveExtension(
|
|
2047
|
+
path,
|
|
2048
|
+
uri: pathToFileURL2(path).href,
|
|
2049
|
+
languageId: getLanguageId(effectiveExtension(path)),
|
|
1992
2050
|
text,
|
|
1993
2051
|
version: 1,
|
|
1994
2052
|
generation: 1,
|
|
1995
2053
|
publishGeneration: 0,
|
|
1996
2054
|
waiters: new Set
|
|
1997
2055
|
};
|
|
1998
|
-
this.openDocuments.set(
|
|
1999
|
-
this.openByUri.set(state.uri, state);
|
|
2056
|
+
this.openDocuments.set(path, state);
|
|
2057
|
+
this.openByUri.set(normalizeDocumentUri(state.uri), state);
|
|
2000
2058
|
this.notifyWaiters(state);
|
|
2001
2059
|
await this.sendNotification("textDocument/didOpen", {
|
|
2002
2060
|
textDocument: { uri: state.uri, languageId: state.languageId, version: state.version, text }
|
|
2003
2061
|
});
|
|
2004
2062
|
})().finally(() => {
|
|
2005
|
-
this.openPromises.delete(
|
|
2063
|
+
this.openPromises.delete(path);
|
|
2006
2064
|
});
|
|
2007
|
-
this.openPromises.set(
|
|
2065
|
+
this.openPromises.set(path, open);
|
|
2008
2066
|
return open;
|
|
2009
2067
|
}
|
|
2010
2068
|
async changeDocument(state, text) {
|
|
@@ -2021,7 +2079,7 @@ class WorkspaceDocumentState {
|
|
|
2021
2079
|
}
|
|
2022
2080
|
async closeDocument(state) {
|
|
2023
2081
|
this.openDocuments.delete(state.path);
|
|
2024
|
-
this.openByUri.delete(state.uri);
|
|
2082
|
+
this.openByUri.delete(normalizeDocumentUri(state.uri));
|
|
2025
2083
|
this.clearDiagnostics(state.uri);
|
|
2026
2084
|
this.notifyWaiters(state);
|
|
2027
2085
|
await this.sendNotification("textDocument/didClose", { textDocument: { uri: state.uri } });
|
|
@@ -2040,13 +2098,11 @@ function workspaceApplyEditConcurrentFailureReason(phase) {
|
|
|
2040
2098
|
}
|
|
2041
2099
|
|
|
2042
2100
|
class WorkspaceEditPathError extends Error {
|
|
2043
|
-
path
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
constructor(path2, detail) {
|
|
2047
|
-
super(`${detail}: ${path2}`);
|
|
2048
|
-
this.path = path2;
|
|
2101
|
+
constructor(path, detail) {
|
|
2102
|
+
super(`${detail}: ${path}`);
|
|
2103
|
+
this.path = path;
|
|
2049
2104
|
this.detail = detail;
|
|
2105
|
+
this.name = "WorkspaceEditPathError";
|
|
2050
2106
|
}
|
|
2051
2107
|
}
|
|
2052
2108
|
function isPathInsideWorkspace(filePath, workspaceRoot) {
|
|
@@ -2108,26 +2164,26 @@ function uriToCanonicalWorkspacePath(uri, workspaceRoot) {
|
|
|
2108
2164
|
return { success: false, error: `${requestedPath}: ${detail}` };
|
|
2109
2165
|
}
|
|
2110
2166
|
}
|
|
2111
|
-
function snapshotPath(
|
|
2112
|
-
if (!existsSync4(
|
|
2167
|
+
function snapshotPath(path, includeChildren) {
|
|
2168
|
+
if (!existsSync4(path))
|
|
2113
2169
|
return { kind: "missing" };
|
|
2114
|
-
const stats = lstatSync2(
|
|
2170
|
+
const stats = lstatSync2(path);
|
|
2115
2171
|
if (stats.isFile())
|
|
2116
|
-
return { kind: "file", content: readFileSync3(
|
|
2172
|
+
return { kind: "file", content: readFileSync3(path, "utf-8") };
|
|
2117
2173
|
if (stats.isDirectory()) {
|
|
2118
|
-
return includeChildren ? { kind: "directory", children: readdirSync(
|
|
2174
|
+
return includeChildren ? { kind: "directory", children: readdirSync(path).sort() } : { kind: "directory" };
|
|
2119
2175
|
}
|
|
2120
|
-
throw new WorkspaceEditPathError(
|
|
2176
|
+
throw new WorkspaceEditPathError(path, "unsupported filesystem entry");
|
|
2121
2177
|
}
|
|
2122
2178
|
var DEFAULT_IO = {
|
|
2123
|
-
writeFile(
|
|
2124
|
-
writeFileSync(
|
|
2179
|
+
writeFile(path, content) {
|
|
2180
|
+
writeFileSync(path, content, "utf-8");
|
|
2125
2181
|
},
|
|
2126
2182
|
rename(oldPath, newPath) {
|
|
2127
2183
|
renameSync(oldPath, newPath);
|
|
2128
2184
|
},
|
|
2129
|
-
remove(
|
|
2130
|
-
rmSync(
|
|
2185
|
+
remove(path, recursive) {
|
|
2186
|
+
rmSync(path, { recursive, force: false });
|
|
2131
2187
|
}
|
|
2132
2188
|
};
|
|
2133
2189
|
function snapshotsEqual(expected, actual) {
|
|
@@ -2140,8 +2196,8 @@ function snapshotsEqual(expected, actual) {
|
|
|
2140
2196
|
}
|
|
2141
2197
|
return true;
|
|
2142
2198
|
}
|
|
2143
|
-
function liveSnapshot(
|
|
2144
|
-
return snapshotPath(
|
|
2199
|
+
function liveSnapshot(path, expected) {
|
|
2200
|
+
return snapshotPath(path, expected.kind === "directory" && expected.children !== undefined);
|
|
2145
2201
|
}
|
|
2146
2202
|
function firstOperationIndex(plan) {
|
|
2147
2203
|
return plan.operations[0]?.changeIndex ?? 0;
|
|
@@ -2162,28 +2218,28 @@ function failedCommit(plan, failure) {
|
|
|
2162
2218
|
};
|
|
2163
2219
|
}
|
|
2164
2220
|
function verifySnapshots(plan) {
|
|
2165
|
-
for (const [
|
|
2221
|
+
for (const [path, expected] of plan.snapshots) {
|
|
2166
2222
|
let actual;
|
|
2167
2223
|
try {
|
|
2168
|
-
actual = liveSnapshot(
|
|
2224
|
+
actual = liveSnapshot(path, expected);
|
|
2169
2225
|
} catch (error) {
|
|
2170
|
-
const changeIndex = plan.firstChangeByPath.get(
|
|
2226
|
+
const changeIndex = plan.firstChangeByPath.get(path) ?? firstOperationIndex(plan);
|
|
2171
2227
|
const detail = error instanceof Error ? error.message : String(error);
|
|
2172
|
-
return failedCommit(plan, { message: `cannot verify snapshot for ${
|
|
2228
|
+
return failedCommit(plan, { message: `cannot verify snapshot for ${path}: ${detail}`, changeIndex });
|
|
2173
2229
|
}
|
|
2174
2230
|
if (!snapshotsEqual(expected, actual)) {
|
|
2175
|
-
const changeIndex = plan.firstChangeByPath.get(
|
|
2176
|
-
return failedCommit(plan, { message: `workspace state changed before commit: ${
|
|
2231
|
+
const changeIndex = plan.firstChangeByPath.get(path) ?? firstOperationIndex(plan);
|
|
2232
|
+
return failedCommit(plan, { message: `workspace state changed before commit: ${path}`, changeIndex });
|
|
2177
2233
|
}
|
|
2178
2234
|
}
|
|
2179
2235
|
return null;
|
|
2180
2236
|
}
|
|
2181
|
-
function addModifiedPath(paths,
|
|
2182
|
-
if (!paths.includes(
|
|
2183
|
-
paths.push(
|
|
2237
|
+
function addModifiedPath(paths, path) {
|
|
2238
|
+
if (!paths.includes(path))
|
|
2239
|
+
paths.push(path);
|
|
2184
2240
|
}
|
|
2185
|
-
function reportedPath(plan,
|
|
2186
|
-
return plan.reportedPathByCanonical.get(
|
|
2241
|
+
function reportedPath(plan, path) {
|
|
2242
|
+
return plan.reportedPathByCanonical.get(path) ?? path;
|
|
2187
2243
|
}
|
|
2188
2244
|
function changedPathsForMutation(mutation) {
|
|
2189
2245
|
return mutation.kind === "rename" ? [mutation.oldPath, mutation.newPath] : [mutation.path];
|
|
@@ -2191,8 +2247,8 @@ function changedPathsForMutation(mutation) {
|
|
|
2191
2247
|
function mutationDelta(operations) {
|
|
2192
2248
|
const changedPaths = new Set;
|
|
2193
2249
|
for (const operation of operations) {
|
|
2194
|
-
for (const
|
|
2195
|
-
changedPaths.add(
|
|
2250
|
+
for (const path of changedPathsForMutation(operation))
|
|
2251
|
+
changedPaths.add(path);
|
|
2196
2252
|
}
|
|
2197
2253
|
return { operations, changedPaths: [...changedPaths].sort() };
|
|
2198
2254
|
}
|
|
@@ -2332,13 +2388,11 @@ function canonicalFingerprint(operations) {
|
|
|
2332
2388
|
}
|
|
2333
2389
|
|
|
2334
2390
|
class WorkspaceEditValidationError extends Error {
|
|
2335
|
-
changeIndex;
|
|
2336
|
-
detail;
|
|
2337
|
-
name = "WorkspaceEditValidationError";
|
|
2338
2391
|
constructor(changeIndex, detail) {
|
|
2339
2392
|
super(`change ${changeIndex}: ${detail}`);
|
|
2340
2393
|
this.changeIndex = changeIndex;
|
|
2341
2394
|
this.detail = detail;
|
|
2395
|
+
this.name = "WorkspaceEditValidationError";
|
|
2342
2396
|
}
|
|
2343
2397
|
}
|
|
2344
2398
|
function isRecord3(value) {
|
|
@@ -2420,14 +2474,14 @@ function parseSinglePathResource(input, kind) {
|
|
|
2420
2474
|
return;
|
|
2421
2475
|
}
|
|
2422
2476
|
if (kind === "create") {
|
|
2423
|
-
const
|
|
2477
|
+
const options = parseOptions(change["options"], ["overwrite", "ignoreIfExists"], changeIndex);
|
|
2424
2478
|
target.operations.push({
|
|
2425
2479
|
kind,
|
|
2426
2480
|
changeIndex,
|
|
2427
2481
|
path: resolvedPath.path,
|
|
2428
2482
|
reportedPath: resolvedPath.requestedPath,
|
|
2429
|
-
overwrite:
|
|
2430
|
-
ignoreIfExists:
|
|
2483
|
+
overwrite: options["overwrite"] ?? false,
|
|
2484
|
+
ignoreIfExists: options["ignoreIfExists"] ?? false,
|
|
2431
2485
|
followedSymbolicLink: resolvedPath.followedSymbolicLink
|
|
2432
2486
|
});
|
|
2433
2487
|
return;
|
|
@@ -2676,12 +2730,12 @@ function isSameOrDescendant2(candidate, parent) {
|
|
|
2676
2730
|
const relativePath = relative4(parent, candidate);
|
|
2677
2731
|
return relativePath === "" || !relativePath.startsWith("..") && relativePath !== "..";
|
|
2678
2732
|
}
|
|
2679
|
-
function removeVirtualSubtree(virtual,
|
|
2733
|
+
function removeVirtualSubtree(virtual, path) {
|
|
2680
2734
|
for (const candidate of [...virtual.keys()]) {
|
|
2681
|
-
if (isSameOrDescendant2(candidate,
|
|
2735
|
+
if (isSameOrDescendant2(candidate, path))
|
|
2682
2736
|
virtual.delete(candidate);
|
|
2683
2737
|
}
|
|
2684
|
-
virtual.set(
|
|
2738
|
+
virtual.set(path, { kind: "missing" });
|
|
2685
2739
|
}
|
|
2686
2740
|
function moveVirtualSubtree(virtual, oldPath, newPath) {
|
|
2687
2741
|
const moved = [...virtual.entries()].filter(([candidate]) => isSameOrDescendant2(candidate, oldPath));
|
|
@@ -2692,16 +2746,16 @@ function moveVirtualSubtree(virtual, oldPath, newPath) {
|
|
|
2692
2746
|
virtual.set(suffix === "" ? newPath : resolve4(newPath, suffix), entry);
|
|
2693
2747
|
}
|
|
2694
2748
|
}
|
|
2695
|
-
function virtualDirectoryHasChildren(virtual,
|
|
2749
|
+
function virtualDirectoryHasChildren(virtual, path) {
|
|
2696
2750
|
for (const [candidate, entry] of virtual) {
|
|
2697
|
-
if (candidate !==
|
|
2751
|
+
if (candidate !== path && entry.kind !== "missing" && isSameOrDescendant2(candidate, path))
|
|
2698
2752
|
return true;
|
|
2699
2753
|
}
|
|
2700
2754
|
return false;
|
|
2701
2755
|
}
|
|
2702
|
-
function requireVirtualParent(virtual,
|
|
2703
|
-
if (virtual.get(dirname5(
|
|
2704
|
-
throw new WorkspaceEditValidationError(changeIndex, `parent directory does not exist for ${
|
|
2756
|
+
function requireVirtualParent(virtual, path, changeIndex) {
|
|
2757
|
+
if (virtual.get(dirname5(path))?.kind !== "directory") {
|
|
2758
|
+
throw new WorkspaceEditValidationError(changeIndex, `parent directory does not exist for ${path}`);
|
|
2705
2759
|
}
|
|
2706
2760
|
}
|
|
2707
2761
|
function simulateOperations(parsed, snapshots) {
|
|
@@ -2820,10 +2874,9 @@ function simulateDelete(operation, virtual) {
|
|
|
2820
2874
|
}
|
|
2821
2875
|
|
|
2822
2876
|
class WorkspaceSnapshotBuilder {
|
|
2823
|
-
workspaceRoot;
|
|
2824
|
-
snapshots = new Map;
|
|
2825
2877
|
constructor(workspaceRoot) {
|
|
2826
2878
|
this.workspaceRoot = workspaceRoot;
|
|
2879
|
+
this.snapshots = new Map;
|
|
2827
2880
|
}
|
|
2828
2881
|
build(operations) {
|
|
2829
2882
|
this.add(this.workspaceRoot, false);
|
|
@@ -2844,21 +2897,21 @@ class WorkspaceSnapshotBuilder {
|
|
|
2844
2897
|
}
|
|
2845
2898
|
return this.snapshots;
|
|
2846
2899
|
}
|
|
2847
|
-
add(
|
|
2848
|
-
let candidate =
|
|
2900
|
+
add(path, includeChildren) {
|
|
2901
|
+
let candidate = path;
|
|
2849
2902
|
while (true) {
|
|
2850
2903
|
const existing = this.snapshots.get(candidate);
|
|
2851
2904
|
if (existing === undefined || includeChildren && existing.kind === "directory" && existing.children === undefined) {
|
|
2852
|
-
this.snapshots.set(candidate, snapshotPath(candidate, includeChildren && candidate ===
|
|
2905
|
+
this.snapshots.set(candidate, snapshotPath(candidate, includeChildren && candidate === path));
|
|
2853
2906
|
}
|
|
2854
2907
|
if (candidate === this.workspaceRoot)
|
|
2855
2908
|
break;
|
|
2856
2909
|
candidate = dirname6(candidate);
|
|
2857
2910
|
}
|
|
2858
|
-
if (!includeChildren || !existsSync6(
|
|
2911
|
+
if (!includeChildren || !existsSync6(path) || !lstatSync4(path).isDirectory())
|
|
2859
2912
|
return;
|
|
2860
|
-
for (const child of readdirSync2(
|
|
2861
|
-
this.add(resolve5(
|
|
2913
|
+
for (const child of readdirSync2(path))
|
|
2914
|
+
this.add(resolve5(path, child), true);
|
|
2862
2915
|
}
|
|
2863
2916
|
}
|
|
2864
2917
|
function snapshotOperations(operations, workspaceRoot) {
|
|
@@ -2866,8 +2919,10 @@ function snapshotOperations(operations, workspaceRoot) {
|
|
|
2866
2919
|
}
|
|
2867
2920
|
|
|
2868
2921
|
class PlanPathIndex {
|
|
2869
|
-
|
|
2870
|
-
|
|
2922
|
+
constructor() {
|
|
2923
|
+
this.firstChangeByPath = new Map;
|
|
2924
|
+
this.reportedPathByCanonical = new Map;
|
|
2925
|
+
}
|
|
2871
2926
|
build(operations) {
|
|
2872
2927
|
for (const operation of operations) {
|
|
2873
2928
|
switch (operation.kind) {
|
|
@@ -2883,11 +2938,11 @@ class PlanPathIndex {
|
|
|
2883
2938
|
}
|
|
2884
2939
|
}
|
|
2885
2940
|
}
|
|
2886
|
-
add(
|
|
2887
|
-
if (!this.firstChangeByPath.has(
|
|
2888
|
-
this.firstChangeByPath.set(
|
|
2889
|
-
if (!this.reportedPathByCanonical.has(
|
|
2890
|
-
this.reportedPathByCanonical.set(
|
|
2941
|
+
add(path, reportedPath, changeIndex) {
|
|
2942
|
+
if (!this.firstChangeByPath.has(path))
|
|
2943
|
+
this.firstChangeByPath.set(path, changeIndex);
|
|
2944
|
+
if (!this.reportedPathByCanonical.has(path))
|
|
2945
|
+
this.reportedPathByCanonical.set(path, reportedPath);
|
|
2891
2946
|
}
|
|
2892
2947
|
}
|
|
2893
2948
|
function fingerprintWorkspaceEdit(edit, workspaceRoot) {
|
|
@@ -2954,14 +3009,11 @@ function isRecord4(value) {
|
|
|
2954
3009
|
}
|
|
2955
3010
|
|
|
2956
3011
|
class WorkspaceMutationController {
|
|
2957
|
-
workspaceRoot;
|
|
2958
|
-
documents;
|
|
2959
|
-
activeLease = null;
|
|
2960
|
-
nextLeaseId = 1;
|
|
2961
|
-
io;
|
|
2962
3012
|
constructor(workspaceRoot, documents) {
|
|
2963
3013
|
this.workspaceRoot = workspaceRoot;
|
|
2964
3014
|
this.documents = documents;
|
|
3015
|
+
this.activeLease = null;
|
|
3016
|
+
this.nextLeaseId = 1;
|
|
2965
3017
|
}
|
|
2966
3018
|
setIo(io) {
|
|
2967
3019
|
this.io = io;
|
|
@@ -3000,15 +3052,15 @@ class WorkspaceMutationController {
|
|
|
3000
3052
|
};
|
|
3001
3053
|
}
|
|
3002
3054
|
lease.phase = "applying";
|
|
3003
|
-
lease.applyCompletion = new Promise((
|
|
3004
|
-
lease.resolveApply =
|
|
3055
|
+
lease.applyCompletion = new Promise((resolve) => {
|
|
3056
|
+
lease.resolveApply = resolve;
|
|
3005
3057
|
});
|
|
3006
3058
|
const edit = isRecord4(params) ? params["edit"] : undefined;
|
|
3007
|
-
const
|
|
3008
|
-
lease.serverApply =
|
|
3059
|
+
const record = edit === undefined ? { fingerprint: null, result: failure("workspace/applyEdit params.edit is required", 0) } : await this.applyEdit(edit, lease);
|
|
3060
|
+
lease.serverApply = record;
|
|
3009
3061
|
lease.phase = "settled";
|
|
3010
3062
|
lease.resolveApply?.();
|
|
3011
|
-
return responseFor(
|
|
3063
|
+
return responseFor(record.result);
|
|
3012
3064
|
}
|
|
3013
3065
|
async reconcileRename(leaseToken, edit) {
|
|
3014
3066
|
const lease = this.requireActiveLease(leaseToken);
|
|
@@ -3024,16 +3076,16 @@ class WorkspaceMutationController {
|
|
|
3024
3076
|
const applied = await this.applyEdit(edit, lease);
|
|
3025
3077
|
return { edit, apply: applied.result };
|
|
3026
3078
|
}
|
|
3027
|
-
reconcileServerApply(
|
|
3079
|
+
reconcileServerApply(record, edit) {
|
|
3028
3080
|
if (!edit)
|
|
3029
|
-
return { edit, apply:
|
|
3081
|
+
return { edit, apply: record.result };
|
|
3030
3082
|
const fingerprint = fingerprintWorkspaceEdit(edit, this.workspaceRoot);
|
|
3031
|
-
if (fingerprint.success &&
|
|
3032
|
-
return { edit, apply:
|
|
3083
|
+
if (fingerprint.success && record.fingerprint !== null && fingerprint.fingerprint === record.fingerprint) {
|
|
3084
|
+
return { edit, apply: record.result };
|
|
3033
3085
|
}
|
|
3034
3086
|
return {
|
|
3035
3087
|
edit,
|
|
3036
|
-
apply: failure("rename result conflicts with server-applied workspace edit", 0,
|
|
3088
|
+
apply: failure("rename result conflicts with server-applied workspace edit", 0, record.result)
|
|
3037
3089
|
};
|
|
3038
3090
|
}
|
|
3039
3091
|
async applyEdit(edit, lease) {
|
|
@@ -3072,14 +3124,12 @@ var DIAGNOSTICS_FRESHNESS_TIMEOUT_MS = 3000;
|
|
|
3072
3124
|
var VERSIONLESS_PUBLISH_QUIESCENCE_MS = 250;
|
|
3073
3125
|
|
|
3074
3126
|
class LspClient extends LspClientConnection {
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
diagnosticsFreshnessTimeoutMs;
|
|
3079
|
-
constructor(root, server2, options = {}) {
|
|
3080
|
-
super(root, server2, options);
|
|
3127
|
+
constructor(root, server, options = {}) {
|
|
3128
|
+
super(root, server, options);
|
|
3129
|
+
this.diagnosticPullErrors = [];
|
|
3081
3130
|
this.diagnosticsFreshnessTimeoutMs = options.diagnosticsFreshnessTimeoutMs ?? DIAGNOSTICS_FRESHNESS_TIMEOUT_MS;
|
|
3082
3131
|
this.documents = new WorkspaceDocumentState((method, params) => this.sendNotification(method, params), (uri) => this.diagnosticsStore.delete(uri), {
|
|
3132
|
+
timerProvider: this.timerProvider,
|
|
3083
3133
|
versionlessPublishQuiescenceMs: options.versionlessPublishQuiescenceMs ?? VERSIONLESS_PUBLISH_QUIESCENCE_MS
|
|
3084
3134
|
});
|
|
3085
3135
|
this.workspaceMutations = new WorkspaceMutationController(root, this.documents);
|
|
@@ -3132,6 +3182,18 @@ class LspClient extends LspClientConnection {
|
|
|
3132
3182
|
textDocument: { uri: pathToFileURL3(absPath).href }
|
|
3133
3183
|
}, options);
|
|
3134
3184
|
}
|
|
3185
|
+
async formatDocument(filePath, options, signal) {
|
|
3186
|
+
if (!this.isDocumentFormattingSupported())
|
|
3187
|
+
return null;
|
|
3188
|
+
const absPath = this.resolveWorkspacePath(filePath);
|
|
3189
|
+
await this.openFile(absPath);
|
|
3190
|
+
const requestOptions = signal === undefined ? {} : { signal };
|
|
3191
|
+
const edits = await this.sendRequest("textDocument/formatting", {
|
|
3192
|
+
textDocument: { uri: pathToFileURL3(absPath).href },
|
|
3193
|
+
options
|
|
3194
|
+
}, requestOptions);
|
|
3195
|
+
return edits ?? [];
|
|
3196
|
+
}
|
|
3135
3197
|
async workspaceSymbols(query, signal) {
|
|
3136
3198
|
const options = signal === undefined ? {} : { signal };
|
|
3137
3199
|
return this.sendRequest("workspace/symbol", { query }, options);
|
|
@@ -3171,7 +3233,7 @@ class LspClient extends LspClientConnection {
|
|
|
3171
3233
|
const absPath = this.resolveWorkspacePath(filePath);
|
|
3172
3234
|
const uri = pathToFileURL3(absPath).href;
|
|
3173
3235
|
await this.openFile(absPath);
|
|
3174
|
-
const deadlineAt =
|
|
3236
|
+
const deadlineAt = this.timerProvider.now() + this.diagnosticsFreshnessTimeoutMs;
|
|
3175
3237
|
for (;; ) {
|
|
3176
3238
|
signal?.throwIfAborted();
|
|
3177
3239
|
const snapshot = this.documents.captureDiagnosticSnapshot(absPath);
|
|
@@ -3184,13 +3246,13 @@ class LspClient extends LspClientConnection {
|
|
|
3184
3246
|
if (!pushFallbackOnly) {
|
|
3185
3247
|
const cached = this.documents.getPullCache(snapshot);
|
|
3186
3248
|
try {
|
|
3187
|
-
const
|
|
3188
|
-
if (
|
|
3249
|
+
const remainingMs = deadlineAt - this.timerProvider.now();
|
|
3250
|
+
if (remainingMs <= 0)
|
|
3189
3251
|
return this.freshnessTimeout(absPath);
|
|
3190
3252
|
const result = await this.sendRequest("textDocument/diagnostic", {
|
|
3191
3253
|
textDocument: { uri },
|
|
3192
3254
|
...cached?.resultId === undefined ? {} : { previousResultId: cached.resultId }
|
|
3193
|
-
}, { timeoutMs:
|
|
3255
|
+
}, { timeoutMs: remainingMs, ...signal === undefined ? {} : { signal } });
|
|
3194
3256
|
if (!this.documents.isCurrentSnapshot(snapshot))
|
|
3195
3257
|
continue;
|
|
3196
3258
|
const report = this.parseDiagnosticPullReport(result);
|
|
@@ -3219,7 +3281,7 @@ class LspClient extends LspClientConnection {
|
|
|
3219
3281
|
}
|
|
3220
3282
|
if (!pushFallbackOnly)
|
|
3221
3283
|
continue;
|
|
3222
|
-
const remainingMs = deadlineAt -
|
|
3284
|
+
const remainingMs = deadlineAt - this.timerProvider.now();
|
|
3223
3285
|
if (remainingMs <= 0) {
|
|
3224
3286
|
if (!this.isDiagnosticPullSupported() && snapshot.publishGeneration === 0) {
|
|
3225
3287
|
const cached = this.documents.getPullCache(snapshot);
|
|
@@ -3271,7 +3333,7 @@ function waitForDiagnosticsActivity(wait, signal) {
|
|
|
3271
3333
|
return wait;
|
|
3272
3334
|
if (signal.aborted)
|
|
3273
3335
|
return Promise.reject(abortError3(signal));
|
|
3274
|
-
return new Promise((
|
|
3336
|
+
return new Promise((resolve, reject) => {
|
|
3275
3337
|
const onAbort = () => {
|
|
3276
3338
|
signal.removeEventListener("abort", onAbort);
|
|
3277
3339
|
reject(abortError3(signal));
|
|
@@ -3279,7 +3341,7 @@ function waitForDiagnosticsActivity(wait, signal) {
|
|
|
3279
3341
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
3280
3342
|
wait.then(() => {
|
|
3281
3343
|
signal.removeEventListener("abort", onAbort);
|
|
3282
|
-
|
|
3344
|
+
resolve();
|
|
3283
3345
|
}, (error) => {
|
|
3284
3346
|
signal.removeEventListener("abort", onAbort);
|
|
3285
3347
|
reject(error);
|
|
@@ -3343,7 +3405,7 @@ async function stopClientBestEffort(client) {
|
|
|
3343
3405
|
function awaitWithSignal2(promise, signal) {
|
|
3344
3406
|
if (!signal)
|
|
3345
3407
|
return promise;
|
|
3346
|
-
return new Promise((
|
|
3408
|
+
return new Promise((resolve, reject) => {
|
|
3347
3409
|
let settled = false;
|
|
3348
3410
|
const onAbort = () => {
|
|
3349
3411
|
if (settled)
|
|
@@ -3361,7 +3423,7 @@ function awaitWithSignal2(promise, signal) {
|
|
|
3361
3423
|
return;
|
|
3362
3424
|
settled = true;
|
|
3363
3425
|
signal.removeEventListener("abort", onAbort);
|
|
3364
|
-
|
|
3426
|
+
resolve(value);
|
|
3365
3427
|
}, (err) => {
|
|
3366
3428
|
if (settled)
|
|
3367
3429
|
return;
|
|
@@ -3373,20 +3435,18 @@ function awaitWithSignal2(promise, signal) {
|
|
|
3373
3435
|
}
|
|
3374
3436
|
|
|
3375
3437
|
class LspManager {
|
|
3376
|
-
clients = new Map;
|
|
3377
|
-
reaperHandle = null;
|
|
3378
|
-
signalDisposer = null;
|
|
3379
|
-
disposed = false;
|
|
3380
|
-
idleTimeoutMs;
|
|
3381
|
-
initTimeoutMs;
|
|
3382
|
-
reaperIntervalMs;
|
|
3383
|
-
clientFactory;
|
|
3384
|
-
now;
|
|
3385
3438
|
constructor(options = {}) {
|
|
3439
|
+
this.clients = new Map;
|
|
3440
|
+
this.pendingStops = new Map;
|
|
3441
|
+
this.respawnBudgets = new Map;
|
|
3442
|
+
this.reaperHandle = null;
|
|
3443
|
+
this.signalDisposer = null;
|
|
3444
|
+
this.disposed = false;
|
|
3386
3445
|
this.idleTimeoutMs = options.idleTimeoutMs ?? IDLE_TIMEOUT_MS;
|
|
3387
3446
|
this.initTimeoutMs = options.initTimeoutMs ?? INIT_TIMEOUT_MS;
|
|
3447
|
+
this.maxResidentClients = options.maxResidentClients ?? MAX_RESIDENT_CLIENTS;
|
|
3388
3448
|
this.reaperIntervalMs = options.reaperIntervalMs ?? REAPER_INTERVAL_MS;
|
|
3389
|
-
this.clientFactory = options.clientFactory ?? ((root,
|
|
3449
|
+
this.clientFactory = options.clientFactory ?? ((root, server) => new LspClient(root, server));
|
|
3390
3450
|
this.now = options.now ?? (() => Date.now());
|
|
3391
3451
|
this.startReaper();
|
|
3392
3452
|
this.signalDisposer = installProcessSignalCleanup(() => this.stopAll());
|
|
@@ -3404,38 +3464,103 @@ class LspManager {
|
|
|
3404
3464
|
getKey(root, serverId) {
|
|
3405
3465
|
return `${root}::${serverId}`;
|
|
3406
3466
|
}
|
|
3467
|
+
tombstoneStop(key, client) {
|
|
3468
|
+
const stop = stopClientBestEffort(client);
|
|
3469
|
+
this.pendingStops.set(key, stop);
|
|
3470
|
+
stop.finally(() => {
|
|
3471
|
+
if (this.pendingStops.get(key) === stop) {
|
|
3472
|
+
this.pendingStops.delete(key);
|
|
3473
|
+
}
|
|
3474
|
+
});
|
|
3475
|
+
return stop;
|
|
3476
|
+
}
|
|
3477
|
+
recordDeadGeneration(key) {
|
|
3478
|
+
let budget = this.respawnBudgets.get(key);
|
|
3479
|
+
if (budget === undefined) {
|
|
3480
|
+
budget = { deadGenerations: 0, exhaustedAt: null };
|
|
3481
|
+
this.respawnBudgets.set(key, budget);
|
|
3482
|
+
}
|
|
3483
|
+
budget.deadGenerations += 1;
|
|
3484
|
+
}
|
|
3485
|
+
markHealthyGeneration(key) {
|
|
3486
|
+
this.respawnBudgets.delete(key);
|
|
3487
|
+
}
|
|
3488
|
+
ensureRespawnAllowed(key, root, serverId) {
|
|
3489
|
+
const budget = this.respawnBudgets.get(key);
|
|
3490
|
+
if (budget === undefined || budget.deadGenerations < CLIENT_RESPAWN_RETRY_LIMIT)
|
|
3491
|
+
return;
|
|
3492
|
+
if (budget.exhaustedAt === null) {
|
|
3493
|
+
budget.exhaustedAt = this.now();
|
|
3494
|
+
throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
|
|
3495
|
+
}
|
|
3496
|
+
if (this.now() - budget.exhaustedAt < CLIENT_RESPAWN_COOLDOWN_MS) {
|
|
3497
|
+
throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
|
|
3498
|
+
}
|
|
3499
|
+
budget.deadGenerations = 0;
|
|
3500
|
+
budget.exhaustedAt = null;
|
|
3501
|
+
}
|
|
3407
3502
|
reapStale() {
|
|
3408
3503
|
const t = this.now();
|
|
3409
3504
|
for (const [key, managed] of this.clients) {
|
|
3410
3505
|
if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
|
|
3411
|
-
stopClientBestEffort(managed.client);
|
|
3412
3506
|
this.clients.delete(key);
|
|
3507
|
+
this.tombstoneStop(key, managed.client);
|
|
3413
3508
|
continue;
|
|
3414
3509
|
}
|
|
3415
3510
|
if (!managed.isInitializing && managed.refCount === 0 && managed.pendingWaiters === 0 && t - managed.lastUsedAt > this.idleTimeoutMs) {
|
|
3416
|
-
stopClientBestEffort(managed.client);
|
|
3417
3511
|
this.clients.delete(key);
|
|
3512
|
+
this.tombstoneStop(key, managed.client);
|
|
3418
3513
|
}
|
|
3419
3514
|
}
|
|
3420
3515
|
}
|
|
3516
|
+
evictForAdmission() {
|
|
3517
|
+
while (this.clients.size >= this.maxResidentClients) {
|
|
3518
|
+
const victim = this.leastRecentlyUsedIdleClient();
|
|
3519
|
+
if (!victim)
|
|
3520
|
+
return;
|
|
3521
|
+
this.clients.delete(victim.key);
|
|
3522
|
+
this.tombstoneStop(victim.key, victim.managed.client);
|
|
3523
|
+
}
|
|
3524
|
+
}
|
|
3525
|
+
leastRecentlyUsedIdleClient() {
|
|
3526
|
+
let candidate = null;
|
|
3527
|
+
for (const [key, managed] of this.clients) {
|
|
3528
|
+
if (managed.refCount > 0 || managed.pendingWaiters > 0 || managed.isInitializing)
|
|
3529
|
+
continue;
|
|
3530
|
+
if (candidate === null || managed.lastUsedAt < candidate.managed.lastUsedAt) {
|
|
3531
|
+
candidate = { key, managed };
|
|
3532
|
+
}
|
|
3533
|
+
}
|
|
3534
|
+
return candidate;
|
|
3535
|
+
}
|
|
3421
3536
|
async tryDeleteIfOrphaned(key, managed) {
|
|
3422
3537
|
if (managed.refCount === 0 && managed.pendingWaiters === 0 && !managed.isInitializing && this.clients.get(key) === managed) {
|
|
3423
3538
|
this.clients.delete(key);
|
|
3424
|
-
await
|
|
3539
|
+
await this.tombstoneStop(key, managed.client);
|
|
3425
3540
|
}
|
|
3426
3541
|
}
|
|
3427
|
-
async getClient(root,
|
|
3542
|
+
async getClient(root, server, signal) {
|
|
3428
3543
|
if (this.disposed) {
|
|
3429
3544
|
throw new Error("LspManager has been disposed");
|
|
3430
3545
|
}
|
|
3431
3546
|
signal?.throwIfAborted();
|
|
3432
|
-
const key = this.getKey(root,
|
|
3547
|
+
const key = this.getKey(root, server.id);
|
|
3548
|
+
for (;; ) {
|
|
3549
|
+
const pendingStop = this.pendingStops.get(key);
|
|
3550
|
+
if (pendingStop === undefined)
|
|
3551
|
+
break;
|
|
3552
|
+
await awaitWithSignal2(pendingStop, signal);
|
|
3553
|
+
signal?.throwIfAborted();
|
|
3554
|
+
}
|
|
3555
|
+
if (this.disposed) {
|
|
3556
|
+
throw new Error("LspManager has been disposed");
|
|
3557
|
+
}
|
|
3433
3558
|
let managed = this.clients.get(key);
|
|
3434
3559
|
if (managed) {
|
|
3435
3560
|
const t = this.now();
|
|
3436
3561
|
if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
|
|
3437
|
-
await stopClientBestEffort(managed.client);
|
|
3438
3562
|
this.clients.delete(key);
|
|
3563
|
+
await this.tombstoneStop(key, managed.client);
|
|
3439
3564
|
managed = undefined;
|
|
3440
3565
|
}
|
|
3441
3566
|
}
|
|
@@ -3456,15 +3581,21 @@ class LspManager {
|
|
|
3456
3581
|
signal.throwIfAborted();
|
|
3457
3582
|
}
|
|
3458
3583
|
if (!managed.client.isAlive()) {
|
|
3459
|
-
|
|
3460
|
-
this.clients.
|
|
3461
|
-
|
|
3584
|
+
this.recordDeadGeneration(key);
|
|
3585
|
+
if (this.clients.get(key) === managed) {
|
|
3586
|
+
this.clients.delete(key);
|
|
3587
|
+
}
|
|
3588
|
+
await this.tombstoneStop(key, managed.client);
|
|
3589
|
+
return this.getClient(root, server, signal);
|
|
3462
3590
|
}
|
|
3591
|
+
this.markHealthyGeneration(key);
|
|
3463
3592
|
managed.refCount++;
|
|
3464
3593
|
managed.lastUsedAt = this.now();
|
|
3465
3594
|
return managed.client;
|
|
3466
3595
|
}
|
|
3467
|
-
|
|
3596
|
+
this.evictForAdmission();
|
|
3597
|
+
this.ensureRespawnAllowed(key, root, server.id);
|
|
3598
|
+
const client = this.clientFactory(root, server);
|
|
3468
3599
|
const initStartedAt = this.now();
|
|
3469
3600
|
const initPromise = (async () => {
|
|
3470
3601
|
await client.start();
|
|
@@ -3487,7 +3618,7 @@ class LspManager {
|
|
|
3487
3618
|
if (this.clients.get(key) === newManaged) {
|
|
3488
3619
|
this.clients.delete(key);
|
|
3489
3620
|
}
|
|
3490
|
-
await
|
|
3621
|
+
await this.tombstoneStop(key, client);
|
|
3491
3622
|
throw err;
|
|
3492
3623
|
}
|
|
3493
3624
|
newManaged.pendingWaiters--;
|
|
@@ -3498,6 +3629,15 @@ class LspManager {
|
|
|
3498
3629
|
await this.tryDeleteIfOrphaned(key, newManaged);
|
|
3499
3630
|
signal.throwIfAborted();
|
|
3500
3631
|
}
|
|
3632
|
+
if (!client.isAlive()) {
|
|
3633
|
+
this.recordDeadGeneration(key);
|
|
3634
|
+
if (this.clients.get(key) === newManaged) {
|
|
3635
|
+
this.clients.delete(key);
|
|
3636
|
+
}
|
|
3637
|
+
await this.tombstoneStop(key, client);
|
|
3638
|
+
return this.getClient(root, server, signal);
|
|
3639
|
+
}
|
|
3640
|
+
this.markHealthyGeneration(key);
|
|
3501
3641
|
newManaged.refCount++;
|
|
3502
3642
|
newManaged.lastUsedAt = this.now();
|
|
3503
3643
|
return client;
|
|
@@ -3518,15 +3658,21 @@ class LspManager {
|
|
|
3518
3658
|
if (client && managed.client !== client)
|
|
3519
3659
|
return;
|
|
3520
3660
|
this.clients.delete(key);
|
|
3521
|
-
|
|
3661
|
+
this.tombstoneStop(key, managed.client);
|
|
3522
3662
|
}
|
|
3523
|
-
warmupClient(root,
|
|
3663
|
+
warmupClient(root, server) {
|
|
3524
3664
|
if (this.disposed)
|
|
3525
3665
|
return;
|
|
3526
|
-
const key = this.getKey(root,
|
|
3527
|
-
if (this.clients.has(key))
|
|
3666
|
+
const key = this.getKey(root, server.id);
|
|
3667
|
+
if (this.clients.has(key) || this.pendingStops.has(key))
|
|
3528
3668
|
return;
|
|
3529
|
-
|
|
3669
|
+
this.evictForAdmission();
|
|
3670
|
+
try {
|
|
3671
|
+
this.ensureRespawnAllowed(key, root, server.id);
|
|
3672
|
+
} catch {
|
|
3673
|
+
return;
|
|
3674
|
+
}
|
|
3675
|
+
const client = this.clientFactory(root, server);
|
|
3530
3676
|
const initStartedAt = this.now();
|
|
3531
3677
|
const initPromise = (async () => {
|
|
3532
3678
|
await client.start();
|
|
@@ -3551,7 +3697,7 @@ class LspManager {
|
|
|
3551
3697
|
if (this.clients.get(key) === managed) {
|
|
3552
3698
|
this.clients.delete(key);
|
|
3553
3699
|
}
|
|
3554
|
-
|
|
3700
|
+
this.tombstoneStop(key, client);
|
|
3555
3701
|
});
|
|
3556
3702
|
}
|
|
3557
3703
|
isServerInitializing(root, serverId) {
|
|
@@ -3595,8 +3741,11 @@ class LspManager {
|
|
|
3595
3741
|
for (const managed of this.clients.values()) {
|
|
3596
3742
|
stopPromises.push(stopClientBestEffort(managed.client));
|
|
3597
3743
|
}
|
|
3744
|
+
const tombstonedStops = [...this.pendingStops.values()];
|
|
3598
3745
|
this.clients.clear();
|
|
3599
|
-
|
|
3746
|
+
this.respawnBudgets.clear();
|
|
3747
|
+
await Promise.allSettled([...stopPromises, ...tombstonedStops]);
|
|
3748
|
+
this.pendingStops.clear();
|
|
3600
3749
|
}
|
|
3601
3750
|
}
|
|
3602
3751
|
var _defaultInstance = null;
|
|
@@ -3606,49 +3755,43 @@ function getLspManager() {
|
|
|
3606
3755
|
}
|
|
3607
3756
|
return _defaultInstance;
|
|
3608
3757
|
}
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
|
|
3758
|
+
var GIT_WORKSPACE_MARKER = ".git";
|
|
3759
|
+
var PROJECT_WORKSPACE_MARKERS = [
|
|
3760
|
+
"package.json",
|
|
3761
|
+
"pyproject.toml",
|
|
3762
|
+
"Cargo.toml",
|
|
3763
|
+
"go.mod",
|
|
3764
|
+
"pom.xml",
|
|
3765
|
+
"build.gradle"
|
|
3766
|
+
];
|
|
3767
|
+
var WORKSPACE_MARKERS = [GIT_WORKSPACE_MARKER, ...PROJECT_WORKSPACE_MARKERS];
|
|
3768
|
+
function findWorkspaceRootOutsideContext(directory) {
|
|
3769
|
+
const marked = nearestMarkedAncestor(directory);
|
|
3770
|
+
if (marked !== undefined)
|
|
3771
|
+
return marked;
|
|
3772
|
+
return realpathSync4(nearestExistingAncestor(directory));
|
|
3773
|
+
}
|
|
3774
|
+
function nearestMarkedAncestor(directory) {
|
|
3775
|
+
let current = directory;
|
|
3776
|
+
for (;; ) {
|
|
3777
|
+
if (existsSync7(current) && WORKSPACE_MARKERS.some((marker) => existsSync7(join3(current, marker)))) {
|
|
3778
|
+
return realpathSync4(current);
|
|
3779
|
+
}
|
|
3780
|
+
const parent = dirname7(current);
|
|
3781
|
+
if (parent === current)
|
|
3782
|
+
return;
|
|
3783
|
+
current = parent;
|
|
3621
3784
|
}
|
|
3622
3785
|
}
|
|
3623
|
-
function
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
|
|
3629
|
-
|
|
3630
|
-
}
|
|
3631
|
-
|
|
3632
|
-
return value === "declined" || value === "allowed";
|
|
3633
|
-
}
|
|
3634
|
-
function writeInstallDecisions(decisions) {
|
|
3635
|
-
const path2 = getInstallDecisionsPath();
|
|
3636
|
-
mkdirSync3(dirname7(path2), { recursive: true });
|
|
3637
|
-
const tmpPath = `${path2}.tmp`;
|
|
3638
|
-
writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
|
|
3639
|
-
`, "utf8");
|
|
3640
|
-
renameSync2(tmpPath, path2);
|
|
3641
|
-
}
|
|
3642
|
-
function isInstallDecisions(value) {
|
|
3643
|
-
return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
|
|
3644
|
-
}
|
|
3645
|
-
function isInstallDecisionRecord(value) {
|
|
3646
|
-
if (!isRecord5(value))
|
|
3647
|
-
return false;
|
|
3648
|
-
return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
|
|
3649
|
-
}
|
|
3650
|
-
function isRecord5(value) {
|
|
3651
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3786
|
+
function nearestExistingAncestor(directory) {
|
|
3787
|
+
let current = directory;
|
|
3788
|
+
while (!existsSync7(current)) {
|
|
3789
|
+
const parent = dirname7(current);
|
|
3790
|
+
if (parent === current)
|
|
3791
|
+
return current;
|
|
3792
|
+
current = parent;
|
|
3793
|
+
}
|
|
3794
|
+
return current;
|
|
3652
3795
|
}
|
|
3653
3796
|
var LSP_INSTALL_HINTS = {
|
|
3654
3797
|
typescript: "npm install -g typescript-language-server typescript",
|
|
@@ -3694,6 +3837,26 @@ var LSP_INSTALL_HINTS = {
|
|
|
3694
3837
|
julials: `julia -e 'using Pkg; Pkg.add("LanguageServer")'`,
|
|
3695
3838
|
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"
|
|
3696
3839
|
};
|
|
3840
|
+
var LSP_LOCAL_INSTALL_HINTS = {
|
|
3841
|
+
typescript: "bun add -d typescript-language-server typescript",
|
|
3842
|
+
vue: "bun add -d @vue/language-server",
|
|
3843
|
+
eslint: "bun add -d vscode-langservers-extracted",
|
|
3844
|
+
oxlint: "bun add -d oxlint",
|
|
3845
|
+
biome: "bun add -d @biomejs/biome",
|
|
3846
|
+
svelte: "bun add -d svelte-language-server",
|
|
3847
|
+
astro: "bun add -d @astrojs/language-server",
|
|
3848
|
+
bash: "bun add -d bash-language-server",
|
|
3849
|
+
"bash-ls": "bun add -d bash-language-server",
|
|
3850
|
+
"yaml-ls": "bun add -d yaml-language-server",
|
|
3851
|
+
php: "bun add -d intelephense",
|
|
3852
|
+
prisma: "bun add -d prisma",
|
|
3853
|
+
dockerfile: "bun add -d dockerfile-language-server-nodejs",
|
|
3854
|
+
pyright: "uv add --dev pyright",
|
|
3855
|
+
basedpyright: "uv add --dev basedpyright",
|
|
3856
|
+
ruff: "uv add --dev ruff",
|
|
3857
|
+
ty: "uv add --dev ty",
|
|
3858
|
+
"ruby-lsp": "bundle add ruby-lsp --group development"
|
|
3859
|
+
};
|
|
3697
3860
|
var BUILTIN_SERVERS = {
|
|
3698
3861
|
typescript: {
|
|
3699
3862
|
command: ["typescript-language-server", "--stdio"],
|
|
@@ -3795,17 +3958,61 @@ var BUILTIN_SERVERS = {
|
|
|
3795
3958
|
extensions: [".razor", ".cshtml"]
|
|
3796
3959
|
}
|
|
3797
3960
|
};
|
|
3961
|
+
function getInstallDecisionsPath() {
|
|
3962
|
+
return lspRequestContext().installDecisionsPath;
|
|
3963
|
+
}
|
|
3964
|
+
function loadInstallDecisions() {
|
|
3965
|
+
const path = getInstallDecisionsPath();
|
|
3966
|
+
if (!existsSync8(path))
|
|
3967
|
+
return {};
|
|
3968
|
+
try {
|
|
3969
|
+
const parsed = JSON.parse(readFileSync4(path, "utf8"));
|
|
3970
|
+
return isInstallDecisions(parsed) ? parsed : {};
|
|
3971
|
+
} catch {
|
|
3972
|
+
return {};
|
|
3973
|
+
}
|
|
3974
|
+
}
|
|
3975
|
+
function loadInstallDecision(serverId) {
|
|
3976
|
+
return loadInstallDecisions()[serverId];
|
|
3977
|
+
}
|
|
3978
|
+
function recordInstallDecision(serverId, decision, decidedAt = new Date().toISOString()) {
|
|
3979
|
+
const decisions = loadInstallDecisions();
|
|
3980
|
+
decisions[serverId] = { decision, decidedAt };
|
|
3981
|
+
writeInstallDecisions(decisions);
|
|
3982
|
+
}
|
|
3983
|
+
function isInstallDecision(value) {
|
|
3984
|
+
return value === "declined" || value === "allowed";
|
|
3985
|
+
}
|
|
3986
|
+
function writeInstallDecisions(decisions) {
|
|
3987
|
+
const path = getInstallDecisionsPath();
|
|
3988
|
+
mkdirSync3(dirname8(path), { recursive: true });
|
|
3989
|
+
const tmpPath = `${path}.tmp`;
|
|
3990
|
+
writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
|
|
3991
|
+
`, "utf8");
|
|
3992
|
+
renameSync2(tmpPath, path);
|
|
3993
|
+
}
|
|
3994
|
+
function isInstallDecisions(value) {
|
|
3995
|
+
return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
|
|
3996
|
+
}
|
|
3997
|
+
function isInstallDecisionRecord(value) {
|
|
3998
|
+
if (!isRecord5(value))
|
|
3999
|
+
return false;
|
|
4000
|
+
return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
|
|
4001
|
+
}
|
|
4002
|
+
function isRecord5(value) {
|
|
4003
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4004
|
+
}
|
|
3798
4005
|
function getProjectConfigPaths() {
|
|
3799
4006
|
return lspRequestContext().projectConfigPaths;
|
|
3800
4007
|
}
|
|
3801
4008
|
function getUserConfigPath() {
|
|
3802
4009
|
return lspRequestContext().userConfigPath;
|
|
3803
4010
|
}
|
|
3804
|
-
function loadJsonFile(
|
|
3805
|
-
if (!
|
|
4011
|
+
function loadJsonFile(path) {
|
|
4012
|
+
if (!existsSync9(path))
|
|
3806
4013
|
return null;
|
|
3807
4014
|
try {
|
|
3808
|
-
const parsed = JSON.parse(readFileSync5(
|
|
4015
|
+
const parsed = JSON.parse(readFileSync5(path, "utf-8"));
|
|
3809
4016
|
return isConfigJson(parsed) ? parsed : null;
|
|
3810
4017
|
} catch {
|
|
3811
4018
|
return null;
|
|
@@ -3822,8 +4029,8 @@ function loadAllConfigs() {
|
|
|
3822
4029
|
return configs;
|
|
3823
4030
|
}
|
|
3824
4031
|
function loadFirstJsonFile(paths) {
|
|
3825
|
-
for (const
|
|
3826
|
-
const config = loadJsonFile(
|
|
4032
|
+
for (const path of paths) {
|
|
4033
|
+
const config = loadJsonFile(path);
|
|
3827
4034
|
if (config)
|
|
3828
4035
|
return config;
|
|
3829
4036
|
}
|
|
@@ -3849,10 +4056,10 @@ function getMergedServers() {
|
|
|
3849
4056
|
}
|
|
3850
4057
|
if (seen.has(id))
|
|
3851
4058
|
continue;
|
|
3852
|
-
const
|
|
3853
|
-
if (!
|
|
4059
|
+
const server = createServerFromEntry(id, entry, source);
|
|
4060
|
+
if (!server)
|
|
3854
4061
|
continue;
|
|
3855
|
-
servers.push(
|
|
4062
|
+
servers.push(server);
|
|
3856
4063
|
seen.add(id);
|
|
3857
4064
|
}
|
|
3858
4065
|
}
|
|
@@ -3884,7 +4091,7 @@ function createServerFromEntry(id, entry, source) {
|
|
|
3884
4091
|
if (source === "project") {
|
|
3885
4092
|
if (!builtin)
|
|
3886
4093
|
return null;
|
|
3887
|
-
const
|
|
4094
|
+
const server = createServer({
|
|
3888
4095
|
id,
|
|
3889
4096
|
command: builtin.command,
|
|
3890
4097
|
extensions: entry.extensions ?? builtin.extensions,
|
|
@@ -3892,35 +4099,35 @@ function createServerFromEntry(id, entry, source) {
|
|
|
3892
4099
|
source
|
|
3893
4100
|
});
|
|
3894
4101
|
if (entry.initialization !== undefined) {
|
|
3895
|
-
|
|
4102
|
+
server.initialization = entry.initialization;
|
|
3896
4103
|
}
|
|
3897
|
-
return
|
|
4104
|
+
return server;
|
|
3898
4105
|
}
|
|
3899
4106
|
if (entry.command && entry.extensions) {
|
|
3900
|
-
const
|
|
4107
|
+
const server = createServer({
|
|
3901
4108
|
id,
|
|
3902
4109
|
command: entry.command,
|
|
3903
4110
|
extensions: entry.extensions,
|
|
3904
4111
|
priority: entry.priority ?? 0,
|
|
3905
4112
|
source
|
|
3906
4113
|
});
|
|
3907
|
-
applyOptionalServerFields(
|
|
3908
|
-
return
|
|
4114
|
+
applyOptionalServerFields(server, entry);
|
|
4115
|
+
return server;
|
|
3909
4116
|
}
|
|
3910
4117
|
if (!builtin)
|
|
3911
4118
|
return null;
|
|
3912
|
-
const
|
|
4119
|
+
const server = createServer({
|
|
3913
4120
|
id,
|
|
3914
4121
|
command: entry.command ?? builtin.command,
|
|
3915
4122
|
extensions: entry.extensions ?? builtin.extensions,
|
|
3916
4123
|
priority: entry.priority ?? 0,
|
|
3917
4124
|
source
|
|
3918
4125
|
});
|
|
3919
|
-
applyOptionalServerFields(
|
|
3920
|
-
return
|
|
4126
|
+
applyOptionalServerFields(server, entry);
|
|
4127
|
+
return server;
|
|
3921
4128
|
}
|
|
3922
4129
|
function createServer(input) {
|
|
3923
|
-
const
|
|
4130
|
+
const server = {
|
|
3924
4131
|
id: input.id,
|
|
3925
4132
|
command: input.command,
|
|
3926
4133
|
extensions: input.extensions,
|
|
@@ -3928,19 +4135,19 @@ function createServer(input) {
|
|
|
3928
4135
|
source: input.source
|
|
3929
4136
|
};
|
|
3930
4137
|
if (input.env !== undefined) {
|
|
3931
|
-
|
|
4138
|
+
server.env = input.env;
|
|
3932
4139
|
}
|
|
3933
4140
|
if (input.initialization !== undefined) {
|
|
3934
|
-
|
|
4141
|
+
server.initialization = input.initialization;
|
|
3935
4142
|
}
|
|
3936
|
-
return
|
|
4143
|
+
return server;
|
|
3937
4144
|
}
|
|
3938
|
-
function applyOptionalServerFields(
|
|
4145
|
+
function applyOptionalServerFields(server, entry) {
|
|
3939
4146
|
if (entry.env !== undefined) {
|
|
3940
|
-
|
|
4147
|
+
server.env = entry.env;
|
|
3941
4148
|
}
|
|
3942
4149
|
if (entry.initialization !== undefined) {
|
|
3943
|
-
|
|
4150
|
+
server.initialization = entry.initialization;
|
|
3944
4151
|
}
|
|
3945
4152
|
}
|
|
3946
4153
|
function isConfigJson(value) {
|
|
@@ -3988,60 +4195,161 @@ function getDisabledServerIds() {
|
|
|
3988
4195
|
}
|
|
3989
4196
|
return disabled;
|
|
3990
4197
|
}
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
|
-
|
|
3994
|
-
|
|
3995
|
-
|
|
3996
|
-
|
|
3997
|
-
|
|
3998
|
-
|
|
3999
|
-
|
|
4198
|
+
var LOCAL_BIN_RULES = [
|
|
4199
|
+
{
|
|
4200
|
+
markers: ["package.json", "bun.lock", "bun.lockb", "package-lock.json", "yarn.lock", "pnpm-lock.yaml"],
|
|
4201
|
+
binDirs: [join4("node_modules", ".bin")]
|
|
4202
|
+
},
|
|
4203
|
+
{
|
|
4204
|
+
markers: [
|
|
4205
|
+
"pyproject.toml",
|
|
4206
|
+
"ty.toml",
|
|
4207
|
+
"requirements.txt",
|
|
4208
|
+
"setup.py",
|
|
4209
|
+
"setup.cfg",
|
|
4210
|
+
"Pipfile",
|
|
4211
|
+
"pyrightconfig.json",
|
|
4212
|
+
"ruff.toml",
|
|
4213
|
+
".ruff.toml"
|
|
4214
|
+
],
|
|
4215
|
+
binDirs: [
|
|
4216
|
+
join4(".venv", "bin"),
|
|
4217
|
+
join4(".venv", "Scripts"),
|
|
4218
|
+
join4("venv", "bin"),
|
|
4219
|
+
join4("venv", "Scripts"),
|
|
4220
|
+
join4(".env", "bin"),
|
|
4221
|
+
join4(".env", "Scripts")
|
|
4222
|
+
]
|
|
4223
|
+
},
|
|
4224
|
+
{
|
|
4225
|
+
markers: ["Gemfile", "Gemfile.lock"],
|
|
4226
|
+
binDirs: [join4("vendor", "bundle", "bin"), "bin"]
|
|
4227
|
+
},
|
|
4228
|
+
{
|
|
4229
|
+
markers: ["go.mod", "go.sum", "go.work"],
|
|
4230
|
+
binDirs: ["bin"]
|
|
4231
|
+
}
|
|
4232
|
+
];
|
|
4233
|
+
var resolutionCache = new Map;
|
|
4234
|
+
var probeCount = 0;
|
|
4235
|
+
function probe(path) {
|
|
4236
|
+
probeCount += 1;
|
|
4237
|
+
return existsSync10(path);
|
|
4238
|
+
}
|
|
4239
|
+
function executableSuffixes(platform, pathExt) {
|
|
4240
|
+
if (platform !== "win32")
|
|
4241
|
+
return [""];
|
|
4242
|
+
const configured = pathExt ?? process.env["PATHEXT"] ?? "";
|
|
4243
|
+
const systemExts = configured.split(";").filter((entry) => entry.length > 0).map((entry) => entry.toLowerCase());
|
|
4244
|
+
return [...new Set(["", ...systemExts, ".exe", ".cmd", ".bat", ".ps1"])];
|
|
4245
|
+
}
|
|
4246
|
+
function probeWithSuffixes(directory, command, suffixes) {
|
|
4247
|
+
for (const suffix of suffixes) {
|
|
4248
|
+
const candidate = join4(directory, command + suffix);
|
|
4249
|
+
if (probe(candidate))
|
|
4250
|
+
return candidate;
|
|
4000
4251
|
}
|
|
4001
|
-
|
|
4002
|
-
|
|
4003
|
-
|
|
4004
|
-
|
|
4005
|
-
|
|
4006
|
-
|
|
4007
|
-
|
|
4008
|
-
|
|
4009
|
-
|
|
4252
|
+
return null;
|
|
4253
|
+
}
|
|
4254
|
+
function resolveLocal(command, workingDirectory, suffixes, stopAt) {
|
|
4255
|
+
const boundary = stopAt === undefined ? undefined : resolve7(stopAt);
|
|
4256
|
+
let current = resolve7(workingDirectory);
|
|
4257
|
+
while (true) {
|
|
4258
|
+
for (const rule of LOCAL_BIN_RULES) {
|
|
4259
|
+
if (!rule.markers.some((marker) => probe(join4(current, marker))))
|
|
4260
|
+
continue;
|
|
4261
|
+
for (const binDir of rule.binDirs) {
|
|
4262
|
+
const found = probeWithSuffixes(join4(current, binDir), command, suffixes);
|
|
4263
|
+
if (found !== null)
|
|
4264
|
+
return found;
|
|
4265
|
+
}
|
|
4010
4266
|
}
|
|
4267
|
+
if (probe(join4(current, ".git")))
|
|
4268
|
+
return null;
|
|
4269
|
+
if (boundary !== undefined && current === boundary)
|
|
4270
|
+
return null;
|
|
4271
|
+
const parent = dirname9(current);
|
|
4272
|
+
if (parent === current)
|
|
4273
|
+
return null;
|
|
4274
|
+
current = parent;
|
|
4011
4275
|
}
|
|
4012
|
-
|
|
4013
|
-
|
|
4276
|
+
}
|
|
4277
|
+
function resolveFromPath(command, suffixes, platform, pathEnvOverride) {
|
|
4278
|
+
let pathEnv = pathEnvOverride ?? process.env["PATH"] ?? "";
|
|
4279
|
+
if (platform === "win32" && !pathEnv) {
|
|
4014
4280
|
pathEnv = process.env["Path"] ?? "";
|
|
4015
4281
|
}
|
|
4016
|
-
const
|
|
4017
|
-
|
|
4018
|
-
|
|
4019
|
-
|
|
4020
|
-
|
|
4021
|
-
|
|
4022
|
-
}
|
|
4282
|
+
for (const entry of pathEnv.split(delimiter3)) {
|
|
4283
|
+
if (entry.length === 0)
|
|
4284
|
+
continue;
|
|
4285
|
+
const found = probeWithSuffixes(entry, command, suffixes);
|
|
4286
|
+
if (found !== null)
|
|
4287
|
+
return found;
|
|
4023
4288
|
}
|
|
4024
|
-
|
|
4025
|
-
|
|
4026
|
-
|
|
4289
|
+
return null;
|
|
4290
|
+
}
|
|
4291
|
+
function resolveServerBinary(command, workingDirectory, options = {}) {
|
|
4292
|
+
if (command.length === 0)
|
|
4293
|
+
return null;
|
|
4294
|
+
const [cmd] = command;
|
|
4295
|
+
if (cmd === undefined || cmd.length === 0)
|
|
4296
|
+
return null;
|
|
4297
|
+
const platform = options.platform ?? process.platform;
|
|
4298
|
+
const suffixes = executableSuffixes(platform, options.pathExt);
|
|
4299
|
+
if (cmd.includes("/") || cmd.includes("\\")) {
|
|
4300
|
+
const explicit = isAbsolute5(cmd) ? cmd : resolve7(workingDirectory ?? process.cwd(), cmd);
|
|
4301
|
+
return probe(explicit) ? explicit : null;
|
|
4302
|
+
}
|
|
4303
|
+
const cacheKey = JSON.stringify([
|
|
4304
|
+
workingDirectory ?? "",
|
|
4305
|
+
cmd,
|
|
4306
|
+
platform,
|
|
4307
|
+
options.stopAt ?? "",
|
|
4308
|
+
options.pathExt ?? "",
|
|
4309
|
+
options.pathEnv ?? process.env["PATH"] ?? ""
|
|
4310
|
+
]);
|
|
4311
|
+
const cached = resolutionCache.get(cacheKey);
|
|
4312
|
+
if (cached !== undefined)
|
|
4313
|
+
return cached;
|
|
4314
|
+
let resolved = null;
|
|
4315
|
+
if (workingDirectory !== undefined && workingDirectory.length > 0) {
|
|
4316
|
+
resolved = resolveLocal(cmd, workingDirectory, suffixes, options.stopAt);
|
|
4317
|
+
}
|
|
4318
|
+
resolved ??= resolveFromPath(cmd, suffixes, platform, options.pathEnv);
|
|
4319
|
+
if (resolved === null && cmd === "node")
|
|
4320
|
+
resolved = cmd;
|
|
4321
|
+
resolutionCache.set(cacheKey, resolved);
|
|
4322
|
+
return resolved;
|
|
4323
|
+
}
|
|
4324
|
+
function isServerInstalled(command, workingDirectory, options = {}) {
|
|
4325
|
+
if (command.length === 0)
|
|
4326
|
+
return false;
|
|
4327
|
+
return resolveServerBinary(command, workingDirectory, options) !== null;
|
|
4328
|
+
}
|
|
4329
|
+
function withResolvedCommand(command, binaryPath) {
|
|
4330
|
+
return [binaryPath, ...command.slice(1)];
|
|
4027
4331
|
}
|
|
4028
4332
|
function findServerForExtension(ext) {
|
|
4029
4333
|
const servers = getMergedServers();
|
|
4030
|
-
|
|
4031
|
-
|
|
4334
|
+
const workingDirectory = contextCwd();
|
|
4335
|
+
for (const server of servers) {
|
|
4336
|
+
if (!server.extensions.includes(ext))
|
|
4337
|
+
continue;
|
|
4338
|
+
const binaryPath = resolveServerBinary(server.command, workingDirectory);
|
|
4339
|
+
if (binaryPath !== null) {
|
|
4032
4340
|
const resolvedServer = {
|
|
4033
|
-
id:
|
|
4034
|
-
command:
|
|
4035
|
-
extensions:
|
|
4036
|
-
priority:
|
|
4341
|
+
id: server.id,
|
|
4342
|
+
command: withResolvedCommand(server.command, binaryPath),
|
|
4343
|
+
extensions: server.extensions,
|
|
4344
|
+
priority: server.priority
|
|
4037
4345
|
};
|
|
4038
|
-
if (
|
|
4346
|
+
if (server.env !== undefined) {
|
|
4039
4347
|
return {
|
|
4040
4348
|
status: "found",
|
|
4041
4349
|
server: {
|
|
4042
4350
|
...resolvedServer,
|
|
4043
|
-
env:
|
|
4044
|
-
...
|
|
4351
|
+
env: server.env,
|
|
4352
|
+
...server.initialization === undefined ? {} : { initialization: server.initialization }
|
|
4045
4353
|
}
|
|
4046
4354
|
};
|
|
4047
4355
|
}
|
|
@@ -4049,20 +4357,20 @@ function findServerForExtension(ext) {
|
|
|
4049
4357
|
status: "found",
|
|
4050
4358
|
server: {
|
|
4051
4359
|
...resolvedServer,
|
|
4052
|
-
...
|
|
4360
|
+
...server.initialization === undefined ? {} : { initialization: server.initialization }
|
|
4053
4361
|
}
|
|
4054
4362
|
};
|
|
4055
4363
|
}
|
|
4056
4364
|
}
|
|
4057
|
-
for (const
|
|
4058
|
-
if (
|
|
4059
|
-
const installHint = LSP_INSTALL_HINTS[
|
|
4365
|
+
for (const server of servers) {
|
|
4366
|
+
if (server.extensions.includes(ext)) {
|
|
4367
|
+
const installHint = LSP_INSTALL_HINTS[server.id] ?? `Install '${server.command[0]}' and ensure it's in your PATH`;
|
|
4060
4368
|
return {
|
|
4061
4369
|
status: "not_installed",
|
|
4062
4370
|
server: {
|
|
4063
|
-
id:
|
|
4064
|
-
command:
|
|
4065
|
-
extensions:
|
|
4371
|
+
id: server.id,
|
|
4372
|
+
command: server.command,
|
|
4373
|
+
extensions: server.extensions
|
|
4066
4374
|
},
|
|
4067
4375
|
installHint
|
|
4068
4376
|
};
|
|
@@ -4078,20 +4386,21 @@ function findServerForExtension(ext) {
|
|
|
4078
4386
|
function getAllServers() {
|
|
4079
4387
|
const servers = getMergedServers();
|
|
4080
4388
|
const disabled = getDisabledServerIds();
|
|
4389
|
+
const workingDirectory = contextCwd();
|
|
4081
4390
|
const result = [];
|
|
4082
4391
|
const seen = new Set;
|
|
4083
|
-
for (const
|
|
4084
|
-
if (seen.has(
|
|
4392
|
+
for (const server of servers) {
|
|
4393
|
+
if (seen.has(server.id))
|
|
4085
4394
|
continue;
|
|
4086
4395
|
result.push({
|
|
4087
|
-
id:
|
|
4088
|
-
installed: isServerInstalled(
|
|
4089
|
-
extensions:
|
|
4396
|
+
id: server.id,
|
|
4397
|
+
installed: isServerInstalled(server.command, workingDirectory),
|
|
4398
|
+
extensions: server.extensions,
|
|
4090
4399
|
disabled: false,
|
|
4091
|
-
source:
|
|
4092
|
-
priority:
|
|
4400
|
+
source: server.source,
|
|
4401
|
+
priority: server.priority
|
|
4093
4402
|
});
|
|
4094
|
-
seen.add(
|
|
4403
|
+
seen.add(server.id);
|
|
4095
4404
|
}
|
|
4096
4405
|
for (const id of disabled) {
|
|
4097
4406
|
if (seen.has(id))
|
|
@@ -4099,7 +4408,7 @@ function getAllServers() {
|
|
|
4099
4408
|
const builtin = BUILTIN_SERVERS[id];
|
|
4100
4409
|
result.push({
|
|
4101
4410
|
id,
|
|
4102
|
-
installed: builtin ? isServerInstalled(builtin.command) : false,
|
|
4411
|
+
installed: builtin ? isServerInstalled(builtin.command, workingDirectory) : false,
|
|
4103
4412
|
extensions: builtin?.extensions ?? [],
|
|
4104
4413
|
disabled: true,
|
|
4105
4414
|
source: "disabled",
|
|
@@ -4108,7 +4417,6 @@ function getAllServers() {
|
|
|
4108
4417
|
}
|
|
4109
4418
|
return result;
|
|
4110
4419
|
}
|
|
4111
|
-
var WORKSPACE_MARKERS = [".git", "package.json", "pyproject.toml", "Cargo.toml", "go.mod", "pom.xml", "build.gradle"];
|
|
4112
4420
|
function isDirectoryPath(filePath) {
|
|
4113
4421
|
try {
|
|
4114
4422
|
return statSync4(filePath).isDirectory();
|
|
@@ -4121,36 +4429,40 @@ function findWorkspaceRoot(filePath) {
|
|
|
4121
4429
|
const abs = resolveReadablePathInsideContext(filePath);
|
|
4122
4430
|
let dir = abs;
|
|
4123
4431
|
if (!isDirectoryPath(dir)) {
|
|
4124
|
-
dir =
|
|
4432
|
+
dir = dirname10(dir);
|
|
4125
4433
|
}
|
|
4434
|
+
if (!isPathInside(cwd, abs))
|
|
4435
|
+
return findWorkspaceRootOutsideContext(dir);
|
|
4126
4436
|
const fallbackRoot = nearestExistingDirectoryInsideContext(dir, cwd) ?? cwd;
|
|
4437
|
+
let nearestPackageRoot;
|
|
4127
4438
|
while (isPathInside(cwd, dir)) {
|
|
4128
4439
|
const canonicalDir = existingDirectoryInsideContext(dir, cwd);
|
|
4129
4440
|
if (canonicalDir !== undefined) {
|
|
4130
|
-
|
|
4131
|
-
|
|
4132
|
-
|
|
4133
|
-
|
|
4441
|
+
if (existsSync11(join5(dir, GIT_WORKSPACE_MARKER))) {
|
|
4442
|
+
return canonicalDir;
|
|
4443
|
+
}
|
|
4444
|
+
if (nearestPackageRoot === undefined && hasProjectWorkspaceMarker(dir)) {
|
|
4445
|
+
nearestPackageRoot = canonicalDir;
|
|
4134
4446
|
}
|
|
4135
4447
|
}
|
|
4136
4448
|
if (dir === cwd)
|
|
4137
4449
|
break;
|
|
4138
|
-
dir =
|
|
4450
|
+
dir = dirname10(dir);
|
|
4139
4451
|
}
|
|
4140
|
-
return fallbackRoot;
|
|
4452
|
+
return nearestPackageRoot ?? fallbackRoot;
|
|
4453
|
+
}
|
|
4454
|
+
function hasProjectWorkspaceMarker(directory) {
|
|
4455
|
+
return PROJECT_WORKSPACE_MARKERS.some((marker) => existsSync11(join5(directory, marker)));
|
|
4141
4456
|
}
|
|
4142
4457
|
function resolveReadablePathInsideContext(filePath) {
|
|
4143
4458
|
const cwd = contextCwd();
|
|
4144
|
-
const abs =
|
|
4459
|
+
const abs = resolve8(cwd, filePath);
|
|
4145
4460
|
if (isPathInside(cwd, abs))
|
|
4146
4461
|
return abs;
|
|
4147
4462
|
const rebased = rebaseThroughCanonicalAncestor(abs, cwd);
|
|
4148
4463
|
if (rebased !== undefined)
|
|
4149
4464
|
return rebased;
|
|
4150
|
-
|
|
4151
|
-
if (isPathInside(cwd, canonical))
|
|
4152
|
-
return canonical;
|
|
4153
|
-
throw new LspInvalidPathError(`LSP file path must be inside request cwd: ${filePath}`);
|
|
4465
|
+
return canonicalizeExistingOrNearestAncestor(abs);
|
|
4154
4466
|
}
|
|
4155
4467
|
function resolvePathInsideContext(filePath) {
|
|
4156
4468
|
const cwd = contextCwd();
|
|
@@ -4161,16 +4473,16 @@ function resolvePathInsideContext(filePath) {
|
|
|
4161
4473
|
}
|
|
4162
4474
|
return canonical;
|
|
4163
4475
|
}
|
|
4164
|
-
function rebaseThroughCanonicalAncestor(
|
|
4165
|
-
let current =
|
|
4476
|
+
function rebaseThroughCanonicalAncestor(path, cwd) {
|
|
4477
|
+
let current = path;
|
|
4166
4478
|
const suffix = [];
|
|
4167
4479
|
while (true) {
|
|
4168
|
-
if (
|
|
4169
|
-
const canonical =
|
|
4480
|
+
if (existsSync11(current)) {
|
|
4481
|
+
const canonical = realpathSync5(current);
|
|
4170
4482
|
if (isPathInside(cwd, canonical))
|
|
4171
|
-
return suffix.length === 0 ? canonical :
|
|
4483
|
+
return suffix.length === 0 ? canonical : join5(canonical, ...suffix);
|
|
4172
4484
|
}
|
|
4173
|
-
const parent =
|
|
4485
|
+
const parent = dirname10(current);
|
|
4174
4486
|
if (parent === current)
|
|
4175
4487
|
return;
|
|
4176
4488
|
suffix.unshift(basename3(current));
|
|
@@ -4178,9 +4490,9 @@ function rebaseThroughCanonicalAncestor(path2, cwd) {
|
|
|
4178
4490
|
}
|
|
4179
4491
|
}
|
|
4180
4492
|
function existingDirectoryInsideContext(directory, cwd) {
|
|
4181
|
-
if (!
|
|
4493
|
+
if (!existsSync11(directory))
|
|
4182
4494
|
return;
|
|
4183
|
-
const canonical =
|
|
4495
|
+
const canonical = realpathSync5(directory);
|
|
4184
4496
|
if (!statSync4(canonical).isDirectory())
|
|
4185
4497
|
return;
|
|
4186
4498
|
return isPathInside(cwd, canonical) ? canonical : undefined;
|
|
@@ -4193,7 +4505,7 @@ function nearestExistingDirectoryInsideContext(directory, cwd) {
|
|
|
4193
4505
|
return canonical;
|
|
4194
4506
|
if (current === cwd)
|
|
4195
4507
|
return;
|
|
4196
|
-
current =
|
|
4508
|
+
current = dirname10(current);
|
|
4197
4509
|
}
|
|
4198
4510
|
return;
|
|
4199
4511
|
}
|
|
@@ -4220,33 +4532,46 @@ function formatServerLookupError(result) {
|
|
|
4220
4532
|
].join(`
|
|
4221
4533
|
`);
|
|
4222
4534
|
}
|
|
4535
|
+
function formatInstallOptions(serverId, installHint) {
|
|
4536
|
+
const localHint = LSP_LOCAL_INSTALL_HINTS[serverId];
|
|
4537
|
+
if (localHint === undefined) {
|
|
4538
|
+
return ["To install, run:", ` ${installHint}`];
|
|
4539
|
+
}
|
|
4540
|
+
return [
|
|
4541
|
+
"To install in THIS repository (preferred — no global install needed):",
|
|
4542
|
+
` ${localHint}`,
|
|
4543
|
+
"",
|
|
4544
|
+
"Or install it globally:",
|
|
4545
|
+
` ${installHint}`
|
|
4546
|
+
];
|
|
4547
|
+
}
|
|
4223
4548
|
function formatNotInstalled(result) {
|
|
4224
|
-
const { server
|
|
4225
|
-
const extensions =
|
|
4226
|
-
const decision = loadInstallDecision(
|
|
4549
|
+
const { server, installHint } = result;
|
|
4550
|
+
const extensions = server.extensions.join(", ");
|
|
4551
|
+
const decision = loadInstallDecision(server.id)?.decision;
|
|
4227
4552
|
const context = lspRequestContext();
|
|
4228
4553
|
if (decision === "declined") {
|
|
4229
|
-
return `LSP server '${
|
|
4554
|
+
return `LSP server '${server.id}' (${extensions}) is NOT INSTALLED; user previously declined installation — proceed without LSP.`;
|
|
4230
4555
|
}
|
|
4231
4556
|
const header = [
|
|
4232
|
-
`LSP server '${
|
|
4557
|
+
`LSP server '${server.id}' for ${extensions} is NOT INSTALLED.`,
|
|
4233
4558
|
"",
|
|
4234
|
-
`Command not found: ${
|
|
4559
|
+
`Command not found: ${server.command[0]}`,
|
|
4235
4560
|
""
|
|
4236
4561
|
];
|
|
4562
|
+
const installOptions = formatInstallOptions(server.id, installHint);
|
|
4237
4563
|
if (decision === "allowed") {
|
|
4238
4564
|
return [
|
|
4239
4565
|
...header,
|
|
4240
4566
|
"The user has pre-authorized LSP installation. Run the install command, then retry this tool:",
|
|
4241
|
-
|
|
4567
|
+
...installOptions.slice(1)
|
|
4242
4568
|
].join(`
|
|
4243
4569
|
`);
|
|
4244
4570
|
}
|
|
4245
4571
|
if (!context.capabilities.installDecisionTool) {
|
|
4246
4572
|
return [
|
|
4247
4573
|
...header,
|
|
4248
|
-
|
|
4249
|
-
` ${installHint}`,
|
|
4574
|
+
...installOptions,
|
|
4250
4575
|
"",
|
|
4251
4576
|
"ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
|
|
4252
4577
|
"Install-decision recording is unavailable in this harness; proceed without LSP if the user declines."
|
|
@@ -4255,13 +4580,12 @@ function formatNotInstalled(result) {
|
|
|
4255
4580
|
}
|
|
4256
4581
|
return [
|
|
4257
4582
|
...header,
|
|
4258
|
-
|
|
4259
|
-
` ${installHint}`,
|
|
4583
|
+
...installOptions,
|
|
4260
4584
|
"",
|
|
4261
4585
|
"ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
|
|
4262
4586
|
"- If the user agrees: run the install command above, then retry this tool.",
|
|
4263
4587
|
"- If the user declines, OR has NOT explicitly asked for LSP installation:",
|
|
4264
|
-
` call lsp_install_decision { server_id: "${
|
|
4588
|
+
` call lsp_install_decision { server_id: "${server.id}", decision: "declined" },`,
|
|
4265
4589
|
` which writes to ${context.installDecisionsPath},`,
|
|
4266
4590
|
" then ignore this message and proceed WITHOUT LSP."
|
|
4267
4591
|
].join(`
|
|
@@ -4285,26 +4609,26 @@ async function withLspClient(filePath, fn, toolName, options = {}) {
|
|
|
4285
4609
|
if (result.status !== "found") {
|
|
4286
4610
|
throw new LspServerLookupError(formatServerLookupError(result), result);
|
|
4287
4611
|
}
|
|
4288
|
-
const
|
|
4612
|
+
const server = result.server;
|
|
4289
4613
|
const root = findWorkspaceRoot(absPath);
|
|
4290
4614
|
const manager = options.manager ?? getLspManager();
|
|
4291
4615
|
const acquireAndCall = async (allowRetry) => {
|
|
4292
|
-
const client = await manager.getClient(root,
|
|
4616
|
+
const client = await manager.getClient(root, server, options.signal);
|
|
4293
4617
|
try {
|
|
4294
4618
|
return await fn(client, root, absPath);
|
|
4295
4619
|
} catch (err) {
|
|
4296
4620
|
if (allowRetry && READ_ONLY_TOOLS.has(toolName) && isLspDeadConnectionError(err)) {
|
|
4297
|
-
manager.invalidateClient(root,
|
|
4621
|
+
manager.invalidateClient(root, server.id, client);
|
|
4298
4622
|
return acquireAndCall(false);
|
|
4299
4623
|
}
|
|
4300
4624
|
if (err instanceof LspRequestTimeoutError) {
|
|
4301
|
-
if (manager.isServerInitializing(root,
|
|
4625
|
+
if (manager.isServerInitializing(root, server.id)) {
|
|
4302
4626
|
throw new LspServerInitializingError(err);
|
|
4303
4627
|
}
|
|
4304
4628
|
}
|
|
4305
4629
|
throw err;
|
|
4306
4630
|
} finally {
|
|
4307
|
-
manager.releaseClient(root,
|
|
4631
|
+
manager.releaseClient(root, server.id);
|
|
4308
4632
|
}
|
|
4309
4633
|
};
|
|
4310
4634
|
return acquireAndCall(true);
|
|
@@ -4320,10 +4644,10 @@ function uriToPath(uri) {
|
|
|
4320
4644
|
}
|
|
4321
4645
|
function formatLocation(loc) {
|
|
4322
4646
|
if ("targetUri" in loc) {
|
|
4323
|
-
const
|
|
4324
|
-
const
|
|
4325
|
-
const
|
|
4326
|
-
return `${
|
|
4647
|
+
const uri = uriToPath(loc.targetUri);
|
|
4648
|
+
const line = loc.targetRange.start.line + 1;
|
|
4649
|
+
const char = loc.targetRange.start.character;
|
|
4650
|
+
return `${uri}:${line}:${char}`;
|
|
4327
4651
|
}
|
|
4328
4652
|
const uri = uriToPath(loc.uri);
|
|
4329
4653
|
const line = loc.range.start.line + 1;
|
|
@@ -4433,7 +4757,7 @@ function collectFilesWithExtension(dir, extension, maxFiles) {
|
|
|
4433
4757
|
for (const entry of entries) {
|
|
4434
4758
|
if (files.length >= maxFiles)
|
|
4435
4759
|
return;
|
|
4436
|
-
const fullPath =
|
|
4760
|
+
const fullPath = join6(currentDir, entry);
|
|
4437
4761
|
let stat;
|
|
4438
4762
|
try {
|
|
4439
4763
|
stat = lstatSync5(fullPath);
|
|
@@ -4458,15 +4782,15 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
|
|
|
4458
4782
|
if (!extension.startsWith(".")) {
|
|
4459
4783
|
throw new LspInvalidPathError(`Extension must start with a dot (e.g., ".ts", not "${extension}"). Use ".${extension}" instead.`);
|
|
4460
4784
|
}
|
|
4461
|
-
const absDir =
|
|
4462
|
-
if (!
|
|
4785
|
+
const absDir = resolve9(options.workspaceRoot ?? contextCwd(), directory);
|
|
4786
|
+
if (!existsSync12(absDir)) {
|
|
4463
4787
|
throw new LspInvalidPathError(`Directory does not exist: ${absDir}`);
|
|
4464
4788
|
}
|
|
4465
4789
|
const serverResult = options.server === undefined ? findServerForExtension(extension) : { status: "found", server: options.server };
|
|
4466
4790
|
if (serverResult.status !== "found") {
|
|
4467
4791
|
throw new LspServerLookupError(formatServerLookupError(serverResult));
|
|
4468
4792
|
}
|
|
4469
|
-
const
|
|
4793
|
+
const server = serverResult.server;
|
|
4470
4794
|
const allFiles = (options.listFiles ?? collectFilesWithExtension)(absDir, extension, maxFiles + 1);
|
|
4471
4795
|
const wasCapped = allFiles.length > maxFiles;
|
|
4472
4796
|
const filesToProcess = allFiles.slice(0, maxFiles);
|
|
@@ -4486,7 +4810,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
|
|
|
4486
4810
|
const fileErrors = [];
|
|
4487
4811
|
const maxConcurrency = Math.max(1, options.maxConcurrency ?? DIRECTORY_DIAGNOSTICS_MAX_CONCURRENCY);
|
|
4488
4812
|
options.signal?.throwIfAborted();
|
|
4489
|
-
const client = await manager.getClient(root,
|
|
4813
|
+
const client = await manager.getClient(root, server, options.signal);
|
|
4490
4814
|
try {
|
|
4491
4815
|
let nextIndex = 0;
|
|
4492
4816
|
const workers = Array.from({ length: Math.min(maxConcurrency, filesToProcess.length) }, async () => {
|
|
@@ -4514,7 +4838,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
|
|
|
4514
4838
|
});
|
|
4515
4839
|
await Promise.all(workers);
|
|
4516
4840
|
} finally {
|
|
4517
|
-
manager.releaseClient(root,
|
|
4841
|
+
manager.releaseClient(root, server.id);
|
|
4518
4842
|
}
|
|
4519
4843
|
const displayDiagnostics = allDiagnostics.slice(0, DEFAULT_MAX_DIAGNOSTICS);
|
|
4520
4844
|
const wasDiagCapped = allDiagnostics.length > DEFAULT_MAX_DIAGNOSTICS;
|
|
@@ -4560,7 +4884,7 @@ function inferExtensionFromDirectory(directory) {
|
|
|
4560
4884
|
for (const entry of entries) {
|
|
4561
4885
|
if (scanned >= MAX_SCAN_ENTRIES)
|
|
4562
4886
|
return;
|
|
4563
|
-
const fullPath =
|
|
4887
|
+
const fullPath = join7(dir, entry);
|
|
4564
4888
|
let stat;
|
|
4565
4889
|
try {
|
|
4566
4890
|
stat = lstatSync6(fullPath);
|
|
@@ -4709,8 +5033,8 @@ function severityFilter(params) {
|
|
|
4709
5033
|
function clientOptions(signal) {
|
|
4710
5034
|
return signal === undefined ? {} : { signal };
|
|
4711
5035
|
}
|
|
4712
|
-
function text(
|
|
4713
|
-
return { content: [{ type: "text", text
|
|
5036
|
+
function text(text, details, isError = false) {
|
|
5037
|
+
return { content: [{ type: "text", text }], details, isError };
|
|
4714
5038
|
}
|
|
4715
5039
|
function asDiagnosticArray(result) {
|
|
4716
5040
|
if (!result)
|
|
@@ -4728,7 +5052,7 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
4728
5052
|
const extension = inferExtensionFromDirectory(absPath);
|
|
4729
5053
|
if (!extension) {
|
|
4730
5054
|
const message = `No supported source files found in directory: ${absPath}`;
|
|
4731
|
-
const
|
|
5055
|
+
const details = {
|
|
4732
5056
|
filePath,
|
|
4733
5057
|
severity,
|
|
4734
5058
|
mode: "directory",
|
|
@@ -4738,24 +5062,24 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
4738
5062
|
error: message,
|
|
4739
5063
|
errorKind: "no_files"
|
|
4740
5064
|
};
|
|
4741
|
-
return text(message,
|
|
5065
|
+
return text(message, details);
|
|
4742
5066
|
}
|
|
4743
|
-
const
|
|
4744
|
-
const
|
|
5067
|
+
const output = await aggregateDiagnosticsForDirectory(absPath, extension, severity, undefined, signal === undefined ? {} : { signal });
|
|
5068
|
+
const details = {
|
|
4745
5069
|
filePath,
|
|
4746
5070
|
severity,
|
|
4747
5071
|
mode: "directory",
|
|
4748
5072
|
diagnostics: [],
|
|
4749
|
-
totalDiagnostics:
|
|
5073
|
+
totalDiagnostics: output.totalDiagnostics,
|
|
4750
5074
|
truncated: false,
|
|
4751
|
-
fileFailures: [...
|
|
5075
|
+
fileFailures: [...output.fileFailures]
|
|
4752
5076
|
};
|
|
4753
|
-
return text(
|
|
5077
|
+
return text(output.output, details);
|
|
4754
5078
|
}
|
|
4755
5079
|
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.diagnostics(resolvedFilePath, signal), "diagnostics", clientOptions(signal));
|
|
4756
5080
|
if (result.transientError) {
|
|
4757
5081
|
const message = result.transientError.message;
|
|
4758
|
-
const
|
|
5082
|
+
const details = {
|
|
4759
5083
|
filePath,
|
|
4760
5084
|
severity,
|
|
4761
5085
|
mode: "file",
|
|
@@ -4765,7 +5089,7 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
4765
5089
|
error: message,
|
|
4766
5090
|
errorKind: result.transientError.kind
|
|
4767
5091
|
};
|
|
4768
|
-
return text(message,
|
|
5092
|
+
return text(message, details, true);
|
|
4769
5093
|
}
|
|
4770
5094
|
const diagnostics = filterDiagnosticsBySeverity(asDiagnosticArray(result), severity);
|
|
4771
5095
|
const total = diagnostics.length;
|
|
@@ -4799,13 +5123,98 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
4799
5123
|
throw error;
|
|
4800
5124
|
}
|
|
4801
5125
|
}
|
|
5126
|
+
var DEFAULT_FORMATTING_OPTIONS = {
|
|
5127
|
+
tabSize: 4,
|
|
5128
|
+
insertSpaces: false,
|
|
5129
|
+
trimTrailingWhitespace: true,
|
|
5130
|
+
insertFinalNewline: true,
|
|
5131
|
+
trimFinalNewlines: true
|
|
5132
|
+
};
|
|
5133
|
+
var UNCHANGED = { status: "unchanged", linesAdded: 0, linesRemoved: 0 };
|
|
5134
|
+
async function formatDocumentWithClient(client, filePath, options = {}) {
|
|
5135
|
+
const edits = await client.formatDocument(filePath, options.formattingOptions ?? DEFAULT_FORMATTING_OPTIONS, options.signal);
|
|
5136
|
+
if (edits === null)
|
|
5137
|
+
return { status: "unavailable", reason: "capability_not_advertised" };
|
|
5138
|
+
if (edits.length === 0)
|
|
5139
|
+
return UNCHANGED;
|
|
5140
|
+
const before = readFileSync6(filePath, "utf-8");
|
|
5141
|
+
const normalized = normalizeTextEdits(before, edits, 0);
|
|
5142
|
+
if (normalized.text === before)
|
|
5143
|
+
return UNCHANGED;
|
|
5144
|
+
writeAtomically(filePath, normalized.text);
|
|
5145
|
+
await client.openFile(filePath);
|
|
5146
|
+
return {
|
|
5147
|
+
status: "formatted",
|
|
5148
|
+
...lineDelta(normalized.edits)
|
|
5149
|
+
};
|
|
5150
|
+
}
|
|
5151
|
+
function lineDelta(edits) {
|
|
5152
|
+
let linesAdded = 0;
|
|
5153
|
+
let linesRemoved = 0;
|
|
5154
|
+
for (const edit of edits) {
|
|
5155
|
+
linesRemoved += edit.range.end.line - edit.range.start.line + 1;
|
|
5156
|
+
linesAdded += edit.newText.split(`
|
|
5157
|
+
`).length;
|
|
5158
|
+
}
|
|
5159
|
+
return { linesAdded, linesRemoved };
|
|
5160
|
+
}
|
|
5161
|
+
function writeAtomically(filePath, content) {
|
|
5162
|
+
const tempPath = `${filePath}.omo-format.tmp`;
|
|
5163
|
+
writeFileSync3(tempPath, content, "utf-8");
|
|
5164
|
+
try {
|
|
5165
|
+
renameSync3(tempPath, filePath);
|
|
5166
|
+
} catch (error) {
|
|
5167
|
+
try {
|
|
5168
|
+
unlinkSync2(tempPath);
|
|
5169
|
+
} catch {}
|
|
5170
|
+
throw error;
|
|
5171
|
+
}
|
|
5172
|
+
}
|
|
5173
|
+
async function executeLspFormat(params, signal) {
|
|
5174
|
+
const filePath = requireString(params, "filePath");
|
|
5175
|
+
try {
|
|
5176
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => formatDocumentWithClient(client, resolvedFilePath, signal === undefined ? {} : { signal }), "format", clientOptions(signal));
|
|
5177
|
+
return text(describeResult(filePath, result), formatDetails(filePath, result));
|
|
5178
|
+
} catch (error) {
|
|
5179
|
+
const missingDependency = missingDependencyResult(error, {
|
|
5180
|
+
filePath,
|
|
5181
|
+
status: "unavailable",
|
|
5182
|
+
reason: "server_unavailable",
|
|
5183
|
+
linesAdded: 0,
|
|
5184
|
+
linesRemoved: 0
|
|
5185
|
+
});
|
|
5186
|
+
if (missingDependency)
|
|
5187
|
+
return missingDependency;
|
|
5188
|
+
throw error;
|
|
5189
|
+
}
|
|
5190
|
+
}
|
|
5191
|
+
function formatDetails(filePath, result) {
|
|
5192
|
+
if (result.status === "unavailable") {
|
|
5193
|
+
return { filePath, status: "unavailable", reason: result.reason, linesAdded: 0, linesRemoved: 0 };
|
|
5194
|
+
}
|
|
5195
|
+
return {
|
|
5196
|
+
filePath,
|
|
5197
|
+
status: result.status,
|
|
5198
|
+
linesAdded: result.linesAdded,
|
|
5199
|
+
linesRemoved: result.linesRemoved
|
|
5200
|
+
};
|
|
5201
|
+
}
|
|
5202
|
+
function describeResult(filePath, result) {
|
|
5203
|
+
if (result.status === "unavailable") {
|
|
5204
|
+
return `Formatting unavailable for ${filePath}: the language server does not advertise documentFormattingProvider.`;
|
|
5205
|
+
}
|
|
5206
|
+
if (result.status === "unchanged") {
|
|
5207
|
+
return `Already formatted: ${filePath}`;
|
|
5208
|
+
}
|
|
5209
|
+
return `Formatted ${filePath} (+${result.linesAdded}/-${result.linesRemoved} lines)`;
|
|
5210
|
+
}
|
|
4802
5211
|
async function executeLspInstallDecision(params) {
|
|
4803
5212
|
const serverId = requireString(params, "server_id");
|
|
4804
5213
|
const decision = params["decision"];
|
|
4805
5214
|
if (!isInstallDecision(decision)) {
|
|
4806
5215
|
return text(`Invalid decision '${String(decision)}'. Expected "declined" or "allowed".`, { serverId, errorKind: "invalid_decision" }, true);
|
|
4807
5216
|
}
|
|
4808
|
-
const serverIds = [...new Set(getMergedServers().map((
|
|
5217
|
+
const serverIds = [...new Set(getMergedServers().map((server) => server.id))];
|
|
4809
5218
|
if (!serverIds.includes(serverId)) {
|
|
4810
5219
|
const preview = serverIds.slice(0, 20).join(", ");
|
|
4811
5220
|
return text(`Unknown LSP server '${serverId}'. Known servers: ${preview}${serverIds.length > 20 ? "..." : ""}`, { serverId, errorKind: "unknown_server" }, true);
|
|
@@ -4937,10 +5346,10 @@ function objectSchema(properties, required = []) {
|
|
|
4937
5346
|
async function executeLspStatus() {
|
|
4938
5347
|
const servers = getAllServers();
|
|
4939
5348
|
const snapshots = getLspManager().getSnapshot();
|
|
4940
|
-
const installed = servers.filter((
|
|
4941
|
-
const configuredLines = servers.map((
|
|
4942
|
-
const state =
|
|
4943
|
-
return `- ${
|
|
5349
|
+
const installed = servers.filter((server) => server.installed && !server.disabled);
|
|
5350
|
+
const configuredLines = servers.map((server) => {
|
|
5351
|
+
const state = server.disabled ? "disabled" : server.installed ? "installed" : "missing";
|
|
5352
|
+
return `- ${server.id}: ${state}; source=${server.source}; extensions=${server.extensions.join(", ")}`;
|
|
4944
5353
|
});
|
|
4945
5354
|
const activeLines = snapshots.map((snapshot) => {
|
|
4946
5355
|
const state = snapshot.alive ? snapshot.isInitializing ? "initializing" : "alive" : "dead";
|
|
@@ -4981,8 +5390,8 @@ async function executeLspSymbols(params, signal) {
|
|
|
4981
5390
|
errorKind: "missing_query"
|
|
4982
5391
|
});
|
|
4983
5392
|
}
|
|
4984
|
-
const
|
|
4985
|
-
return formatSymbolsResult(filePath, scope,
|
|
5393
|
+
const symbols = await withLspClient(filePath, async (client) => client.workspaceSymbols(query, signal), "workspaceSymbols", clientOptions(signal));
|
|
5394
|
+
return formatSymbolsResult(filePath, scope, symbols, limit, query);
|
|
4986
5395
|
}
|
|
4987
5396
|
const symbols = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.documentSymbols(resolvedFilePath, signal), "documentSymbols", clientOptions(signal));
|
|
4988
5397
|
return formatSymbolsResult(filePath, scope, symbols, limit);
|
|
@@ -5118,6 +5527,16 @@ var LSP_MCP_TOOLS = [
|
|
|
5118
5527
|
}, ["filePath", "line", "character", "newName"]),
|
|
5119
5528
|
execute: executeLspRename
|
|
5120
5529
|
},
|
|
5530
|
+
{
|
|
5531
|
+
name: "format",
|
|
5532
|
+
aliases: ["lsp_format"],
|
|
5533
|
+
title: "LSP Format",
|
|
5534
|
+
description: "Format a source file with its language server and write the returned edits to disk.",
|
|
5535
|
+
inputSchema: objectSchema({
|
|
5536
|
+
filePath: { type: "string", description: "Source file path to format." }
|
|
5537
|
+
}, ["filePath"]),
|
|
5538
|
+
execute: executeLspFormat
|
|
5539
|
+
},
|
|
5121
5540
|
{
|
|
5122
5541
|
name: "install_decision",
|
|
5123
5542
|
aliases: ["lsp_install_decision"],
|
|
@@ -5139,6 +5558,7 @@ var LSP_MCP_TOOLS = [
|
|
|
5139
5558
|
];
|
|
5140
5559
|
var CONTEXT_KEY = "_context";
|
|
5141
5560
|
var DEFAULT_REQUEST_TIMEOUT_MS = 30000;
|
|
5561
|
+
var STARTUP_BACKOFF_MS = [0, 100, 300];
|
|
5142
5562
|
var nextProxyRequestId = 1;
|
|
5143
5563
|
async function callToolViaDaemon(name, args, options) {
|
|
5144
5564
|
const context = requireContext(options.context);
|
|
@@ -5146,17 +5566,31 @@ async function callToolViaDaemon(name, args, options) {
|
|
|
5146
5566
|
const ensure = options.ensure ?? ((ensurePaths, signal) => ensureDaemonRunning(ensurePaths, undefined, signal === undefined ? {} : { signal }));
|
|
5147
5567
|
const timeoutMs = options.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
|
|
5148
5568
|
const requestArgs = withContext(args, context);
|
|
5569
|
+
const probe = options.probe ?? ((probePaths, signal) => probeDaemon(probePaths, undefined, signal));
|
|
5570
|
+
const sleep = options.sleep ?? ((ms, signal) => delay(ms, undefined, { signal }));
|
|
5149
5571
|
let lastError;
|
|
5150
5572
|
let authRefreshUsed = false;
|
|
5151
|
-
for (
|
|
5573
|
+
for (const [attempt, backoffMs] of STARTUP_BACKOFF_MS.entries()) {
|
|
5152
5574
|
try {
|
|
5153
|
-
|
|
5575
|
+
if (backoffMs > 0)
|
|
5576
|
+
await sleep(backoffMs, options.signal);
|
|
5577
|
+
if (options.signal?.aborted)
|
|
5578
|
+
throw new DaemonRequestCancelledError(false);
|
|
5579
|
+
if (attempt === 0) {
|
|
5580
|
+
await ensureDaemonAvailable(paths, ensure, options.signal);
|
|
5581
|
+
} else if (!await probe(paths, options.signal)) {
|
|
5582
|
+
throw new DaemonUnreachableError(paths.socket);
|
|
5583
|
+
}
|
|
5154
5584
|
const token = readAuthToken(paths);
|
|
5155
5585
|
if (!token)
|
|
5156
5586
|
throw new DaemonRequestError("daemon auth token missing", false);
|
|
5157
5587
|
const sendOptions = options.signal === undefined ? { timeoutMs } : { timeoutMs, signal: options.signal };
|
|
5158
5588
|
return await sendToolCall(paths, token, name, requestArgs, sendOptions);
|
|
5159
5589
|
} catch (error) {
|
|
5590
|
+
if (options.signal?.aborted) {
|
|
5591
|
+
lastError = new DaemonRequestCancelledError(false);
|
|
5592
|
+
break;
|
|
5593
|
+
}
|
|
5160
5594
|
lastError = error;
|
|
5161
5595
|
if (error instanceof DaemonAuthenticationRejectedError && !authRefreshUsed) {
|
|
5162
5596
|
authRefreshUsed = true;
|
|
@@ -5184,7 +5618,7 @@ function withContext(args, context) {
|
|
|
5184
5618
|
function ensureDaemonAvailable(paths, ensure, signal) {
|
|
5185
5619
|
if (!signal)
|
|
5186
5620
|
return ensure(paths);
|
|
5187
|
-
return new Promise((
|
|
5621
|
+
return new Promise((resolve, reject) => {
|
|
5188
5622
|
let settled = false;
|
|
5189
5623
|
const finish = (run) => {
|
|
5190
5624
|
if (settled)
|
|
@@ -5199,11 +5633,11 @@ function ensureDaemonAvailable(paths, ensure, signal) {
|
|
|
5199
5633
|
return;
|
|
5200
5634
|
}
|
|
5201
5635
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
5202
|
-
Promise.resolve().then(() => ensure(paths, signal)).then(() => finish(() =>
|
|
5636
|
+
Promise.resolve().then(() => ensure(paths, signal)).then(() => finish(() => resolve()), (error) => finish(() => reject(signal.aborted ? new DaemonRequestCancelledError(false) : error)));
|
|
5203
5637
|
});
|
|
5204
5638
|
}
|
|
5205
5639
|
function sendToolCall(paths, token, name, args, options) {
|
|
5206
|
-
return new Promise((
|
|
5640
|
+
return new Promise((resolve, reject) => {
|
|
5207
5641
|
const socket = connect(paths.socket);
|
|
5208
5642
|
const requestId = allocateProxyRequestId();
|
|
5209
5643
|
let settled = false;
|
|
@@ -5256,7 +5690,7 @@ function sendToolCall(paths, token, name, args, options) {
|
|
|
5256
5690
|
}
|
|
5257
5691
|
const result = toToolResult(message, requestId);
|
|
5258
5692
|
if (result)
|
|
5259
|
-
finish(() =>
|
|
5693
|
+
finish(() => resolve(result));
|
|
5260
5694
|
else
|
|
5261
5695
|
finish(() => reject(new DaemonRequestError("invalid daemon response", requestWritten)));
|
|
5262
5696
|
});
|
|
@@ -5305,10 +5739,9 @@ var OMO_LSP_DAEMON_VERSION2 = "OMO_LSP_DAEMON_VERSION";
|
|
|
5305
5739
|
var DAEMON_VERSION_PATTERN2 = /^[A-Za-z0-9][A-Za-z0-9._+-]{0,127}$/;
|
|
5306
5740
|
|
|
5307
5741
|
class InvalidRuntimeOverrideError2 extends Error {
|
|
5308
|
-
code = "invalid_runtime_override";
|
|
5309
|
-
reason;
|
|
5310
5742
|
constructor(reason, message) {
|
|
5311
5743
|
super(message);
|
|
5744
|
+
this.code = "invalid_runtime_override";
|
|
5312
5745
|
this.name = "InvalidRuntimeOverrideError";
|
|
5313
5746
|
this.reason = reason;
|
|
5314
5747
|
}
|
|
@@ -5328,12 +5761,12 @@ function resolveDaemonRuntime2(env, defaults) {
|
|
|
5328
5761
|
throw new InvalidRuntimeOverrideError2("paired_values_required", `${OMO_LSP_DAEMON_CLI2} and ${OMO_LSP_DAEMON_VERSION2} must be set together`);
|
|
5329
5762
|
}
|
|
5330
5763
|
if (!hasCliOverride || !hasVersionOverride) {
|
|
5331
|
-
if (!
|
|
5764
|
+
if (!isAbsolute6(defaults.cliPath)) {
|
|
5332
5765
|
throw new InvalidRuntimeOverrideError2("packaged_cli_must_be_absolute", "Packaged LSP daemon CLI path must be absolute");
|
|
5333
5766
|
}
|
|
5334
5767
|
return { cliPath: defaults.cliPath, version: validateDaemonVersion2(defaults.version) };
|
|
5335
5768
|
}
|
|
5336
|
-
if (!
|
|
5769
|
+
if (!isAbsolute6(cliOverride)) {
|
|
5337
5770
|
throw new InvalidRuntimeOverrideError2("cli_must_be_absolute", `${OMO_LSP_DAEMON_CLI2} must be an absolute path to an existing regular file`);
|
|
5338
5771
|
}
|
|
5339
5772
|
const stat = statSync5(cliOverride, { throwIfNoEntry: false });
|
|
@@ -5432,8 +5865,8 @@ function normalizeDiagnosticsOutcome(outcome) {
|
|
|
5432
5865
|
return normalizeDiagnosticsText(outcome);
|
|
5433
5866
|
return outcome;
|
|
5434
5867
|
}
|
|
5435
|
-
function normalizeDiagnosticsText(
|
|
5436
|
-
return
|
|
5868
|
+
function normalizeDiagnosticsText(text) {
|
|
5869
|
+
return text.trim();
|
|
5437
5870
|
}
|
|
5438
5871
|
function formatDiagnosticsError(error) {
|
|
5439
5872
|
const message = normalizeDiagnosticsText(error.message);
|
|
@@ -5454,15 +5887,14 @@ function extensionKey(filePath) {
|
|
|
5454
5887
|
}
|
|
5455
5888
|
// ../../../../lsp-core/src/request-context.ts
|
|
5456
5889
|
import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
|
|
5457
|
-
import { existsSync as
|
|
5458
|
-
import { basename as basename4, delimiter as delimiter4, dirname as dirname2, isAbsolute as
|
|
5890
|
+
import { existsSync as existsSync13, realpathSync as realpathSync6, statSync as statSync6 } from "node:fs";
|
|
5891
|
+
import { basename as basename4, delimiter as delimiter4, dirname as dirname2, isAbsolute as isAbsolute7, join as join8, relative as relative5, resolve as resolve10 } from "node:path";
|
|
5459
5892
|
|
|
5460
5893
|
class LspRequestContextParseError2 extends Error {
|
|
5461
|
-
code;
|
|
5462
|
-
name = "LspRequestContextParseError";
|
|
5463
5894
|
constructor(code, message) {
|
|
5464
5895
|
super(message);
|
|
5465
5896
|
this.code = code;
|
|
5897
|
+
this.name = "LspRequestContextParseError";
|
|
5466
5898
|
}
|
|
5467
5899
|
}
|
|
5468
5900
|
var storage2 = new AsyncLocalStorage2;
|
|
@@ -5479,37 +5911,37 @@ function parseLspRequestContext2(value) {
|
|
|
5479
5911
|
const installDecisionsPath = stringField2(value, "installDecisionsPath");
|
|
5480
5912
|
const capabilities = capabilitiesField2(value["capabilities"]);
|
|
5481
5913
|
const canonical = canonicalCwd2(cwd);
|
|
5482
|
-
for (const
|
|
5483
|
-
requireAbsolutePath2(
|
|
5484
|
-
const projectPath = canonicalizeExistingOrNearestAncestor2(
|
|
5914
|
+
for (const path of projectConfigPaths) {
|
|
5915
|
+
requireAbsolutePath2(path, "projectConfigPaths");
|
|
5916
|
+
const projectPath = canonicalizeExistingOrNearestAncestor2(path);
|
|
5485
5917
|
if (!isPathInside2(canonical, projectPath)) {
|
|
5486
|
-
throw new LspRequestContextParseError2("project_config_outside_cwd", `Project LSP config path must be inside cwd: ${
|
|
5918
|
+
throw new LspRequestContextParseError2("project_config_outside_cwd", `Project LSP config path must be inside cwd: ${path}`);
|
|
5487
5919
|
}
|
|
5488
5920
|
}
|
|
5489
5921
|
requireAbsolutePath2(userConfigPath, "userConfigPath");
|
|
5490
5922
|
requireAbsolutePath2(installDecisionsPath, "installDecisionsPath");
|
|
5491
5923
|
return {
|
|
5492
5924
|
cwd: canonical,
|
|
5493
|
-
projectConfigPaths: projectConfigPaths.map((
|
|
5925
|
+
projectConfigPaths: projectConfigPaths.map((path) => canonicalizeExistingOrNearestAncestor2(path)),
|
|
5494
5926
|
userConfigPath,
|
|
5495
5927
|
installDecisionsPath,
|
|
5496
5928
|
capabilities
|
|
5497
5929
|
};
|
|
5498
5930
|
}
|
|
5499
5931
|
function canonicalCwd2(cwd) {
|
|
5500
|
-
const resolved =
|
|
5501
|
-
if (!
|
|
5932
|
+
const resolved = resolve10(cwd);
|
|
5933
|
+
if (!existsSync13(resolved) || !statSync6(resolved).isDirectory()) {
|
|
5502
5934
|
throw new LspRequestContextParseError2("invalid_cwd", `LSP request cwd must be an existing directory: ${cwd}`);
|
|
5503
5935
|
}
|
|
5504
|
-
return
|
|
5936
|
+
return realpathSync6(resolved);
|
|
5505
5937
|
}
|
|
5506
|
-
function canonicalizeExistingOrNearestAncestor2(
|
|
5507
|
-
let current =
|
|
5938
|
+
function canonicalizeExistingOrNearestAncestor2(path) {
|
|
5939
|
+
let current = resolve10(path);
|
|
5508
5940
|
const suffix = [];
|
|
5509
5941
|
while (true) {
|
|
5510
5942
|
try {
|
|
5511
|
-
const existing =
|
|
5512
|
-
return suffix.length === 0 ? existing :
|
|
5943
|
+
const existing = realpathSync6(current);
|
|
5944
|
+
return suffix.length === 0 ? existing : join8(existing, ...suffix);
|
|
5513
5945
|
} catch (error) {
|
|
5514
5946
|
if (!isMissingPathError2(error))
|
|
5515
5947
|
throw error;
|
|
@@ -5546,15 +5978,15 @@ function stringArrayField2(value, field) {
|
|
|
5546
5978
|
}
|
|
5547
5979
|
return fieldValue;
|
|
5548
5980
|
}
|
|
5549
|
-
function requireAbsolutePath2(
|
|
5550
|
-
if (!
|
|
5551
|
-
throw new LspRequestContextParseError2("relative_path", `LSP request context.${field} must be absolute: ${
|
|
5981
|
+
function requireAbsolutePath2(path, field) {
|
|
5982
|
+
if (!isAbsolute7(path)) {
|
|
5983
|
+
throw new LspRequestContextParseError2("relative_path", `LSP request context.${field} must be absolute: ${path}`);
|
|
5552
5984
|
}
|
|
5553
5985
|
}
|
|
5554
5986
|
function isPathInside2(parent, child) {
|
|
5555
|
-
const childPath =
|
|
5987
|
+
const childPath = resolve10(child);
|
|
5556
5988
|
const relativePath = relative5(parent, childPath);
|
|
5557
|
-
return relativePath === "" || !relativePath.startsWith("..") && !
|
|
5989
|
+
return relativePath === "" || !relativePath.startsWith("..") && !isAbsolute7(relativePath);
|
|
5558
5990
|
}
|
|
5559
5991
|
function isMissingPathError2(error) {
|
|
5560
5992
|
const code = errorCode2(error);
|
|
@@ -5577,9 +6009,9 @@ function errorCode2(error) {
|
|
|
5577
6009
|
}
|
|
5578
6010
|
|
|
5579
6011
|
// src/daemon-cli-path.ts
|
|
5580
|
-
import { existsSync as existsSync14, readFileSync as
|
|
6012
|
+
import { existsSync as existsSync14, readFileSync as readFileSync7 } from "node:fs";
|
|
5581
6013
|
import { createRequire as createRequire2 } from "node:module";
|
|
5582
|
-
import { dirname as
|
|
6014
|
+
import { dirname as dirname11, join as join9 } from "node:path";
|
|
5583
6015
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
5584
6016
|
var requireFromHere2 = createRequire2(import.meta.url);
|
|
5585
6017
|
var PACKAGE_LSP_DAEMON_CLI = "@code-yeongyu/lsp-daemon/cli";
|
|
@@ -5626,8 +6058,8 @@ function resolveConfiguredLspDaemonCli(cliPath) {
|
|
|
5626
6058
|
}
|
|
5627
6059
|
function readDaemonPackageVersion(cliPath) {
|
|
5628
6060
|
try {
|
|
5629
|
-
const parsed = JSON.parse(
|
|
5630
|
-
if (
|
|
6061
|
+
const parsed = JSON.parse(readFileSync7(join9(dirname11(cliPath), "package.json"), "utf8"));
|
|
6062
|
+
if (isRecord8(parsed) && typeof parsed["version"] === "string" && parsed["version"].length > 0) {
|
|
5631
6063
|
return parsed["version"];
|
|
5632
6064
|
}
|
|
5633
6065
|
} catch (error) {
|
|
@@ -5636,14 +6068,14 @@ function readDaemonPackageVersion(cliPath) {
|
|
|
5636
6068
|
}
|
|
5637
6069
|
return null;
|
|
5638
6070
|
}
|
|
5639
|
-
function
|
|
6071
|
+
function isRecord8(value) {
|
|
5640
6072
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5641
6073
|
}
|
|
5642
6074
|
|
|
5643
6075
|
// src/lsp-session-state.ts
|
|
5644
|
-
import { mkdirSync as mkdirSync4, readFileSync as readFileSync8, writeFileSync as
|
|
6076
|
+
import { mkdirSync as mkdirSync4, readFileSync as readFileSync8, writeFileSync as writeFileSync4 } from "node:fs";
|
|
5645
6077
|
import { homedir } from "node:os";
|
|
5646
|
-
import { dirname as
|
|
6078
|
+
import { dirname as dirname12, join as join10 } from "node:path";
|
|
5647
6079
|
function sessionIdFrom(input) {
|
|
5648
6080
|
return typeof input.session_id === "string" && input.session_id.length > 0 ? input.session_id : undefined;
|
|
5649
6081
|
}
|
|
@@ -5672,21 +6104,21 @@ function sessionStatePath(sessionId) {
|
|
|
5672
6104
|
const root = process.env["PLUGIN_DATA"] ?? join10(homedir(), ".codex", "codex-lsp");
|
|
5673
6105
|
return join10(root, "sessions", `${safePathSegment(sessionId)}.json`);
|
|
5674
6106
|
}
|
|
5675
|
-
function readSessionState(
|
|
6107
|
+
function readSessionState(path) {
|
|
5676
6108
|
try {
|
|
5677
|
-
const parsed = JSON.parse(readFileSync8(
|
|
5678
|
-
if (
|
|
6109
|
+
const parsed = JSON.parse(readFileSync8(path, "utf8"));
|
|
6110
|
+
if (isRecord9(parsed) && isLspSessionState(parsed))
|
|
5679
6111
|
return normalizeSessionState(parsed);
|
|
5680
6112
|
return emptyState();
|
|
5681
6113
|
} catch (error) {
|
|
5682
|
-
if (error instanceof SyntaxError ||
|
|
6114
|
+
if (error instanceof SyntaxError || isRecord9(error) && error["code"] === "ENOENT")
|
|
5683
6115
|
return emptyState();
|
|
5684
6116
|
throw error;
|
|
5685
6117
|
}
|
|
5686
6118
|
}
|
|
5687
|
-
function writeSessionState(
|
|
5688
|
-
mkdirSync4(
|
|
5689
|
-
|
|
6119
|
+
function writeSessionState(path, state) {
|
|
6120
|
+
mkdirSync4(dirname12(path), { recursive: true });
|
|
6121
|
+
writeFileSync4(path, `${JSON.stringify(state)}
|
|
5690
6122
|
`);
|
|
5691
6123
|
}
|
|
5692
6124
|
function emptyState() {
|
|
@@ -5705,7 +6137,7 @@ function normalizeSessionState(value) {
|
|
|
5705
6137
|
notConfiguredExtensions: Array.isArray(notConfiguredExtensions) ? notConfiguredExtensions.filter((item) => typeof item === "string").sort() : []
|
|
5706
6138
|
};
|
|
5707
6139
|
}
|
|
5708
|
-
function
|
|
6140
|
+
function isRecord9(value) {
|
|
5709
6141
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5710
6142
|
}
|
|
5711
6143
|
|
|
@@ -5716,7 +6148,7 @@ function extractMutatedFilePaths(input) {
|
|
|
5716
6148
|
return [];
|
|
5717
6149
|
if (isFailedToolResponse(input.tool_response))
|
|
5718
6150
|
return [];
|
|
5719
|
-
const toolInput =
|
|
6151
|
+
const toolInput = isRecord10(input.tool_input) ? input.tool_input : {};
|
|
5720
6152
|
const paths = new Set;
|
|
5721
6153
|
addStringValue(paths, toolInput["path"]);
|
|
5722
6154
|
addStringValue(paths, toolInput["filePath"]);
|
|
@@ -5735,7 +6167,7 @@ function isMutationTool(value) {
|
|
|
5735
6167
|
return MUTATION_TOOL_NAMES.has(value.toLowerCase());
|
|
5736
6168
|
}
|
|
5737
6169
|
function isFailedToolResponse(value) {
|
|
5738
|
-
if (!
|
|
6170
|
+
if (!isRecord10(value))
|
|
5739
6171
|
return false;
|
|
5740
6172
|
return value["isError"] === true || value["is_error"] === true || value["error"] === true || value["status"] === "error";
|
|
5741
6173
|
}
|
|
@@ -5761,9 +6193,9 @@ function addPatchInput(paths, value) {
|
|
|
5761
6193
|
return;
|
|
5762
6194
|
for (const line of value.split(`
|
|
5763
6195
|
`)) {
|
|
5764
|
-
const
|
|
5765
|
-
if (
|
|
5766
|
-
paths.add(
|
|
6196
|
+
const path = extractPatchHeaderPath(line);
|
|
6197
|
+
if (path !== undefined)
|
|
6198
|
+
paths.add(path);
|
|
5767
6199
|
}
|
|
5768
6200
|
}
|
|
5769
6201
|
function extractPatchHeaderPath(line) {
|
|
@@ -5778,7 +6210,7 @@ function addPatchFiles(paths, value) {
|
|
|
5778
6210
|
if (!Array.isArray(value))
|
|
5779
6211
|
return;
|
|
5780
6212
|
for (const item of value) {
|
|
5781
|
-
if (!
|
|
6213
|
+
if (!isRecord10(item))
|
|
5782
6214
|
continue;
|
|
5783
6215
|
addStringValue(paths, item["path"]);
|
|
5784
6216
|
addStringValue(paths, item["filePath"]);
|
|
@@ -5787,7 +6219,7 @@ function addPatchFiles(paths, value) {
|
|
|
5787
6219
|
addStringValue(paths, item["move_path"]);
|
|
5788
6220
|
}
|
|
5789
6221
|
}
|
|
5790
|
-
function
|
|
6222
|
+
function isRecord10(value) {
|
|
5791
6223
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5792
6224
|
}
|
|
5793
6225
|
|
|
@@ -5818,10 +6250,10 @@ function postEditOutcomeFromDaemonResult(result) {
|
|
|
5818
6250
|
`);
|
|
5819
6251
|
}
|
|
5820
6252
|
function notConfiguredAvailability(details) {
|
|
5821
|
-
if (!
|
|
6253
|
+
if (!isRecord11(details))
|
|
5822
6254
|
return;
|
|
5823
6255
|
const availability = details["availability"];
|
|
5824
|
-
if (!
|
|
6256
|
+
if (!isRecord11(availability))
|
|
5825
6257
|
return;
|
|
5826
6258
|
if (availability["kind"] !== "not_configured")
|
|
5827
6259
|
return;
|
|
@@ -5829,11 +6261,11 @@ function notConfiguredAvailability(details) {
|
|
|
5829
6261
|
return typeof extension === "string" && extension.length > 0 ? { extension } : undefined;
|
|
5830
6262
|
}
|
|
5831
6263
|
function codexLspRequestContext(env = process.env, cwd = process.cwd()) {
|
|
5832
|
-
const
|
|
6264
|
+
const canonicalCwd = realpathSync7(resolve11(cwd));
|
|
5833
6265
|
const codexHome = resolve11(env["CODEX_HOME"]?.trim() || join11(homedir3(), ".codex"));
|
|
5834
6266
|
return parseLspRequestContext2({
|
|
5835
|
-
cwd:
|
|
5836
|
-
projectConfigPaths: [join11(
|
|
6267
|
+
cwd: canonicalCwd,
|
|
6268
|
+
projectConfigPaths: [join11(canonicalCwd, ".codex", "lsp-client.json")],
|
|
5837
6269
|
userConfigPath: join11(codexHome, "lsp-client.json"),
|
|
5838
6270
|
installDecisionsPath: join11(codexHome, "lsp-install-decisions.json"),
|
|
5839
6271
|
capabilities: { installDecisionTool: true }
|
|
@@ -5936,22 +6368,22 @@ function isContextPressureTranscript(transcriptPath) {
|
|
|
5936
6368
|
throw error;
|
|
5937
6369
|
}
|
|
5938
6370
|
}
|
|
5939
|
-
function hasContextPressureMarker(
|
|
5940
|
-
const normalizedText =
|
|
6371
|
+
function hasContextPressureMarker(text) {
|
|
6372
|
+
const normalizedText = text.toLowerCase();
|
|
5941
6373
|
return CONTEXT_PRESSURE_MARKERS.some((marker) => normalizedText.includes(marker));
|
|
5942
6374
|
}
|
|
5943
|
-
function limitHookText(
|
|
5944
|
-
if (
|
|
5945
|
-
return
|
|
6375
|
+
function limitHookText(text, maxChars) {
|
|
6376
|
+
if (text.length <= maxChars)
|
|
6377
|
+
return text;
|
|
5946
6378
|
const marker = `
|
|
5947
6379
|
|
|
5948
6380
|
[Truncated hook output to ${maxChars} chars to avoid Codex context overflow.]`;
|
|
5949
6381
|
if (marker.length >= maxChars)
|
|
5950
6382
|
return marker.slice(0, maxChars);
|
|
5951
|
-
const head =
|
|
6383
|
+
const head = text.slice(0, maxChars - marker.length).replace(/[ \t\r\n]+$/, "");
|
|
5952
6384
|
return `${head}${marker}`;
|
|
5953
6385
|
}
|
|
5954
|
-
function
|
|
6386
|
+
function isRecord11(value) {
|
|
5955
6387
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5956
6388
|
}
|
|
5957
6389
|
|
|
@@ -5968,7 +6400,7 @@ async function runHookCli(runHook, stdin) {
|
|
|
5968
6400
|
if (!raw.trim())
|
|
5969
6401
|
return;
|
|
5970
6402
|
const parsed = JSON.parse(raw);
|
|
5971
|
-
const input =
|
|
6403
|
+
const input = isRecord11(parsed) ? parsed : {};
|
|
5972
6404
|
const output = await runHook(input);
|
|
5973
6405
|
if (output)
|
|
5974
6406
|
process.stdout.write(output);
|
|
@@ -6011,15 +6443,15 @@ main().catch((error) => {
|
|
|
6011
6443
|
});
|
|
6012
6444
|
async function runPackageLspMcpCli() {
|
|
6013
6445
|
const cliPath = resolveLspDaemonCliPath();
|
|
6014
|
-
const child = spawn3(execPath2, [cliPath, "mcp"], { stdio: "inherit" });
|
|
6015
|
-
await new Promise((
|
|
6446
|
+
const child = spawn3(execPath2, [cliPath, "mcp"], { stdio: "inherit", windowsHide: true });
|
|
6447
|
+
await new Promise((resolve, reject) => {
|
|
6016
6448
|
child.once("error", reject);
|
|
6017
6449
|
child.once("exit", (code, signal) => {
|
|
6018
6450
|
if (code !== null && code !== 0)
|
|
6019
6451
|
process.exitCode = code;
|
|
6020
6452
|
if (code === null && signal !== null)
|
|
6021
6453
|
process.exitCode = 1;
|
|
6022
|
-
|
|
6454
|
+
resolve();
|
|
6023
6455
|
});
|
|
6024
6456
|
});
|
|
6025
6457
|
}
|