oh-my-opencode 5.0.0-beta.3 → 5.0.0-beta.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/command/publish.md +44 -16
- package/.agents/skills/publish/SKILL.md +44 -16
- package/.agents/skills/senpi-qa/SKILL.md +80 -0
- package/.agents/skills/senpi-qa/scripts/resolve-evidence-dir.mjs +65 -0
- package/.agents/skills/senpi-qa/scripts/resolve-evidence-dir.test.mjs +171 -0
- package/.agents/skills/work-with-pr/SKILL.md +37 -23
- package/.opencode/command/publish.md +44 -16
- package/.opencode/skills/work-with-pr/SKILL.md +37 -23
- package/README.ja.md +25 -21
- package/README.ko.md +25 -21
- package/README.md +38 -23
- package/README.ru.md +24 -20
- package/README.zh-cn.md +25 -21
- package/dist/agents/atlas/agent.d.ts +0 -1
- package/dist/agents/sisyphus/grok-4.d.ts +20 -0
- package/dist/agents/sisyphus/index.d.ts +2 -0
- package/dist/agents/sisyphus-agent-config.d.ts +6 -0
- package/dist/agents/sisyphus-agent-factory.d.ts +1 -1
- package/dist/agents/sisyphus-runtime-prompt-reconciler.d.ts +15 -4
- package/dist/agents/types.d.ts +2 -2
- package/dist/cli/config-manager/parse-opencode-config-file.d.ts +2 -1
- package/dist/cli/doctor/checks/system-plugin.d.ts +4 -3
- package/dist/cli/fallback-lane-policy.d.ts +1 -0
- package/dist/cli/index.js +22601 -20302
- 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 +22219 -19897
- package/dist/config/schema/background-task.d.ts +1 -0
- package/dist/config/schema/commands.d.ts +1 -1
- package/dist/config/schema/hooks.d.ts +1 -1
- package/dist/config/schema/oh-my-opencode-config.d.ts +5 -1
- package/dist/config/schema/ulw-execute.d.ts +5 -0
- package/dist/config/validate.d.ts +2 -0
- package/dist/create-hooks.d.ts +3 -1
- package/dist/features/background-agent/constants.d.ts +0 -7
- package/dist/features/background-agent/manager.d.ts +2 -1
- package/dist/features/background-agent/parent-wake-dispatched-tracker.d.ts +0 -1
- package/dist/features/background-agent/subagent-spawn-limits.d.ts +8 -0
- package/dist/features/btw-side/btw-command-draft.d.ts +7 -0
- package/dist/features/btw-side/context-injector.d.ts +15 -0
- package/dist/features/btw-side/index.d.ts +8 -0
- package/dist/features/btw-side/metadata.d.ts +15 -0
- package/dist/features/btw-side/parent-context-budget.d.ts +9 -0
- package/dist/features/btw-side/server-session-registry.d.ts +8 -0
- package/dist/features/btw-side/tui-adoption-cache.d.ts +13 -0
- package/dist/features/btw-side/tui-adoption-guard.d.ts +5 -0
- package/dist/features/btw-side/tui-controller-types.d.ts +68 -0
- package/dist/features/btw-side/tui-controller.d.ts +19 -0
- package/dist/features/btw-side/tui-escape-return.d.ts +12 -0
- package/dist/features/btw-side/tui-keymap.d.ts +17 -0
- package/dist/features/btw-side/tui-parent-validator.d.ts +6 -0
- package/dist/features/btw-side/tui-picker-options.d.ts +20 -0
- package/dist/features/btw-side/tui-picker.d.ts +9 -0
- package/dist/features/btw-side/tui-prompt-queue.d.ts +8 -0
- package/dist/features/btw-side/tui-session-bridge.d.ts +11 -0
- package/dist/features/btw-side/tui-session-catalog.d.ts +35 -0
- package/dist/features/btw-side/tui-side-removal.d.ts +11 -0
- package/dist/features/btw-side/tui-side-start.d.ts +9 -0
- package/dist/features/btw-side/tui-wiring.d.ts +8 -0
- package/dist/features/builtin-commands/templates/ulw-execute.d.ts +1 -0
- package/dist/features/builtin-commands/types.d.ts +1 -1
- package/dist/features/opengateway-provider/index.d.ts +13 -0
- package/dist/features/task-toast-manager/manager.d.ts +0 -24
- package/dist/features/team-mode/tools/messaging-fallback-wake.d.ts +15 -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/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/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 -1
- package/dist/hooks/keyword-detector/hook.d.ts +7 -0
- package/dist/hooks/keyword-detector/ultrawork/source-detector.d.ts +0 -1
- package/dist/hooks/model-fallback/hook.d.ts +1 -1
- package/dist/hooks/prometheus-md-only/agent-resolution.d.ts +2 -2
- package/dist/hooks/runtime-fallback/chat-message-handler.d.ts +2 -0
- package/dist/hooks/runtime-fallback/retry-model-payload.d.ts +1 -0
- package/dist/hooks/runtime-fallback/runtime-model-settings.d.ts +6 -0
- package/dist/hooks/runtime-fallback/session-status-handler.d.ts +1 -1
- package/dist/hooks/runtime-fallback/types.d.ts +3 -1
- package/dist/hooks/sisyphus-junior-notepad/constants.d.ts +1 -1
- package/dist/hooks/todo-continuation-enforcer/types.d.ts +1 -0
- package/dist/hooks/{start-work → ulw-execute}/context-info-builder.d.ts +1 -1
- package/dist/hooks/{start-work → ulw-execute}/index.d.ts +1 -1
- package/dist/hooks/ulw-execute/ulw-execute-hook.d.ts +23 -0
- package/dist/index.js +12989 -7152
- package/dist/oh-my-opencode.schema.json +20 -2
- package/dist/plugin/chat-message/types.d.ts +3 -3
- package/dist/plugin/chat-message/ulw-execute-message.d.ts +5 -0
- package/dist/plugin/event-session-lifecycle.d.ts +1 -0
- package/dist/plugin/hooks/create-core-hooks.d.ts +2 -1
- package/dist/plugin/hooks/create-session-hooks.d.ts +2 -2
- package/dist/plugin/hooks/create-transform-hooks.d.ts +2 -0
- package/dist/plugin/messages-transform.d.ts +1 -0
- package/dist/plugin-dispose.d.ts +3 -0
- package/dist/shared/agent-tool-restrictions.d.ts +0 -1
- package/dist/shared/index.d.ts +2 -0
- package/dist/shared/legacy-plugin-warning.d.ts +2 -1
- package/dist/shared/normalize-sdk-response.d.ts +1 -0
- package/dist/shared/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/coding-agent-sessions/AGENTS.md +62 -0
- package/dist/skills/coding-agent-sessions/SKILL.md +3 -2
- package/dist/skills/coding-agent-sessions/references/all-platforms.md +1 -1
- package/dist/skills/coding-agent-sessions/references/senpi.md +4 -4
- package/dist/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +1 -1
- package/dist/skills/data-scientist/SKILL.md +99 -239
- package/dist/skills/data-scientist/references/execution-surfaces.md +91 -0
- package/dist/skills/data-scientist/references/placement.md +74 -0
- package/dist/skills/data-scientist/references/polars-lane.md +95 -0
- package/dist/skills/data-scientist/references/uv-setup.md +1 -1
- package/dist/skills/data-scientist/references/visualization.md +64 -0
- package/dist/skills/data-scientist/scripts/ensure-js-deps.sh +28 -0
- package/dist/skills/data-scientist/scripts/ensure-py-deps.sh +37 -0
- package/dist/skills/debugging/SKILL.md +2 -0
- package/dist/skills/debugging/references/methodology/00-setup.md +12 -0
- package/dist/skills/debugging/references/methodology/02-investigate.md +21 -0
- package/dist/skills/debugging/references/runtimes/go.md +15 -1
- package/dist/skills/debugging/references/runtimes/native-binary.md +38 -0
- package/dist/skills/debugging/references/runtimes/node.md +25 -0
- package/dist/skills/debugging/references/runtimes/python.md +13 -0
- package/dist/skills/debugging/references/runtimes/rust.md +41 -0
- package/dist/skills/debugging/references/scripts/dap.mjs +267 -0
- package/dist/skills/debugging/references/scripts/dap.test.ts +86 -0
- package/dist/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
- package/dist/skills/debugging/references/tools/dap.md +103 -0
- package/dist/skills/debugging/references/tools/frida.md +193 -0
- package/dist/skills/frontend/SKILL.md +11 -7
- package/dist/skills/frontend/references/design/_INDEX.md +1 -0
- package/dist/skills/frontend/references/design/print-paged-media.md +76 -0
- package/dist/skills/frontend/references/design/stylegallery.md +80 -0
- package/dist/skills/frontend/references/designpowers/README.md +1 -1
- package/dist/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
- package/dist/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
- package/dist/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
- package/dist/skills/frontend/references/designpowers/orchestration.md +1 -1
- package/dist/skills/frontend/references/designpowers/routing.md +5 -5
- package/dist/skills/review-work/SKILL.md +3 -3
- package/dist/skills/ultimate-browsing/ATTRIBUTION.md +37 -10
- package/dist/skills/ultimate-browsing/SKILL.md +2 -0
- package/dist/skills/ultimate-browsing/engine/AGENTS.md +179 -0
- package/dist/skills/ultimate-browsing/engine/templates/package.json +1 -1
- package/dist/skills/ultimate-browsing/references/chrome-stealth.md +13 -11
- package/dist/skills/{start-work → ulw-execute}/SKILL.md +9 -8
- package/dist/skills/ulw-plan/SKILL.md +6 -6
- package/dist/skills/ulw-plan/references/full-workflow.md +31 -7
- package/dist/skills/ulw-plan/references/intent-clear.md +2 -1
- package/dist/skills/ulw-plan/references/intent-unclear.md +5 -5
- package/dist/skills/ulw-research/SKILL.md +4 -2
- package/dist/skills/visual-qa/AGENTS.md +58 -0
- package/dist/skills/visual-qa/SKILL.md +3 -2
- package/dist/tools/delegate-task/builtin-categories.d.ts +1 -0
- package/dist/tools/delegate-task/builtin-category-definition.d.ts +1 -0
- 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/tui.d.ts +12 -0
- package/dist/tui.js +11522 -11501
- package/package.json +42 -36
- package/packages/git-bash-mcp/dist/cli.js +6 -1
- package/packages/git-bash-mcp/package.json +1 -1
- package/packages/lsp-core/src/index.ts +1 -0
- package/packages/lsp-core/src/lsp/client-diagnostics-concurrency.integration.test.ts +44 -0
- package/packages/lsp-core/src/lsp/client-diagnostics-freshness.integration.test.ts +0 -28
- package/packages/lsp-core/src/lsp/client-wrapper-outside-cwd.test.ts +78 -0
- package/packages/lsp-core/src/lsp/client-wrapper.test.ts +163 -13
- package/packages/lsp-core/src/lsp/client-wrapper.ts +110 -23
- package/packages/lsp-core/src/lsp/client.ts +26 -0
- 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/errors.ts +15 -0
- 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/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/transport.ts +9 -0
- package/packages/lsp-core/src/lsp/types.ts +8 -0
- package/packages/lsp-core/src/lsp/workspace-edit-adversarial.test.ts +20 -1
- package/packages/lsp-core/src/lsp/workspace-markers.ts +18 -0
- package/packages/lsp-core/src/mcp.ts +3 -0
- package/packages/lsp-core/src/request-context.test.ts +29 -0
- package/packages/lsp-core/src/request-context.ts +1 -1
- package/packages/lsp-core/src/tool-surface.test.ts +13 -1
- package/packages/lsp-core/src/tools/definitions.ts +14 -0
- package/packages/lsp-core/src/tools/diagnostics.ts +3 -3
- package/packages/lsp-core/src/tools/format.test.ts +56 -0
- package/packages/lsp-core/src/tools/format.ts +56 -0
- package/packages/lsp-core/src/tools/index.ts +1 -0
- package/packages/lsp-core/src/tools/navigation.ts +4 -2
- package/packages/lsp-core/src/tools/rename.ts +4 -2
- package/packages/lsp-core/src/tools/symbols.ts +1 -1
- package/packages/lsp-core/src/tools/types.ts +10 -0
- package/packages/lsp-daemon/dist/cli.js +752 -307
- package/packages/lsp-daemon/dist/client.d.ts +10 -0
- package/packages/lsp-daemon/dist/client.js +712 -264
- package/packages/lsp-daemon/dist/daemon-client.d.ts +1 -0
- package/packages/lsp-daemon/dist/daemon-client.js +3 -0
- package/packages/lsp-daemon/dist/ensure-daemon.js +1 -0
- package/packages/lsp-daemon/dist/index.js +716 -273
- package/packages/lsp-daemon/dist/proxy.js +3 -0
- package/packages/lsp-daemon/dist/version-reap.js +1 -1
- package/packages/lsp-daemon/package.json +1 -1
- package/packages/lsp-tools-mcp/dist/cli.js +671 -228
- package/packages/lsp-tools-mcp/dist/lsp/manager.js +207 -103
- package/packages/lsp-tools-mcp/dist/mcp.js +673 -230
- package/packages/lsp-tools-mcp/dist/request-context.js +12 -13
- package/packages/lsp-tools-mcp/dist/tools.js +677 -238
- package/packages/omo-codex/THIRD-PARTY-NOTICES.md +4 -4
- package/packages/omo-codex/plugin/.codex-plugin/plugin.json +4 -4
- package/packages/omo-codex/plugin/AGENTS.md +47 -0
- package/packages/omo-codex/plugin/README.md +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +34 -33
- 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/codegraph/dist/cli.js +323 -117
- package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +275 -85
- package/packages/omo-codex/plugin/components/codegraph/package.json +4 -4
- package/packages/omo-codex/plugin/components/codegraph/src/mcp-bridge.ts +1 -0
- package/packages/omo-codex/plugin/components/codegraph/src/mcp-unavailable.ts +12 -0
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-hook-runtime.ts +1 -0
- package/packages/omo-codex/plugin/components/codegraph/test/serve-unavailable-idle.test.ts +47 -0
- package/packages/omo-codex/plugin/components/comment-checker/AGENTS.md +9 -0
- package/packages/omo-codex/plugin/components/comment-checker/biome.json +2 -2
- package/packages/omo-codex/plugin/components/comment-checker/dist/cli.js +2 -1
- package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/package.json +5 -5
- package/packages/omo-codex/plugin/components/comment-checker/src/apply-patch.ts +2 -8
- package/packages/omo-codex/plugin/components/comment-checker/src/core.ts +1 -2
- package/packages/omo-codex/plugin/components/comment-checker/src/request-extractor.ts +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/src/runner.ts +1 -0
- package/packages/omo-codex/plugin/components/git-bash/AGENTS.md +1 -1
- package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/git-bash/package.json +3 -4
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/biome.json +2 -2
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/cli.js +1 -5
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/codex-hook.js +1 -5
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +5 -5
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/src/codex-hook.ts +1 -5
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/test/codex-hook.test.ts +4 -21
- 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 +702 -278
- package/packages/omo-codex/plugin/components/lsp/dist/daemon-cli-path.js +1 -1
- package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/lsp/package.json +5 -5
- package/packages/omo-codex/plugin/components/lsp/src/cli.ts +1 -1
- package/packages/omo-codex/plugin/components/lsp/src/codex-hook.ts +1 -1
- package/packages/omo-codex/plugin/components/lsp/src/daemon-cli-path.ts +1 -5
- package/packages/omo-codex/plugin/components/lsp/test/codex-hook-unavailable.test.ts +6 -7
- package/packages/omo-codex/plugin/components/lsp/test/codex-hook.test.ts +1 -2
- package/packages/omo-codex/plugin/components/lsp/test/package-smoke.test.ts +11 -1
- package/packages/omo-codex/plugin/components/rules/AGENTS.md +12 -0
- package/packages/omo-codex/plugin/components/rules/biome.json +2 -2
- package/packages/omo-codex/plugin/components/rules/dist/cli.js +60 -45
- package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
- package/packages/omo-codex/plugin/components/rules/package.json +7 -7
- package/packages/omo-codex/plugin/components/rules/src/config.ts +1 -2
- package/packages/omo-codex/plugin/components/rules/src/persistent-cache.ts +1 -2
- package/packages/omo-codex/plugin/components/rules/src/post-compact-budget.ts +9 -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 +1 -2
- 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 +5 -6
- package/packages/omo-codex/plugin/components/rules/test/rules-engine-consumption.test.ts +3 -6
- package/packages/omo-codex/plugin/components/rules/test/scanner.test.ts +1 -2
- package/packages/omo-codex/plugin/components/rules/test/sources.test.ts +2 -5
- package/packages/omo-codex/plugin/components/rules/test/windows-git-bash-bundled-rule.test.ts +2 -17
- package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/package.json +5 -5
- package/packages/omo-codex/plugin/components/teammode/test/thread-title-hook.test.ts +3 -9
- 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 +2463 -437
- package/packages/omo-codex/plugin/components/telemetry/dist/posthog.js +2467 -441
- package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/package.json +5 -5
- package/packages/omo-codex/plugin/components/telemetry/src/codex-hook.ts +1 -4
- package/packages/omo-codex/plugin/components/telemetry/src/posthog.ts +4 -14
- package/packages/omo-codex/plugin/components/telemetry/src/product-identity.ts +1 -1
- package/packages/omo-codex/plugin/components/telemetry/test/diagnostics.test.ts +2 -5
- package/packages/omo-codex/plugin/components/ultrawork/AGENTS.md +5 -0
- package/packages/omo-codex/plugin/components/ultrawork/biome.json +2 -2
- package/packages/omo-codex/plugin/components/ultrawork/directive.md +13 -1
- package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/package.json +5 -5
- package/packages/omo-codex/plugin/components/ultrawork/skills/ultrawork/SKILL.md +13 -1
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +6 -6
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +31 -7
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-clear.md +2 -1
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-unclear.md +5 -5
- package/packages/omo-codex/plugin/components/ultrawork/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/skill-pointer.test.ts +0 -2
- package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/AGENTS.md +5 -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 +5 -5
- 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 +6 -6
- package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/dist/cli.js +12 -12
- package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +28 -0
- package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/package.json +12 -12
- package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/boulder-reader.ts +1 -1
- package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/cli.ts +1 -1
- package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/codex-hook.ts +3 -3
- 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}/test/boulder-reader.test.ts +3 -3
- package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/cli.test.ts +1 -4
- package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/codex-hook.test.ts +8 -22
- package/packages/omo-codex/plugin/components/ulw-loop/AGENTS.md +17 -0
- package/packages/omo-codex/plugin/components/ulw-loop/CHANGELOG.md +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/biome.json +2 -2
- package/packages/omo-codex/plugin/components/ulw-loop/directive.md +13 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.js +2 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-commands.js +5 -1
- 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 +11 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +124 -68
- 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 +9 -6
- package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-snapshot.js +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/paths.js +1 -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 +7 -10
- package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-guard.js +3 -2
- package/packages/omo-codex/plugin/components/ulw-loop/dist/stop-resume-hook.js +3 -3
- package/packages/omo-codex/plugin/components/ulw-loop/dist/surface.d.ts +15 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/surface.js +50 -0
- package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +4 -4
- package/packages/omo-codex/plugin/components/ulw-loop/package.json +5 -5
- package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md +3 -2
- package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/define-goal.md +108 -0
- package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +1 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint.ts +2 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/cli-commands.ts +5 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/cli-output.ts +13 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/cli.ts +3 -5
- package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-instruction.ts +16 -5
- package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-snapshot.ts +3 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/codex-hook.ts +3 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/paths.ts +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate.ts +11 -14
- package/packages/omo-codex/plugin/components/ulw-loop/src/spawn-guard.ts +3 -2
- package/packages/omo-codex/plugin/components/ulw-loop/src/stop-resume-hook.ts +3 -3
- package/packages/omo-codex/plugin/components/ulw-loop/src/surface.ts +73 -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 +44 -1
- package/packages/omo-codex/plugin/components/ulw-loop/test/cli-create-goals.test.ts +25 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/cli-entrypoint.test.ts +26 -2
- package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-instruction.test.ts +27 -2
- package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-snapshot.test.ts +18 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/codex-hook.test.ts +0 -3
- package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/quality-gate-builder.ts +7 -3
- 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/quality-gate-roles.test.ts +45 -2
- package/packages/omo-codex/plugin/components/ulw-loop/test/spawn-guard.test.ts +20 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/steering.test.ts +8 -5
- package/packages/omo-codex/plugin/components/ulw-loop/test/stop-resume-hook.test.ts +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/test/surface.test.ts +74 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/ultrawork-directive.test.ts +4 -5
- 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-codegraph-init-guidance.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/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-checking-codegraph-bootstrap.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-checking-ulw-execute-continuation.json +17 -0
- 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 +3 -3
- package/packages/omo-codex/plugin/package-lock.json +681 -395
- package/packages/omo-codex/plugin/package.json +2 -2
- package/packages/omo-codex/plugin/scripts/AGENTS.md +40 -0
- package/packages/omo-codex/plugin/scripts/auto-update-plan.mjs +1 -1
- package/packages/omo-codex/plugin/scripts/migrate-codex-config/catalog.mjs +3 -3
- package/packages/omo-codex/plugin/scripts/sync-skills.mjs +11 -11
- package/packages/omo-codex/plugin/shared/package.json +3 -4
- package/packages/omo-codex/plugin/skills/ast-grep/AGENTS.md +51 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/AGENTS.md +62 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/SKILL.md +3 -2
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/all-platforms.md +1 -1
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/senpi.md +4 -4
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +1 -1
- package/packages/omo-codex/plugin/skills/data-scientist/SKILL.md +99 -239
- package/packages/omo-codex/plugin/skills/data-scientist/references/execution-surfaces.md +91 -0
- package/packages/omo-codex/plugin/skills/data-scientist/references/placement.md +74 -0
- package/packages/omo-codex/plugin/skills/data-scientist/references/polars-lane.md +95 -0
- package/packages/omo-codex/plugin/skills/data-scientist/references/uv-setup.md +1 -1
- package/packages/omo-codex/plugin/skills/data-scientist/references/visualization.md +64 -0
- package/packages/omo-codex/plugin/skills/data-scientist/scripts/ensure-js-deps.sh +28 -0
- package/packages/omo-codex/plugin/skills/data-scientist/scripts/ensure-py-deps.sh +37 -0
- package/packages/omo-codex/plugin/skills/debugging/SKILL.md +2 -0
- package/packages/omo-codex/plugin/skills/debugging/references/methodology/00-setup.md +12 -0
- package/packages/omo-codex/plugin/skills/debugging/references/methodology/02-investigate.md +21 -0
- package/packages/omo-codex/plugin/skills/debugging/references/runtimes/go.md +15 -1
- package/packages/omo-codex/plugin/skills/debugging/references/runtimes/native-binary.md +38 -0
- package/packages/omo-codex/plugin/skills/debugging/references/runtimes/node.md +25 -0
- package/packages/omo-codex/plugin/skills/debugging/references/runtimes/python.md +13 -0
- package/packages/omo-codex/plugin/skills/debugging/references/runtimes/rust.md +41 -0
- package/packages/omo-codex/plugin/skills/debugging/references/scripts/dap.mjs +267 -0
- package/packages/omo-codex/plugin/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
- package/packages/omo-codex/plugin/skills/debugging/references/tools/dap.md +103 -0
- package/packages/omo-codex/plugin/skills/debugging/references/tools/frida.md +193 -0
- package/packages/omo-codex/plugin/skills/frontend/SKILL.md +11 -7
- package/packages/omo-codex/plugin/skills/frontend/references/design/_INDEX.md +1 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/print-paged-media.md +76 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/stylegallery.md +80 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/README.md +1 -1
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/orchestration.md +1 -1
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/routing.md +5 -5
- package/packages/omo-codex/plugin/skills/review-work/SKILL.md +4 -4
- package/packages/omo-codex/plugin/skills/ultimate-browsing/ATTRIBUTION.md +37 -10
- package/packages/omo-codex/plugin/skills/ultimate-browsing/SKILL.md +2 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/AGENTS.md +179 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/templates/package.json +1 -1
- package/packages/omo-codex/plugin/skills/ultimate-browsing/references/chrome-stealth.md +13 -11
- package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +13 -1
- package/packages/omo-codex/plugin/skills/{start-work → ulw-execute}/SKILL.md +12 -11
- package/packages/omo-codex/plugin/skills/ulw-execute/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +3 -2
- package/packages/omo-codex/plugin/skills/ulw-loop/references/define-goal.md +108 -0
- package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +1 -0
- package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +6 -6
- package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +31 -7
- package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-clear.md +2 -1
- package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-unclear.md +5 -5
- package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +4 -2
- package/packages/omo-codex/plugin/skills/visual-qa/AGENTS.md +58 -0
- package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +3 -2
- 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 +8 -28
- package/packages/omo-codex/plugin/test/aggregate-manifest.test.mjs +1 -1
- package/packages/omo-codex/plugin/test/aggregate-model-catalog.test.mjs +1 -1
- 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 +2 -2
- 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 -1
- package/packages/omo-codex/plugin/test/component-hook-contract-cases.mjs +2 -2
- package/packages/omo-codex/plugin/test/hook-status-message.test.mjs +4 -4
- package/packages/omo-codex/plugin/test/lcx-contribute-bug-fix-template.test.mjs +21 -27
- package/packages/omo-codex/plugin/test/migrate-codex-config.test.mjs +8 -8
- package/packages/omo-codex/plugin/test/scaffold-plan.test.mjs +0 -36
- package/packages/omo-codex/plugin/test/sync-skills-codex-compatibility.test.mjs +101 -0
- package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +12 -12
- package/packages/omo-codex/plugin/test/sync-skills.test.mjs +1 -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 +0 -3
- 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/install-config-reasoning.test.mjs +2 -2
- package/packages/omo-codex/scripts/install-dist/install-local.mjs +2637 -549
- package/packages/omo-codex/scripts/install-lazycodex-version-stamp.test.mjs +7 -2
- package/packages/shared-skills/skills/ast-grep/AGENTS.md +51 -0
- package/packages/shared-skills/skills/coding-agent-sessions/AGENTS.md +62 -0
- package/packages/shared-skills/skills/coding-agent-sessions/SKILL.md +3 -2
- package/packages/shared-skills/skills/coding-agent-sessions/references/all-platforms.md +1 -1
- package/packages/shared-skills/skills/coding-agent-sessions/references/senpi.md +4 -4
- package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +1 -1
- package/packages/shared-skills/skills/data-scientist/SKILL.md +99 -239
- package/packages/shared-skills/skills/data-scientist/references/execution-surfaces.md +91 -0
- package/packages/shared-skills/skills/data-scientist/references/placement.md +74 -0
- package/packages/shared-skills/skills/data-scientist/references/polars-lane.md +95 -0
- package/packages/shared-skills/skills/data-scientist/references/uv-setup.md +1 -1
- package/packages/shared-skills/skills/data-scientist/references/visualization.md +64 -0
- package/packages/shared-skills/skills/data-scientist/scripts/ensure-js-deps.sh +28 -0
- package/packages/shared-skills/skills/data-scientist/scripts/ensure-py-deps.sh +37 -0
- package/packages/shared-skills/skills/debugging/SKILL.md +2 -0
- package/packages/shared-skills/skills/debugging/references/methodology/00-setup.md +12 -0
- package/packages/shared-skills/skills/debugging/references/methodology/02-investigate.md +21 -0
- package/packages/shared-skills/skills/debugging/references/runtimes/go.md +15 -1
- package/packages/shared-skills/skills/debugging/references/runtimes/native-binary.md +38 -0
- package/packages/shared-skills/skills/debugging/references/runtimes/node.md +25 -0
- package/packages/shared-skills/skills/debugging/references/runtimes/python.md +13 -0
- package/packages/shared-skills/skills/debugging/references/runtimes/rust.md +41 -0
- package/packages/shared-skills/skills/debugging/references/scripts/dap.mjs +267 -0
- package/packages/shared-skills/skills/debugging/references/scripts/dap.test.ts +86 -0
- package/packages/shared-skills/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
- package/packages/shared-skills/skills/debugging/references/tools/dap.md +103 -0
- package/packages/shared-skills/skills/debugging/references/tools/frida.md +193 -0
- package/packages/shared-skills/skills/frontend/SKILL.md +11 -7
- package/packages/shared-skills/skills/frontend/references/design/_INDEX.md +1 -0
- package/packages/shared-skills/skills/frontend/references/design/print-paged-media.md +76 -0
- package/packages/shared-skills/skills/frontend/references/design/stylegallery.md +80 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/README.md +1 -1
- package/packages/shared-skills/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
- package/packages/shared-skills/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
- package/packages/shared-skills/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
- package/packages/shared-skills/skills/frontend/references/designpowers/orchestration.md +1 -1
- package/packages/shared-skills/skills/frontend/references/designpowers/routing.md +5 -5
- package/packages/shared-skills/skills/review-work/SKILL.md +3 -3
- package/packages/shared-skills/skills/ultimate-browsing/ATTRIBUTION.md +37 -10
- package/packages/shared-skills/skills/ultimate-browsing/SKILL.md +2 -0
- package/packages/shared-skills/skills/ultimate-browsing/engine/AGENTS.md +179 -0
- package/packages/shared-skills/skills/ultimate-browsing/engine/templates/package.json +1 -1
- package/packages/shared-skills/skills/ultimate-browsing/references/chrome-stealth.md +13 -11
- package/packages/shared-skills/skills/{start-work → ulw-execute}/SKILL.md +9 -8
- package/packages/shared-skills/skills/ulw-plan/SKILL.md +6 -6
- package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +31 -7
- package/packages/shared-skills/skills/ulw-plan/references/intent-clear.md +2 -1
- package/packages/shared-skills/skills/ulw-plan/references/intent-unclear.md +5 -5
- package/packages/shared-skills/skills/ulw-research/SKILL.md +4 -2
- package/packages/shared-skills/skills/visual-qa/AGENTS.md +58 -0
- package/packages/shared-skills/skills/visual-qa/SKILL.md +3 -2
- package/script/qa/web-terminal-visual-qa.mjs +2 -0
- package/script/qa/xterm-live-terminal.mjs +18 -2
- package/dist/config/schema/start-work.d.ts +0 -5
- package/dist/features/builtin-commands/templates/start-work.d.ts +0 -1
- 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/plugin/chat-message/start-work-message.d.ts +0 -5
- package/dist/skills/data-scientist/references/common-scenarios.md +0 -176
- package/dist/skills/data-scientist/references/execution-templates.md +0 -197
- package/dist/skills/data-scientist/references/integration-patterns.md +0 -153
- package/dist/skills/data-scientist/references/performance-benchmarks.md +0 -37
- package/dist/tools/call-omo-agent/background-agent-executor.d.ts +0 -5
- package/dist/tools/call-omo-agent/message-storage-directory.d.ts +0 -1
- package/dist/tools/delegate-task/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/start-work-continuation/hooks/hooks.json +0 -28
- 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/skills/data-scientist/references/common-scenarios.md +0 -176
- package/packages/omo-codex/plugin/skills/data-scientist/references/execution-templates.md +0 -197
- package/packages/omo-codex/plugin/skills/data-scientist/references/integration-patterns.md +0 -153
- package/packages/omo-codex/plugin/skills/data-scientist/references/performance-benchmarks.md +0 -37
- package/packages/omo-codex/plugin/skills/start-work/agents/openai.yaml +0 -2
- package/packages/omo-codex/plugin/test/aggregate-skills.test.mjs +0 -92
- package/packages/omo-codex/plugin/test/sync-skills-orchestration.test.mjs +0 -314
- package/packages/omo-codex/plugin/test/ulw-plan-scope-contract.test.mjs +0 -24
- package/packages/shared-skills/skills/data-scientist/references/common-scenarios.md +0 -176
- package/packages/shared-skills/skills/data-scientist/references/execution-templates.md +0 -197
- package/packages/shared-skills/skills/data-scientist/references/integration-patterns.md +0 -153
- package/packages/shared-skills/skills/data-scientist/references/performance-benchmarks.md +0 -37
- /package/dist/hooks/{start-work → ulw-execute}/context-info-formatters.d.ts +0 -0
- /package/dist/hooks/{start-work → ulw-execute}/explicit-plan-context.d.ts +0 -0
- /package/dist/hooks/{start-work → ulw-execute}/notepad-scaffold.d.ts +0 -0
- /package/dist/hooks/{start-work → ulw-execute}/parse-user-request.d.ts +0 -0
- /package/dist/hooks/{start-work → ulw-execute}/plan-discovery-context.d.ts +0 -0
- /package/dist/hooks/{start-work → ulw-execute}/plan-selection.d.ts +0 -0
- /package/dist/hooks/{start-work → ulw-execute}/session-plan-affinity.d.ts +0 -0
- /package/dist/hooks/{start-work → ulw-execute}/work-initializer.d.ts +0 -0
- /package/dist/hooks/{start-work → ulw-execute}/worktree-block.d.ts +0 -0
- /package/dist/hooks/{start-work → ulw-execute}/worktree-detector.d.ts +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/.gitattributes +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/CHANGELOG.md +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → 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}/src/types.ts +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-completed.json +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-mixed-platforms.json +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-single-codex-work.json +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-all-done.md +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-scaffold.md +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-with-nested-checkboxes.md +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-with-unchecked.md +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/tsconfig.build.json +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/tsconfig.json +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/vitest.config.ts +0 -0
|
@@ -1,7 +1,11 @@
|
|
|
1
|
+
// src/client.ts
|
|
2
|
+
import { statSync as statSync5 } from "node:fs";
|
|
3
|
+
import { isAbsolute as isAbsolute6 } from "node:path";
|
|
4
|
+
|
|
1
5
|
// src/daemon-client.ts
|
|
2
6
|
import { connect } from "node:net";
|
|
3
7
|
import { homedir as homedir3 } from "node:os";
|
|
4
|
-
import { join as
|
|
8
|
+
import { join as join8 } from "node:path";
|
|
5
9
|
|
|
6
10
|
// ../lsp-core/src/request-context.ts
|
|
7
11
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
@@ -10,18 +14,17 @@ import { homedir } from "node:os";
|
|
|
10
14
|
import { basename, delimiter, dirname, isAbsolute, join, relative, resolve } from "node:path";
|
|
11
15
|
|
|
12
16
|
class LspRequestContextParseError extends Error {
|
|
13
|
-
code;
|
|
14
|
-
name = "LspRequestContextParseError";
|
|
15
17
|
constructor(code, message) {
|
|
16
18
|
super(message);
|
|
17
19
|
this.code = code;
|
|
20
|
+
this.name = "LspRequestContextParseError";
|
|
18
21
|
}
|
|
19
22
|
}
|
|
20
23
|
|
|
21
24
|
class LspRequestContextUnavailableError extends Error {
|
|
22
|
-
name = "LspRequestContextUnavailableError";
|
|
23
25
|
constructor() {
|
|
24
26
|
super("LSP request context is required. Standalone MCP startup must install one with runWithRequestContext(createStandaloneMcpRequestContext()).");
|
|
27
|
+
this.name = "LspRequestContextUnavailableError";
|
|
25
28
|
}
|
|
26
29
|
}
|
|
27
30
|
var storage = new AsyncLocalStorage;
|
|
@@ -41,7 +44,7 @@ function contextCwd() {
|
|
|
41
44
|
}
|
|
42
45
|
function createStandaloneMcpRequestContext(input = {}) {
|
|
43
46
|
const env = input.env ?? process.env;
|
|
44
|
-
const cwd = canonicalCwd(input.cwd ?? process.cwd());
|
|
47
|
+
const cwd = canonicalCwd(input.cwd ?? env["LSP_TOOLS_MCP_CWD"] ?? process.cwd());
|
|
45
48
|
const home = input.homeDir ?? homedir();
|
|
46
49
|
const projectConfigPaths = translateProjectConfigEnv(env["LSP_TOOLS_MCP_PROJECT_CONFIG"], cwd);
|
|
47
50
|
const userConfigPath = translateHomeConfigEnv(env["LSP_TOOLS_MCP_USER_CONFIG"], home, ".codex/lsp-client.json");
|
|
@@ -179,7 +182,6 @@ function isPlainRecord(value) {
|
|
|
179
182
|
|
|
180
183
|
// src/daemon-request-error.ts
|
|
181
184
|
class DaemonRequestError extends Error {
|
|
182
|
-
requestWritten;
|
|
183
185
|
constructor(message, requestWritten) {
|
|
184
186
|
super(message);
|
|
185
187
|
this.name = "DaemonRequestError";
|
|
@@ -202,7 +204,6 @@ class DaemonRequestCancelledError extends DaemonRequestError {
|
|
|
202
204
|
}
|
|
203
205
|
|
|
204
206
|
class DaemonRequestTimedOutError extends DaemonRequestError {
|
|
205
|
-
timeoutMs;
|
|
206
207
|
constructor(requestWritten, timeoutMs) {
|
|
207
208
|
super("daemon request timed out", requestWritten);
|
|
208
209
|
this.name = "DaemonRequestTimedOutError";
|
|
@@ -281,14 +282,12 @@ var PROTOCOL_ERROR_CODE = -32002;
|
|
|
281
282
|
var AUTH_TOKEN_BYTES = 32;
|
|
282
283
|
|
|
283
284
|
class UnsafePrivateDirectoryError extends Error {
|
|
284
|
-
path;
|
|
285
|
-
reason;
|
|
286
|
-
name = "UnsafePrivateDirectoryError";
|
|
287
|
-
code = "unsafe_private_directory";
|
|
288
285
|
constructor(path, reason) {
|
|
289
286
|
super(`unsafe private directory ${path}: ${reason}`);
|
|
290
287
|
this.path = path;
|
|
291
288
|
this.reason = reason;
|
|
289
|
+
this.name = "UnsafePrivateDirectoryError";
|
|
290
|
+
this.code = "unsafe_private_directory";
|
|
292
291
|
}
|
|
293
292
|
}
|
|
294
293
|
function authEnvelope(token) {
|
|
@@ -472,20 +471,18 @@ var OMO_LSP_DAEMON_VERSION = "OMO_LSP_DAEMON_VERSION";
|
|
|
472
471
|
var DAEMON_VERSION_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._+-]{0,127}$/;
|
|
473
472
|
|
|
474
473
|
class InvalidRuntimeOverrideError extends Error {
|
|
475
|
-
code = "invalid_runtime_override";
|
|
476
|
-
reason;
|
|
477
474
|
constructor(reason, message) {
|
|
478
475
|
super(message);
|
|
476
|
+
this.code = "invalid_runtime_override";
|
|
479
477
|
this.name = "InvalidRuntimeOverrideError";
|
|
480
478
|
this.reason = reason;
|
|
481
479
|
}
|
|
482
480
|
}
|
|
483
481
|
|
|
484
482
|
class InvalidDaemonVersionError extends Error {
|
|
485
|
-
code = "invalid_daemon_version";
|
|
486
|
-
version;
|
|
487
483
|
constructor(version) {
|
|
488
484
|
super("LSP daemon version must match [A-Za-z0-9][A-Za-z0-9._+-]{0,127}");
|
|
485
|
+
this.code = "invalid_daemon_version";
|
|
489
486
|
this.name = "InvalidDaemonVersionError";
|
|
490
487
|
this.version = version;
|
|
491
488
|
}
|
|
@@ -531,10 +528,9 @@ var requireFromHere = createRequire(import.meta.url);
|
|
|
531
528
|
var MAX_SOCKET_PATH_LENGTH = 100;
|
|
532
529
|
|
|
533
530
|
class InvalidDaemonDirectoryError extends Error {
|
|
534
|
-
code = "invalid_daemon_directory";
|
|
535
|
-
directory;
|
|
536
531
|
constructor(directory) {
|
|
537
532
|
super(`${OMO_LSP_DAEMON_DIR} must be an absolute path`);
|
|
533
|
+
this.code = "invalid_daemon_directory";
|
|
538
534
|
this.name = "InvalidDaemonDirectoryError";
|
|
539
535
|
this.directory = directory;
|
|
540
536
|
}
|
|
@@ -729,7 +725,8 @@ function spawnDaemonProcess(paths) {
|
|
|
729
725
|
try {
|
|
730
726
|
const child = spawn(resolveDaemonNodeExecutable(), [paths.cliPath, "daemon"], {
|
|
731
727
|
detached: true,
|
|
732
|
-
stdio: ["ignore", logFd, logFd]
|
|
728
|
+
stdio: ["ignore", logFd, logFd],
|
|
729
|
+
windowsHide: true
|
|
733
730
|
});
|
|
734
731
|
child.once("spawn", () => closeSync2(logFd));
|
|
735
732
|
child.once("error", (error) => {
|
|
@@ -1010,6 +1007,7 @@ async function runJsonRpcStdioServer(config) {
|
|
|
1010
1007
|
const idleTimer = createIdleTimer(idleTimeoutMs, log, () => {
|
|
1011
1008
|
isClosed = true;
|
|
1012
1009
|
config.onIdleTimeout?.();
|
|
1010
|
+
config.input.destroy();
|
|
1013
1011
|
});
|
|
1014
1012
|
const watchdog = createParentWatchdog(config.parentWatchdog, (parentPid, pollIntervalMs) => {
|
|
1015
1013
|
isClosed = true;
|
|
@@ -1106,7 +1104,11 @@ function createParentWatchdog(config, onDeadParent) {
|
|
|
1106
1104
|
const probeAlive = config.probeAlive ?? isProcessAlive;
|
|
1107
1105
|
let fired = false;
|
|
1108
1106
|
const timer = setInterval(() => {
|
|
1109
|
-
if (fired
|
|
1107
|
+
if (fired)
|
|
1108
|
+
return;
|
|
1109
|
+
const alive = probeAlive(parentPid);
|
|
1110
|
+
config.onPoll?.(alive);
|
|
1111
|
+
if (alive)
|
|
1110
1112
|
return;
|
|
1111
1113
|
fired = true;
|
|
1112
1114
|
onDeadParent(parentPid, pollIntervalMs);
|
|
@@ -1141,8 +1143,8 @@ function createIdleTimer(idleTimeoutMs, log, onTimeout) {
|
|
|
1141
1143
|
};
|
|
1142
1144
|
}
|
|
1143
1145
|
// ../lsp-core/src/lsp/client-wrapper.ts
|
|
1144
|
-
import { existsSync as
|
|
1145
|
-
import { dirname as
|
|
1146
|
+
import { existsSync as existsSync11, realpathSync as realpathSync5, statSync as statSync4 } from "node:fs";
|
|
1147
|
+
import { basename as basename3, dirname as dirname10, join as join5, resolve as resolve8 } from "node:path";
|
|
1146
1148
|
|
|
1147
1149
|
// ../lsp-core/src/lsp/effective-extension.ts
|
|
1148
1150
|
import { basename as basename2, extname } from "node:path";
|
|
@@ -1156,22 +1158,15 @@ function effectiveExtension(filePath) {
|
|
|
1156
1158
|
|
|
1157
1159
|
// ../lsp-core/src/lsp/errors.ts
|
|
1158
1160
|
class LspConnectionClosedError extends Error {
|
|
1159
|
-
serverId;
|
|
1160
|
-
root;
|
|
1161
|
-
name = "LspConnectionClosedError";
|
|
1162
1161
|
constructor(serverId, root, message) {
|
|
1163
1162
|
super(message ?? `LSP connection closed for ${serverId} at ${root}`);
|
|
1164
1163
|
this.serverId = serverId;
|
|
1165
1164
|
this.root = root;
|
|
1165
|
+
this.name = "LspConnectionClosedError";
|
|
1166
1166
|
}
|
|
1167
1167
|
}
|
|
1168
1168
|
|
|
1169
1169
|
class LspProcessExitedError extends Error {
|
|
1170
|
-
serverId;
|
|
1171
|
-
root;
|
|
1172
|
-
exitCode;
|
|
1173
|
-
stderrTail;
|
|
1174
|
-
name = "LspProcessExitedError";
|
|
1175
1170
|
constructor(serverId, root, exitCode, stderrTail) {
|
|
1176
1171
|
const stderrSuffix = stderrTail ? `
|
|
1177
1172
|
stderr tail: ${stderrTail}` : "";
|
|
@@ -1180,46 +1175,59 @@ stderr tail: ${stderrTail}` : "";
|
|
|
1180
1175
|
this.root = root;
|
|
1181
1176
|
this.exitCode = exitCode;
|
|
1182
1177
|
this.stderrTail = stderrTail;
|
|
1178
|
+
this.name = "LspProcessExitedError";
|
|
1183
1179
|
}
|
|
1184
1180
|
}
|
|
1185
1181
|
|
|
1186
1182
|
class LspRequestTimeoutError extends Error {
|
|
1187
|
-
method;
|
|
1188
|
-
stderrTail;
|
|
1189
|
-
name = "LspRequestTimeoutError";
|
|
1190
1183
|
constructor(method, stderrTail) {
|
|
1191
1184
|
const stderrSuffix = stderrTail ? `
|
|
1192
1185
|
recent stderr: ${stderrTail}` : "";
|
|
1193
1186
|
super(`LSP request timeout (method: ${method})${stderrSuffix}`);
|
|
1194
1187
|
this.method = method;
|
|
1195
1188
|
this.stderrTail = stderrTail;
|
|
1189
|
+
this.name = "LspRequestTimeoutError";
|
|
1196
1190
|
}
|
|
1197
1191
|
}
|
|
1198
1192
|
|
|
1199
1193
|
class LspInvalidPathError extends Error {
|
|
1200
|
-
|
|
1194
|
+
constructor() {
|
|
1195
|
+
super(...arguments);
|
|
1196
|
+
this.name = "LspInvalidPathError";
|
|
1197
|
+
}
|
|
1201
1198
|
}
|
|
1202
1199
|
|
|
1203
1200
|
class LspServerLookupError extends Error {
|
|
1204
|
-
lookup;
|
|
1205
|
-
name = "LspServerLookupError";
|
|
1206
1201
|
constructor(message, lookup) {
|
|
1207
1202
|
super(message);
|
|
1208
1203
|
this.lookup = lookup;
|
|
1204
|
+
this.name = "LspServerLookupError";
|
|
1209
1205
|
}
|
|
1210
1206
|
}
|
|
1211
1207
|
|
|
1212
1208
|
class LspServerInitializingError extends Error {
|
|
1213
|
-
originalError;
|
|
1214
|
-
name = "LspServerInitializingError";
|
|
1215
1209
|
constructor(originalError) {
|
|
1216
1210
|
super(`LSP server is still initializing. Please retry in a few seconds. Original error: ${originalError.message}`);
|
|
1217
1211
|
this.originalError = originalError;
|
|
1212
|
+
this.name = "LspServerInitializingError";
|
|
1218
1213
|
}
|
|
1219
1214
|
}
|
|
1220
1215
|
|
|
1221
1216
|
class LspProcessSpawnError extends Error {
|
|
1222
|
-
|
|
1217
|
+
constructor() {
|
|
1218
|
+
super(...arguments);
|
|
1219
|
+
this.name = "LspProcessSpawnError";
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
class LspClientRespawnBudgetExceededError extends Error {
|
|
1224
|
+
constructor(serverId, root, retryLimit) {
|
|
1225
|
+
super(`LSP server ${serverId} at ${root} failed to stay alive; respawn budget exhausted ` + `(${retryLimit} consecutive dead generations). Retrying after the cooldown may succeed.`);
|
|
1226
|
+
this.serverId = serverId;
|
|
1227
|
+
this.root = root;
|
|
1228
|
+
this.retryLimit = retryLimit;
|
|
1229
|
+
this.name = "LspClientRespawnBudgetExceededError";
|
|
1230
|
+
}
|
|
1223
1231
|
}
|
|
1224
1232
|
function isLspDeadConnectionError(err) {
|
|
1225
1233
|
return err instanceof LspConnectionClosedError || err instanceof LspProcessExitedError;
|
|
@@ -1250,9 +1258,12 @@ var DEFAULT_MAX_DIRECTORY_FILES = 50;
|
|
|
1250
1258
|
var REQUEST_TIMEOUT_MS = 15000;
|
|
1251
1259
|
var INIT_TIMEOUT_MS = 60000;
|
|
1252
1260
|
var IDLE_TIMEOUT_MS = 5 * 60000;
|
|
1261
|
+
var MAX_RESIDENT_CLIENTS = 6;
|
|
1253
1262
|
var REAPER_INTERVAL_MS = 60000;
|
|
1254
1263
|
var STOP_HARD_KILL_TIMEOUT_MS = 5000;
|
|
1255
1264
|
var STOP_SIGKILL_GRACE_MS = 1000;
|
|
1265
|
+
var CLIENT_RESPAWN_RETRY_LIMIT = 2;
|
|
1266
|
+
var CLIENT_RESPAWN_COOLDOWN_MS = 60000;
|
|
1256
1267
|
|
|
1257
1268
|
// ../lsp-core/src/lsp/json-rpc-connection.ts
|
|
1258
1269
|
var HEADER_SEPARATOR2 = `\r
|
|
@@ -1264,20 +1275,31 @@ var METHOD_NOT_FOUND = -32601;
|
|
|
1264
1275
|
var INTERNAL_ERROR = -32603;
|
|
1265
1276
|
|
|
1266
1277
|
class JsonRpcConnection {
|
|
1267
|
-
reader;
|
|
1268
|
-
writer;
|
|
1269
|
-
pendingRequests = new Map;
|
|
1270
|
-
notificationHandlers = new Map;
|
|
1271
|
-
requestHandlers = new Map;
|
|
1272
|
-
closeHandlers = [];
|
|
1273
|
-
errorHandlers = [];
|
|
1274
|
-
inputBuffer = Buffer.alloc(0);
|
|
1275
|
-
nextRequestId = 1;
|
|
1276
|
-
listening = false;
|
|
1277
|
-
disposed = false;
|
|
1278
1278
|
constructor(reader, writer) {
|
|
1279
1279
|
this.reader = reader;
|
|
1280
1280
|
this.writer = writer;
|
|
1281
|
+
this.pendingRequests = new Map;
|
|
1282
|
+
this.notificationHandlers = new Map;
|
|
1283
|
+
this.requestHandlers = new Map;
|
|
1284
|
+
this.closeHandlers = [];
|
|
1285
|
+
this.errorHandlers = [];
|
|
1286
|
+
this.inputBuffer = Buffer.alloc(0);
|
|
1287
|
+
this.nextRequestId = 1;
|
|
1288
|
+
this.listening = false;
|
|
1289
|
+
this.disposed = false;
|
|
1290
|
+
this.handleData = (chunk) => {
|
|
1291
|
+
const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
|
|
1292
|
+
this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
|
|
1293
|
+
this.drainInputBuffer();
|
|
1294
|
+
};
|
|
1295
|
+
this.handleClose = () => {
|
|
1296
|
+
for (const handler of this.closeHandlers) {
|
|
1297
|
+
handler();
|
|
1298
|
+
}
|
|
1299
|
+
};
|
|
1300
|
+
this.handleStreamError = (error) => {
|
|
1301
|
+
this.emitError(error);
|
|
1302
|
+
};
|
|
1281
1303
|
}
|
|
1282
1304
|
listen() {
|
|
1283
1305
|
if (this.listening)
|
|
@@ -1398,19 +1420,6 @@ class JsonRpcConnection {
|
|
|
1398
1420
|
this.notificationHandlers.clear();
|
|
1399
1421
|
this.requestHandlers.clear();
|
|
1400
1422
|
}
|
|
1401
|
-
handleData = (chunk) => {
|
|
1402
|
-
const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
|
|
1403
|
-
this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
|
|
1404
|
-
this.drainInputBuffer();
|
|
1405
|
-
};
|
|
1406
|
-
handleClose = () => {
|
|
1407
|
-
for (const handler of this.closeHandlers) {
|
|
1408
|
-
handler();
|
|
1409
|
-
}
|
|
1410
|
-
};
|
|
1411
|
-
handleStreamError = (error) => {
|
|
1412
|
-
this.emitError(error);
|
|
1413
|
-
};
|
|
1414
1423
|
drainInputBuffer() {
|
|
1415
1424
|
while (true) {
|
|
1416
1425
|
const headerEnd = this.inputBuffer.indexOf(HEADER_SEPARATOR2);
|
|
@@ -1758,31 +1767,26 @@ function isPosition(value) {
|
|
|
1758
1767
|
|
|
1759
1768
|
// ../lsp-core/src/lsp/transport.ts
|
|
1760
1769
|
class LspClientNotStartedError extends Error {
|
|
1761
|
-
serverId;
|
|
1762
|
-
root;
|
|
1763
|
-
name = "LspClientNotStartedError";
|
|
1764
1770
|
constructor(serverId, root) {
|
|
1765
1771
|
super("LSP client not started");
|
|
1766
1772
|
this.serverId = serverId;
|
|
1767
1773
|
this.root = root;
|
|
1774
|
+
this.name = "LspClientNotStartedError";
|
|
1768
1775
|
}
|
|
1769
1776
|
}
|
|
1770
1777
|
|
|
1771
1778
|
class LspClientTransport {
|
|
1772
|
-
root;
|
|
1773
|
-
server;
|
|
1774
|
-
proc = null;
|
|
1775
|
-
connection = null;
|
|
1776
|
-
stderrBuffer = [];
|
|
1777
|
-
processExited = false;
|
|
1778
|
-
diagnosticsStore = new Map;
|
|
1779
|
-
requestTimeoutMs;
|
|
1780
|
-
initializeTimeoutMs;
|
|
1781
|
-
workspaceApplyEditHandler = null;
|
|
1782
|
-
diagnosticPullSupported = false;
|
|
1783
1779
|
constructor(root, server2, timeouts = {}) {
|
|
1784
1780
|
this.root = root;
|
|
1785
1781
|
this.server = server2;
|
|
1782
|
+
this.proc = null;
|
|
1783
|
+
this.connection = null;
|
|
1784
|
+
this.stderrBuffer = [];
|
|
1785
|
+
this.processExited = false;
|
|
1786
|
+
this.diagnosticsStore = new Map;
|
|
1787
|
+
this.workspaceApplyEditHandler = null;
|
|
1788
|
+
this.diagnosticPullSupported = false;
|
|
1789
|
+
this.documentFormattingSupported = false;
|
|
1786
1790
|
this.requestTimeoutMs = timeouts.requestTimeoutMs ?? REQUEST_TIMEOUT_MS;
|
|
1787
1791
|
this.initializeTimeoutMs = timeouts.initializeTimeoutMs ?? INIT_TIMEOUT_MS;
|
|
1788
1792
|
}
|
|
@@ -1804,6 +1808,12 @@ class LspClientTransport {
|
|
|
1804
1808
|
isDiagnosticPullSupported() {
|
|
1805
1809
|
return this.diagnosticPullSupported;
|
|
1806
1810
|
}
|
|
1811
|
+
setDocumentFormattingSupported(supported) {
|
|
1812
|
+
this.documentFormattingSupported = supported;
|
|
1813
|
+
}
|
|
1814
|
+
isDocumentFormattingSupported() {
|
|
1815
|
+
return this.documentFormattingSupported;
|
|
1816
|
+
}
|
|
1807
1817
|
handlePublishDiagnostics(params) {
|
|
1808
1818
|
this.diagnosticsStore.set(params.uri, [...params.diagnostics]);
|
|
1809
1819
|
}
|
|
@@ -2017,6 +2027,14 @@ function supportsDiagnosticPull(capabilities) {
|
|
|
2017
2027
|
return false;
|
|
2018
2028
|
return Object.hasOwn(capabilities, "diagnosticProvider");
|
|
2019
2029
|
}
|
|
2030
|
+
function supportsDocumentFormatting(capabilities) {
|
|
2031
|
+
if (capabilities === undefined)
|
|
2032
|
+
return false;
|
|
2033
|
+
const provider = capabilities.documentFormattingProvider;
|
|
2034
|
+
if (provider === undefined || provider === null || provider === false)
|
|
2035
|
+
return false;
|
|
2036
|
+
return provider === true || typeof provider === "object";
|
|
2037
|
+
}
|
|
2020
2038
|
|
|
2021
2039
|
class LspClientConnection extends LspClientTransport {
|
|
2022
2040
|
async initialize() {
|
|
@@ -2033,6 +2051,7 @@ class LspClientConnection extends LspClientTransport {
|
|
|
2033
2051
|
references: {},
|
|
2034
2052
|
documentSymbol: { hierarchicalDocumentSymbolSupport: true },
|
|
2035
2053
|
publishDiagnostics: {},
|
|
2054
|
+
formatting: { dynamicRegistration: false },
|
|
2036
2055
|
rename: {
|
|
2037
2056
|
prepareSupport: true,
|
|
2038
2057
|
prepareSupportDefaultBehavior: 1
|
|
@@ -2074,6 +2093,7 @@ class LspClientConnection extends LspClientTransport {
|
|
|
2074
2093
|
initializationOptions: this.server.initialization
|
|
2075
2094
|
}, { timeoutMs: this.initializeTimeoutMs });
|
|
2076
2095
|
this.setDiagnosticPullSupported(supportsDiagnosticPull(result?.capabilities));
|
|
2096
|
+
this.setDocumentFormattingSupported(supportsDocumentFormatting(result?.capabilities));
|
|
2077
2097
|
await this.sendNotification("initialized", {});
|
|
2078
2098
|
await this.sendNotification("workspace/didChangeConfiguration", {
|
|
2079
2099
|
settings: { json: { validate: { enable: true } } }
|
|
@@ -2279,16 +2299,12 @@ function movedPath(candidate, oldPath, newPath) {
|
|
|
2279
2299
|
}
|
|
2280
2300
|
|
|
2281
2301
|
class WorkspaceDocumentState {
|
|
2282
|
-
sendNotification;
|
|
2283
|
-
clearDiagnostics;
|
|
2284
|
-
openDocuments = new Map;
|
|
2285
|
-
openByUri = new Map;
|
|
2286
|
-
openPromises = new Map;
|
|
2287
|
-
now;
|
|
2288
|
-
versionlessPublishQuiescenceMs;
|
|
2289
2302
|
constructor(sendNotification, clearDiagnostics, options = {}) {
|
|
2290
2303
|
this.sendNotification = sendNotification;
|
|
2291
2304
|
this.clearDiagnostics = clearDiagnostics;
|
|
2305
|
+
this.openDocuments = new Map;
|
|
2306
|
+
this.openByUri = new Map;
|
|
2307
|
+
this.openPromises = new Map;
|
|
2292
2308
|
this.now = options.now ?? (() => Date.now());
|
|
2293
2309
|
this.versionlessPublishQuiescenceMs = options.versionlessPublishQuiescenceMs ?? DEFAULT_VERSIONLESS_PUBLISH_QUIESCENCE_MS;
|
|
2294
2310
|
}
|
|
@@ -2552,13 +2568,11 @@ import { dirname as dirname4, isAbsolute as isAbsolute4, relative as relative3,
|
|
|
2552
2568
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
2553
2569
|
|
|
2554
2570
|
class WorkspaceEditPathError extends Error {
|
|
2555
|
-
path;
|
|
2556
|
-
detail;
|
|
2557
|
-
name = "WorkspaceEditPathError";
|
|
2558
2571
|
constructor(path2, detail) {
|
|
2559
2572
|
super(`${detail}: ${path2}`);
|
|
2560
2573
|
this.path = path2;
|
|
2561
2574
|
this.detail = detail;
|
|
2575
|
+
this.name = "WorkspaceEditPathError";
|
|
2562
2576
|
}
|
|
2563
2577
|
}
|
|
2564
2578
|
function isPathInsideWorkspace(filePath, workspaceRoot) {
|
|
@@ -2850,13 +2864,11 @@ function canonicalFingerprint(operations) {
|
|
|
2850
2864
|
|
|
2851
2865
|
// ../lsp-core/src/lsp/workspace-edit-types.ts
|
|
2852
2866
|
class WorkspaceEditValidationError extends Error {
|
|
2853
|
-
changeIndex;
|
|
2854
|
-
detail;
|
|
2855
|
-
name = "WorkspaceEditValidationError";
|
|
2856
2867
|
constructor(changeIndex, detail) {
|
|
2857
2868
|
super(`change ${changeIndex}: ${detail}`);
|
|
2858
2869
|
this.changeIndex = changeIndex;
|
|
2859
2870
|
this.detail = detail;
|
|
2871
|
+
this.name = "WorkspaceEditValidationError";
|
|
2860
2872
|
}
|
|
2861
2873
|
}
|
|
2862
2874
|
|
|
@@ -3354,10 +3366,9 @@ function simulateDelete(operation, virtual) {
|
|
|
3354
3366
|
import { existsSync as existsSync6, lstatSync as lstatSync4, readdirSync as readdirSync2 } from "node:fs";
|
|
3355
3367
|
import { dirname as dirname6, resolve as resolve5 } from "node:path";
|
|
3356
3368
|
class WorkspaceSnapshotBuilder {
|
|
3357
|
-
workspaceRoot;
|
|
3358
|
-
snapshots = new Map;
|
|
3359
3369
|
constructor(workspaceRoot) {
|
|
3360
3370
|
this.workspaceRoot = workspaceRoot;
|
|
3371
|
+
this.snapshots = new Map;
|
|
3361
3372
|
}
|
|
3362
3373
|
build(operations) {
|
|
3363
3374
|
this.add(this.workspaceRoot, false);
|
|
@@ -3401,8 +3412,10 @@ function snapshotOperations(operations, workspaceRoot) {
|
|
|
3401
3412
|
|
|
3402
3413
|
// ../lsp-core/src/lsp/workspace-edit-plan.ts
|
|
3403
3414
|
class PlanPathIndex {
|
|
3404
|
-
|
|
3405
|
-
|
|
3415
|
+
constructor() {
|
|
3416
|
+
this.firstChangeByPath = new Map;
|
|
3417
|
+
this.reportedPathByCanonical = new Map;
|
|
3418
|
+
}
|
|
3406
3419
|
build(operations) {
|
|
3407
3420
|
for (const operation of operations) {
|
|
3408
3421
|
switch (operation.kind) {
|
|
@@ -3491,14 +3504,11 @@ function isRecord4(value) {
|
|
|
3491
3504
|
}
|
|
3492
3505
|
|
|
3493
3506
|
class WorkspaceMutationController {
|
|
3494
|
-
workspaceRoot;
|
|
3495
|
-
documents;
|
|
3496
|
-
activeLease = null;
|
|
3497
|
-
nextLeaseId = 1;
|
|
3498
|
-
io;
|
|
3499
3507
|
constructor(workspaceRoot, documents) {
|
|
3500
3508
|
this.workspaceRoot = workspaceRoot;
|
|
3501
3509
|
this.documents = documents;
|
|
3510
|
+
this.activeLease = null;
|
|
3511
|
+
this.nextLeaseId = 1;
|
|
3502
3512
|
}
|
|
3503
3513
|
setIo(io) {
|
|
3504
3514
|
this.io = io;
|
|
@@ -3611,12 +3621,9 @@ var DIAGNOSTICS_FRESHNESS_TIMEOUT_MS = 3000;
|
|
|
3611
3621
|
var VERSIONLESS_PUBLISH_QUIESCENCE_MS = 250;
|
|
3612
3622
|
|
|
3613
3623
|
class LspClient extends LspClientConnection {
|
|
3614
|
-
diagnosticPullErrors = [];
|
|
3615
|
-
documents;
|
|
3616
|
-
workspaceMutations;
|
|
3617
|
-
diagnosticsFreshnessTimeoutMs;
|
|
3618
3624
|
constructor(root, server2, options = {}) {
|
|
3619
3625
|
super(root, server2, options);
|
|
3626
|
+
this.diagnosticPullErrors = [];
|
|
3620
3627
|
this.diagnosticsFreshnessTimeoutMs = options.diagnosticsFreshnessTimeoutMs ?? DIAGNOSTICS_FRESHNESS_TIMEOUT_MS;
|
|
3621
3628
|
this.documents = new WorkspaceDocumentState((method, params) => this.sendNotification(method, params), (uri) => this.diagnosticsStore.delete(uri), {
|
|
3622
3629
|
versionlessPublishQuiescenceMs: options.versionlessPublishQuiescenceMs ?? VERSIONLESS_PUBLISH_QUIESCENCE_MS
|
|
@@ -3671,6 +3678,18 @@ class LspClient extends LspClientConnection {
|
|
|
3671
3678
|
textDocument: { uri: pathToFileURL3(absPath).href }
|
|
3672
3679
|
}, options);
|
|
3673
3680
|
}
|
|
3681
|
+
async formatDocument(filePath, options, signal) {
|
|
3682
|
+
if (!this.isDocumentFormattingSupported())
|
|
3683
|
+
return null;
|
|
3684
|
+
const absPath = this.resolveWorkspacePath(filePath);
|
|
3685
|
+
await this.openFile(absPath);
|
|
3686
|
+
const requestOptions = signal === undefined ? {} : { signal };
|
|
3687
|
+
const edits = await this.sendRequest("textDocument/formatting", {
|
|
3688
|
+
textDocument: { uri: pathToFileURL3(absPath).href },
|
|
3689
|
+
options
|
|
3690
|
+
}, requestOptions);
|
|
3691
|
+
return edits ?? [];
|
|
3692
|
+
}
|
|
3674
3693
|
async workspaceSymbols(query, signal) {
|
|
3675
3694
|
const options = signal === undefined ? {} : { signal };
|
|
3676
3695
|
return this.sendRequest("workspace/symbol", { query }, options);
|
|
@@ -3916,18 +3935,16 @@ function awaitWithSignal2(promise, signal) {
|
|
|
3916
3935
|
}
|
|
3917
3936
|
|
|
3918
3937
|
class LspManager {
|
|
3919
|
-
clients = new Map;
|
|
3920
|
-
reaperHandle = null;
|
|
3921
|
-
signalDisposer = null;
|
|
3922
|
-
disposed = false;
|
|
3923
|
-
idleTimeoutMs;
|
|
3924
|
-
initTimeoutMs;
|
|
3925
|
-
reaperIntervalMs;
|
|
3926
|
-
clientFactory;
|
|
3927
|
-
now;
|
|
3928
3938
|
constructor(options = {}) {
|
|
3939
|
+
this.clients = new Map;
|
|
3940
|
+
this.pendingStops = new Map;
|
|
3941
|
+
this.respawnBudgets = new Map;
|
|
3942
|
+
this.reaperHandle = null;
|
|
3943
|
+
this.signalDisposer = null;
|
|
3944
|
+
this.disposed = false;
|
|
3929
3945
|
this.idleTimeoutMs = options.idleTimeoutMs ?? IDLE_TIMEOUT_MS;
|
|
3930
3946
|
this.initTimeoutMs = options.initTimeoutMs ?? INIT_TIMEOUT_MS;
|
|
3947
|
+
this.maxResidentClients = options.maxResidentClients ?? MAX_RESIDENT_CLIENTS;
|
|
3931
3948
|
this.reaperIntervalMs = options.reaperIntervalMs ?? REAPER_INTERVAL_MS;
|
|
3932
3949
|
this.clientFactory = options.clientFactory ?? ((root, server2) => new LspClient(root, server2));
|
|
3933
3950
|
this.now = options.now ?? (() => Date.now());
|
|
@@ -3947,24 +3964,79 @@ class LspManager {
|
|
|
3947
3964
|
getKey(root, serverId) {
|
|
3948
3965
|
return `${root}::${serverId}`;
|
|
3949
3966
|
}
|
|
3967
|
+
tombstoneStop(key, client) {
|
|
3968
|
+
const stop = stopClientBestEffort(client);
|
|
3969
|
+
this.pendingStops.set(key, stop);
|
|
3970
|
+
stop.finally(() => {
|
|
3971
|
+
if (this.pendingStops.get(key) === stop) {
|
|
3972
|
+
this.pendingStops.delete(key);
|
|
3973
|
+
}
|
|
3974
|
+
});
|
|
3975
|
+
return stop;
|
|
3976
|
+
}
|
|
3977
|
+
recordDeadGeneration(key) {
|
|
3978
|
+
let budget = this.respawnBudgets.get(key);
|
|
3979
|
+
if (budget === undefined) {
|
|
3980
|
+
budget = { deadGenerations: 0, exhaustedAt: null };
|
|
3981
|
+
this.respawnBudgets.set(key, budget);
|
|
3982
|
+
}
|
|
3983
|
+
budget.deadGenerations += 1;
|
|
3984
|
+
}
|
|
3985
|
+
markHealthyGeneration(key) {
|
|
3986
|
+
this.respawnBudgets.delete(key);
|
|
3987
|
+
}
|
|
3988
|
+
ensureRespawnAllowed(key, root, serverId) {
|
|
3989
|
+
const budget = this.respawnBudgets.get(key);
|
|
3990
|
+
if (budget === undefined || budget.deadGenerations < CLIENT_RESPAWN_RETRY_LIMIT)
|
|
3991
|
+
return;
|
|
3992
|
+
if (budget.exhaustedAt === null) {
|
|
3993
|
+
budget.exhaustedAt = this.now();
|
|
3994
|
+
throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
|
|
3995
|
+
}
|
|
3996
|
+
if (this.now() - budget.exhaustedAt < CLIENT_RESPAWN_COOLDOWN_MS) {
|
|
3997
|
+
throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
|
|
3998
|
+
}
|
|
3999
|
+
budget.deadGenerations = 0;
|
|
4000
|
+
budget.exhaustedAt = null;
|
|
4001
|
+
}
|
|
3950
4002
|
reapStale() {
|
|
3951
4003
|
const t = this.now();
|
|
3952
4004
|
for (const [key, managed] of this.clients) {
|
|
3953
4005
|
if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
|
|
3954
|
-
stopClientBestEffort(managed.client);
|
|
3955
4006
|
this.clients.delete(key);
|
|
4007
|
+
this.tombstoneStop(key, managed.client);
|
|
3956
4008
|
continue;
|
|
3957
4009
|
}
|
|
3958
4010
|
if (!managed.isInitializing && managed.refCount === 0 && managed.pendingWaiters === 0 && t - managed.lastUsedAt > this.idleTimeoutMs) {
|
|
3959
|
-
stopClientBestEffort(managed.client);
|
|
3960
4011
|
this.clients.delete(key);
|
|
4012
|
+
this.tombstoneStop(key, managed.client);
|
|
4013
|
+
}
|
|
4014
|
+
}
|
|
4015
|
+
}
|
|
4016
|
+
evictForAdmission() {
|
|
4017
|
+
while (this.clients.size >= this.maxResidentClients) {
|
|
4018
|
+
const victim = this.leastRecentlyUsedIdleClient();
|
|
4019
|
+
if (!victim)
|
|
4020
|
+
return;
|
|
4021
|
+
this.clients.delete(victim.key);
|
|
4022
|
+
this.tombstoneStop(victim.key, victim.managed.client);
|
|
4023
|
+
}
|
|
4024
|
+
}
|
|
4025
|
+
leastRecentlyUsedIdleClient() {
|
|
4026
|
+
let candidate = null;
|
|
4027
|
+
for (const [key, managed] of this.clients) {
|
|
4028
|
+
if (managed.refCount > 0 || managed.pendingWaiters > 0 || managed.isInitializing)
|
|
4029
|
+
continue;
|
|
4030
|
+
if (candidate === null || managed.lastUsedAt < candidate.managed.lastUsedAt) {
|
|
4031
|
+
candidate = { key, managed };
|
|
3961
4032
|
}
|
|
3962
4033
|
}
|
|
4034
|
+
return candidate;
|
|
3963
4035
|
}
|
|
3964
4036
|
async tryDeleteIfOrphaned(key, managed) {
|
|
3965
4037
|
if (managed.refCount === 0 && managed.pendingWaiters === 0 && !managed.isInitializing && this.clients.get(key) === managed) {
|
|
3966
4038
|
this.clients.delete(key);
|
|
3967
|
-
await
|
|
4039
|
+
await this.tombstoneStop(key, managed.client);
|
|
3968
4040
|
}
|
|
3969
4041
|
}
|
|
3970
4042
|
async getClient(root, server2, signal) {
|
|
@@ -3973,12 +4045,22 @@ class LspManager {
|
|
|
3973
4045
|
}
|
|
3974
4046
|
signal?.throwIfAborted();
|
|
3975
4047
|
const key = this.getKey(root, server2.id);
|
|
4048
|
+
for (;; ) {
|
|
4049
|
+
const pendingStop = this.pendingStops.get(key);
|
|
4050
|
+
if (pendingStop === undefined)
|
|
4051
|
+
break;
|
|
4052
|
+
await awaitWithSignal2(pendingStop, signal);
|
|
4053
|
+
signal?.throwIfAborted();
|
|
4054
|
+
}
|
|
4055
|
+
if (this.disposed) {
|
|
4056
|
+
throw new Error("LspManager has been disposed");
|
|
4057
|
+
}
|
|
3976
4058
|
let managed = this.clients.get(key);
|
|
3977
4059
|
if (managed) {
|
|
3978
4060
|
const t = this.now();
|
|
3979
4061
|
if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
|
|
3980
|
-
await stopClientBestEffort(managed.client);
|
|
3981
4062
|
this.clients.delete(key);
|
|
4063
|
+
await this.tombstoneStop(key, managed.client);
|
|
3982
4064
|
managed = undefined;
|
|
3983
4065
|
}
|
|
3984
4066
|
}
|
|
@@ -3999,14 +4081,20 @@ class LspManager {
|
|
|
3999
4081
|
signal.throwIfAborted();
|
|
4000
4082
|
}
|
|
4001
4083
|
if (!managed.client.isAlive()) {
|
|
4002
|
-
|
|
4003
|
-
this.clients.
|
|
4084
|
+
this.recordDeadGeneration(key);
|
|
4085
|
+
if (this.clients.get(key) === managed) {
|
|
4086
|
+
this.clients.delete(key);
|
|
4087
|
+
}
|
|
4088
|
+
await this.tombstoneStop(key, managed.client);
|
|
4004
4089
|
return this.getClient(root, server2, signal);
|
|
4005
4090
|
}
|
|
4091
|
+
this.markHealthyGeneration(key);
|
|
4006
4092
|
managed.refCount++;
|
|
4007
4093
|
managed.lastUsedAt = this.now();
|
|
4008
4094
|
return managed.client;
|
|
4009
4095
|
}
|
|
4096
|
+
this.evictForAdmission();
|
|
4097
|
+
this.ensureRespawnAllowed(key, root, server2.id);
|
|
4010
4098
|
const client = this.clientFactory(root, server2);
|
|
4011
4099
|
const initStartedAt = this.now();
|
|
4012
4100
|
const initPromise = (async () => {
|
|
@@ -4030,7 +4118,7 @@ class LspManager {
|
|
|
4030
4118
|
if (this.clients.get(key) === newManaged) {
|
|
4031
4119
|
this.clients.delete(key);
|
|
4032
4120
|
}
|
|
4033
|
-
await
|
|
4121
|
+
await this.tombstoneStop(key, client);
|
|
4034
4122
|
throw err;
|
|
4035
4123
|
}
|
|
4036
4124
|
newManaged.pendingWaiters--;
|
|
@@ -4041,6 +4129,15 @@ class LspManager {
|
|
|
4041
4129
|
await this.tryDeleteIfOrphaned(key, newManaged);
|
|
4042
4130
|
signal.throwIfAborted();
|
|
4043
4131
|
}
|
|
4132
|
+
if (!client.isAlive()) {
|
|
4133
|
+
this.recordDeadGeneration(key);
|
|
4134
|
+
if (this.clients.get(key) === newManaged) {
|
|
4135
|
+
this.clients.delete(key);
|
|
4136
|
+
}
|
|
4137
|
+
await this.tombstoneStop(key, client);
|
|
4138
|
+
return this.getClient(root, server2, signal);
|
|
4139
|
+
}
|
|
4140
|
+
this.markHealthyGeneration(key);
|
|
4044
4141
|
newManaged.refCount++;
|
|
4045
4142
|
newManaged.lastUsedAt = this.now();
|
|
4046
4143
|
return client;
|
|
@@ -4061,14 +4158,20 @@ class LspManager {
|
|
|
4061
4158
|
if (client && managed.client !== client)
|
|
4062
4159
|
return;
|
|
4063
4160
|
this.clients.delete(key);
|
|
4064
|
-
|
|
4161
|
+
this.tombstoneStop(key, managed.client);
|
|
4065
4162
|
}
|
|
4066
4163
|
warmupClient(root, server2) {
|
|
4067
4164
|
if (this.disposed)
|
|
4068
4165
|
return;
|
|
4069
4166
|
const key = this.getKey(root, server2.id);
|
|
4070
|
-
if (this.clients.has(key))
|
|
4167
|
+
if (this.clients.has(key) || this.pendingStops.has(key))
|
|
4071
4168
|
return;
|
|
4169
|
+
this.evictForAdmission();
|
|
4170
|
+
try {
|
|
4171
|
+
this.ensureRespawnAllowed(key, root, server2.id);
|
|
4172
|
+
} catch {
|
|
4173
|
+
return;
|
|
4174
|
+
}
|
|
4072
4175
|
const client = this.clientFactory(root, server2);
|
|
4073
4176
|
const initStartedAt = this.now();
|
|
4074
4177
|
const initPromise = (async () => {
|
|
@@ -4094,7 +4197,7 @@ class LspManager {
|
|
|
4094
4197
|
if (this.clients.get(key) === managed) {
|
|
4095
4198
|
this.clients.delete(key);
|
|
4096
4199
|
}
|
|
4097
|
-
|
|
4200
|
+
this.tombstoneStop(key, client);
|
|
4098
4201
|
});
|
|
4099
4202
|
}
|
|
4100
4203
|
isServerInitializing(root, serverId) {
|
|
@@ -4138,8 +4241,11 @@ class LspManager {
|
|
|
4138
4241
|
for (const managed of this.clients.values()) {
|
|
4139
4242
|
stopPromises.push(stopClientBestEffort(managed.client));
|
|
4140
4243
|
}
|
|
4244
|
+
const tombstonedStops = [...this.pendingStops.values()];
|
|
4141
4245
|
this.clients.clear();
|
|
4142
|
-
|
|
4246
|
+
this.respawnBudgets.clear();
|
|
4247
|
+
await Promise.allSettled([...stopPromises, ...tombstonedStops]);
|
|
4248
|
+
this.pendingStops.clear();
|
|
4143
4249
|
}
|
|
4144
4250
|
}
|
|
4145
4251
|
var _defaultInstance = null;
|
|
@@ -4157,57 +4263,52 @@ async function disposeDefaultLspManager() {
|
|
|
4157
4263
|
}
|
|
4158
4264
|
}
|
|
4159
4265
|
|
|
4160
|
-
// ../lsp-core/src/lsp/
|
|
4161
|
-
import { existsSync as existsSync7,
|
|
4162
|
-
import { dirname as dirname7 } from "node:path";
|
|
4163
|
-
|
|
4164
|
-
|
|
4165
|
-
|
|
4166
|
-
|
|
4167
|
-
|
|
4168
|
-
|
|
4169
|
-
|
|
4170
|
-
|
|
4171
|
-
|
|
4172
|
-
|
|
4173
|
-
|
|
4174
|
-
|
|
4266
|
+
// ../lsp-core/src/lsp/outside-context-workspace.ts
|
|
4267
|
+
import { existsSync as existsSync7, realpathSync as realpathSync4 } from "node:fs";
|
|
4268
|
+
import { dirname as dirname7, join as join3 } from "node:path";
|
|
4269
|
+
|
|
4270
|
+
// ../lsp-core/src/lsp/workspace-markers.ts
|
|
4271
|
+
var GIT_WORKSPACE_MARKER = ".git";
|
|
4272
|
+
var PROJECT_WORKSPACE_MARKERS = [
|
|
4273
|
+
"package.json",
|
|
4274
|
+
"pyproject.toml",
|
|
4275
|
+
"Cargo.toml",
|
|
4276
|
+
"go.mod",
|
|
4277
|
+
"pom.xml",
|
|
4278
|
+
"build.gradle"
|
|
4279
|
+
];
|
|
4280
|
+
var WORKSPACE_MARKERS = [GIT_WORKSPACE_MARKER, ...PROJECT_WORKSPACE_MARKERS];
|
|
4281
|
+
|
|
4282
|
+
// ../lsp-core/src/lsp/outside-context-workspace.ts
|
|
4283
|
+
function findWorkspaceRootOutsideContext(directory) {
|
|
4284
|
+
const marked = nearestMarkedAncestor(directory);
|
|
4285
|
+
if (marked !== undefined)
|
|
4286
|
+
return marked;
|
|
4287
|
+
return realpathSync4(nearestExistingAncestor(directory));
|
|
4288
|
+
}
|
|
4289
|
+
function nearestMarkedAncestor(directory) {
|
|
4290
|
+
let current = directory;
|
|
4291
|
+
for (;; ) {
|
|
4292
|
+
if (existsSync7(current) && WORKSPACE_MARKERS.some((marker) => existsSync7(join3(current, marker)))) {
|
|
4293
|
+
return realpathSync4(current);
|
|
4294
|
+
}
|
|
4295
|
+
const parent = dirname7(current);
|
|
4296
|
+
if (parent === current)
|
|
4297
|
+
return;
|
|
4298
|
+
current = parent;
|
|
4175
4299
|
}
|
|
4176
4300
|
}
|
|
4177
|
-
function
|
|
4178
|
-
|
|
4179
|
-
|
|
4180
|
-
|
|
4181
|
-
|
|
4182
|
-
|
|
4183
|
-
|
|
4184
|
-
}
|
|
4185
|
-
|
|
4186
|
-
return value === "declined" || value === "allowed";
|
|
4187
|
-
}
|
|
4188
|
-
function writeInstallDecisions(decisions) {
|
|
4189
|
-
const path2 = getInstallDecisionsPath();
|
|
4190
|
-
mkdirSync3(dirname7(path2), { recursive: true });
|
|
4191
|
-
const tmpPath = `${path2}.tmp`;
|
|
4192
|
-
writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
|
|
4193
|
-
`, "utf8");
|
|
4194
|
-
renameSync2(tmpPath, path2);
|
|
4195
|
-
}
|
|
4196
|
-
function isInstallDecisions(value) {
|
|
4197
|
-
return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
|
|
4198
|
-
}
|
|
4199
|
-
function isInstallDecisionRecord(value) {
|
|
4200
|
-
if (!isRecord5(value))
|
|
4201
|
-
return false;
|
|
4202
|
-
return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
|
|
4203
|
-
}
|
|
4204
|
-
function isRecord5(value) {
|
|
4205
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4301
|
+
function nearestExistingAncestor(directory) {
|
|
4302
|
+
let current = directory;
|
|
4303
|
+
while (!existsSync7(current)) {
|
|
4304
|
+
const parent = dirname7(current);
|
|
4305
|
+
if (parent === current)
|
|
4306
|
+
return current;
|
|
4307
|
+
current = parent;
|
|
4308
|
+
}
|
|
4309
|
+
return current;
|
|
4206
4310
|
}
|
|
4207
4311
|
|
|
4208
|
-
// ../lsp-core/src/lsp/config-loader.ts
|
|
4209
|
-
import { existsSync as existsSync8, readFileSync as readFileSync5 } from "node:fs";
|
|
4210
|
-
|
|
4211
4312
|
// ../lsp-core/src/lsp/server-definitions.ts
|
|
4212
4313
|
var LSP_INSTALL_HINTS = {
|
|
4213
4314
|
typescript: "npm install -g typescript-language-server typescript",
|
|
@@ -4253,6 +4354,26 @@ var LSP_INSTALL_HINTS = {
|
|
|
4253
4354
|
julials: `julia -e 'using Pkg; Pkg.add("LanguageServer")'`,
|
|
4254
4355
|
razor: "Razor runs through the Roslyn language server (cohosting). " + "Install: dotnet tool install -g roslyn-language-server --prerelease (requires v5.8.0+). See https://github.com/dotnet/razor"
|
|
4255
4356
|
};
|
|
4357
|
+
var LSP_LOCAL_INSTALL_HINTS = {
|
|
4358
|
+
typescript: "bun add -d typescript-language-server typescript",
|
|
4359
|
+
vue: "bun add -d @vue/language-server",
|
|
4360
|
+
eslint: "bun add -d vscode-langservers-extracted",
|
|
4361
|
+
oxlint: "bun add -d oxlint",
|
|
4362
|
+
biome: "bun add -d @biomejs/biome",
|
|
4363
|
+
svelte: "bun add -d svelte-language-server",
|
|
4364
|
+
astro: "bun add -d @astrojs/language-server",
|
|
4365
|
+
bash: "bun add -d bash-language-server",
|
|
4366
|
+
"bash-ls": "bun add -d bash-language-server",
|
|
4367
|
+
"yaml-ls": "bun add -d yaml-language-server",
|
|
4368
|
+
php: "bun add -d intelephense",
|
|
4369
|
+
prisma: "bun add -d prisma",
|
|
4370
|
+
dockerfile: "bun add -d dockerfile-language-server-nodejs",
|
|
4371
|
+
pyright: "uv add --dev pyright",
|
|
4372
|
+
basedpyright: "uv add --dev basedpyright",
|
|
4373
|
+
ruff: "uv add --dev ruff",
|
|
4374
|
+
ty: "uv add --dev ty",
|
|
4375
|
+
"ruby-lsp": "bundle add ruby-lsp --group development"
|
|
4376
|
+
};
|
|
4256
4377
|
var BUILTIN_SERVERS = {
|
|
4257
4378
|
typescript: {
|
|
4258
4379
|
command: ["typescript-language-server", "--stdio"],
|
|
@@ -4355,7 +4476,56 @@ var BUILTIN_SERVERS = {
|
|
|
4355
4476
|
}
|
|
4356
4477
|
};
|
|
4357
4478
|
|
|
4479
|
+
// ../lsp-core/src/lsp/server-install-state.ts
|
|
4480
|
+
import { existsSync as existsSync8, mkdirSync as mkdirSync3, readFileSync as readFileSync4, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
4481
|
+
import { dirname as dirname8 } from "node:path";
|
|
4482
|
+
function getInstallDecisionsPath() {
|
|
4483
|
+
return lspRequestContext().installDecisionsPath;
|
|
4484
|
+
}
|
|
4485
|
+
function loadInstallDecisions() {
|
|
4486
|
+
const path2 = getInstallDecisionsPath();
|
|
4487
|
+
if (!existsSync8(path2))
|
|
4488
|
+
return {};
|
|
4489
|
+
try {
|
|
4490
|
+
const parsed = JSON.parse(readFileSync4(path2, "utf8"));
|
|
4491
|
+
return isInstallDecisions(parsed) ? parsed : {};
|
|
4492
|
+
} catch {
|
|
4493
|
+
return {};
|
|
4494
|
+
}
|
|
4495
|
+
}
|
|
4496
|
+
function loadInstallDecision(serverId) {
|
|
4497
|
+
return loadInstallDecisions()[serverId];
|
|
4498
|
+
}
|
|
4499
|
+
function recordInstallDecision(serverId, decision, decidedAt = new Date().toISOString()) {
|
|
4500
|
+
const decisions = loadInstallDecisions();
|
|
4501
|
+
decisions[serverId] = { decision, decidedAt };
|
|
4502
|
+
writeInstallDecisions(decisions);
|
|
4503
|
+
}
|
|
4504
|
+
function isInstallDecision(value) {
|
|
4505
|
+
return value === "declined" || value === "allowed";
|
|
4506
|
+
}
|
|
4507
|
+
function writeInstallDecisions(decisions) {
|
|
4508
|
+
const path2 = getInstallDecisionsPath();
|
|
4509
|
+
mkdirSync3(dirname8(path2), { recursive: true });
|
|
4510
|
+
const tmpPath = `${path2}.tmp`;
|
|
4511
|
+
writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
|
|
4512
|
+
`, "utf8");
|
|
4513
|
+
renameSync2(tmpPath, path2);
|
|
4514
|
+
}
|
|
4515
|
+
function isInstallDecisions(value) {
|
|
4516
|
+
return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
|
|
4517
|
+
}
|
|
4518
|
+
function isInstallDecisionRecord(value) {
|
|
4519
|
+
if (!isRecord5(value))
|
|
4520
|
+
return false;
|
|
4521
|
+
return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
|
|
4522
|
+
}
|
|
4523
|
+
function isRecord5(value) {
|
|
4524
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4525
|
+
}
|
|
4526
|
+
|
|
4358
4527
|
// ../lsp-core/src/lsp/config-loader.ts
|
|
4528
|
+
import { existsSync as existsSync9, readFileSync as readFileSync5 } from "node:fs";
|
|
4359
4529
|
function getProjectConfigPaths() {
|
|
4360
4530
|
return lspRequestContext().projectConfigPaths;
|
|
4361
4531
|
}
|
|
@@ -4363,7 +4533,7 @@ function getUserConfigPath() {
|
|
|
4363
4533
|
return lspRequestContext().userConfigPath;
|
|
4364
4534
|
}
|
|
4365
4535
|
function loadJsonFile(path2) {
|
|
4366
|
-
if (!
|
|
4536
|
+
if (!existsSync9(path2))
|
|
4367
4537
|
return null;
|
|
4368
4538
|
try {
|
|
4369
4539
|
const parsed = JSON.parse(readFileSync5(path2, "utf-8"));
|
|
@@ -4551,54 +4721,155 @@ function getDisabledServerIds() {
|
|
|
4551
4721
|
}
|
|
4552
4722
|
|
|
4553
4723
|
// ../lsp-core/src/lsp/server-installation.ts
|
|
4554
|
-
import { existsSync as
|
|
4555
|
-
import { delimiter as delimiter3, join as
|
|
4556
|
-
|
|
4557
|
-
|
|
4558
|
-
|
|
4559
|
-
|
|
4560
|
-
|
|
4561
|
-
|
|
4562
|
-
|
|
4563
|
-
|
|
4564
|
-
|
|
4724
|
+
import { existsSync as existsSync10 } from "node:fs";
|
|
4725
|
+
import { delimiter as delimiter3, dirname as dirname9, isAbsolute as isAbsolute5, join as join4, resolve as resolve7 } from "node:path";
|
|
4726
|
+
var LOCAL_BIN_RULES = [
|
|
4727
|
+
{
|
|
4728
|
+
markers: ["package.json", "bun.lock", "bun.lockb", "package-lock.json", "yarn.lock", "pnpm-lock.yaml"],
|
|
4729
|
+
binDirs: [join4("node_modules", ".bin")]
|
|
4730
|
+
},
|
|
4731
|
+
{
|
|
4732
|
+
markers: [
|
|
4733
|
+
"pyproject.toml",
|
|
4734
|
+
"ty.toml",
|
|
4735
|
+
"requirements.txt",
|
|
4736
|
+
"setup.py",
|
|
4737
|
+
"setup.cfg",
|
|
4738
|
+
"Pipfile",
|
|
4739
|
+
"pyrightconfig.json",
|
|
4740
|
+
"ruff.toml",
|
|
4741
|
+
".ruff.toml"
|
|
4742
|
+
],
|
|
4743
|
+
binDirs: [
|
|
4744
|
+
join4(".venv", "bin"),
|
|
4745
|
+
join4(".venv", "Scripts"),
|
|
4746
|
+
join4("venv", "bin"),
|
|
4747
|
+
join4("venv", "Scripts"),
|
|
4748
|
+
join4(".env", "bin"),
|
|
4749
|
+
join4(".env", "Scripts")
|
|
4750
|
+
]
|
|
4751
|
+
},
|
|
4752
|
+
{
|
|
4753
|
+
markers: ["Gemfile", "Gemfile.lock"],
|
|
4754
|
+
binDirs: [join4("vendor", "bundle", "bin"), "bin"]
|
|
4755
|
+
},
|
|
4756
|
+
{
|
|
4757
|
+
markers: ["go.mod", "go.sum", "go.work"],
|
|
4758
|
+
binDirs: ["bin"]
|
|
4565
4759
|
}
|
|
4566
|
-
|
|
4567
|
-
|
|
4568
|
-
|
|
4569
|
-
|
|
4570
|
-
|
|
4571
|
-
|
|
4572
|
-
|
|
4573
|
-
|
|
4574
|
-
|
|
4760
|
+
];
|
|
4761
|
+
var resolutionCache = new Map;
|
|
4762
|
+
var probeCount = 0;
|
|
4763
|
+
function probe(path2) {
|
|
4764
|
+
probeCount += 1;
|
|
4765
|
+
return existsSync10(path2);
|
|
4766
|
+
}
|
|
4767
|
+
function executableSuffixes(platform, pathExt) {
|
|
4768
|
+
if (platform !== "win32")
|
|
4769
|
+
return [""];
|
|
4770
|
+
const configured = pathExt ?? process.env["PATHEXT"] ?? "";
|
|
4771
|
+
const systemExts = configured.split(";").filter((entry) => entry.length > 0).map((entry) => entry.toLowerCase());
|
|
4772
|
+
return [...new Set(["", ...systemExts, ".exe", ".cmd", ".bat", ".ps1"])];
|
|
4773
|
+
}
|
|
4774
|
+
function probeWithSuffixes(directory, command, suffixes) {
|
|
4775
|
+
for (const suffix of suffixes) {
|
|
4776
|
+
const candidate = join4(directory, command + suffix);
|
|
4777
|
+
if (probe(candidate))
|
|
4778
|
+
return candidate;
|
|
4779
|
+
}
|
|
4780
|
+
return null;
|
|
4781
|
+
}
|
|
4782
|
+
function resolveLocal(command, workingDirectory, suffixes, stopAt) {
|
|
4783
|
+
const boundary = stopAt === undefined ? undefined : resolve7(stopAt);
|
|
4784
|
+
let current = resolve7(workingDirectory);
|
|
4785
|
+
while (true) {
|
|
4786
|
+
for (const rule of LOCAL_BIN_RULES) {
|
|
4787
|
+
if (!rule.markers.some((marker) => probe(join4(current, marker))))
|
|
4788
|
+
continue;
|
|
4789
|
+
for (const binDir of rule.binDirs) {
|
|
4790
|
+
const found = probeWithSuffixes(join4(current, binDir), command, suffixes);
|
|
4791
|
+
if (found !== null)
|
|
4792
|
+
return found;
|
|
4793
|
+
}
|
|
4575
4794
|
}
|
|
4795
|
+
if (probe(join4(current, ".git")))
|
|
4796
|
+
return null;
|
|
4797
|
+
if (boundary !== undefined && current === boundary)
|
|
4798
|
+
return null;
|
|
4799
|
+
const parent = dirname9(current);
|
|
4800
|
+
if (parent === current)
|
|
4801
|
+
return null;
|
|
4802
|
+
current = parent;
|
|
4576
4803
|
}
|
|
4577
|
-
|
|
4578
|
-
|
|
4804
|
+
}
|
|
4805
|
+
function resolveFromPath(command, suffixes, platform, pathEnvOverride) {
|
|
4806
|
+
let pathEnv = pathEnvOverride ?? process.env["PATH"] ?? "";
|
|
4807
|
+
if (platform === "win32" && !pathEnv) {
|
|
4579
4808
|
pathEnv = process.env["Path"] ?? "";
|
|
4580
4809
|
}
|
|
4581
|
-
const
|
|
4582
|
-
|
|
4583
|
-
|
|
4584
|
-
|
|
4585
|
-
|
|
4586
|
-
|
|
4587
|
-
}
|
|
4810
|
+
for (const entry of pathEnv.split(delimiter3)) {
|
|
4811
|
+
if (entry.length === 0)
|
|
4812
|
+
continue;
|
|
4813
|
+
const found = probeWithSuffixes(entry, command, suffixes);
|
|
4814
|
+
if (found !== null)
|
|
4815
|
+
return found;
|
|
4588
4816
|
}
|
|
4589
|
-
|
|
4590
|
-
|
|
4591
|
-
|
|
4817
|
+
return null;
|
|
4818
|
+
}
|
|
4819
|
+
function resolveServerBinary(command, workingDirectory, options = {}) {
|
|
4820
|
+
if (command.length === 0)
|
|
4821
|
+
return null;
|
|
4822
|
+
const [cmd] = command;
|
|
4823
|
+
if (cmd === undefined || cmd.length === 0)
|
|
4824
|
+
return null;
|
|
4825
|
+
const platform = options.platform ?? process.platform;
|
|
4826
|
+
const suffixes = executableSuffixes(platform, options.pathExt);
|
|
4827
|
+
if (cmd.includes("/") || cmd.includes("\\")) {
|
|
4828
|
+
const explicit = isAbsolute5(cmd) ? cmd : resolve7(workingDirectory ?? process.cwd(), cmd);
|
|
4829
|
+
return probe(explicit) ? explicit : null;
|
|
4830
|
+
}
|
|
4831
|
+
const cacheKey = JSON.stringify([
|
|
4832
|
+
workingDirectory ?? "",
|
|
4833
|
+
cmd,
|
|
4834
|
+
platform,
|
|
4835
|
+
options.stopAt ?? "",
|
|
4836
|
+
options.pathExt ?? "",
|
|
4837
|
+
options.pathEnv ?? process.env["PATH"] ?? ""
|
|
4838
|
+
]);
|
|
4839
|
+
const cached = resolutionCache.get(cacheKey);
|
|
4840
|
+
if (cached !== undefined)
|
|
4841
|
+
return cached;
|
|
4842
|
+
let resolved = null;
|
|
4843
|
+
if (workingDirectory !== undefined && workingDirectory.length > 0) {
|
|
4844
|
+
resolved = resolveLocal(cmd, workingDirectory, suffixes, options.stopAt);
|
|
4845
|
+
}
|
|
4846
|
+
resolved ??= resolveFromPath(cmd, suffixes, platform, options.pathEnv);
|
|
4847
|
+
if (resolved === null && cmd === "node")
|
|
4848
|
+
resolved = cmd;
|
|
4849
|
+
resolutionCache.set(cacheKey, resolved);
|
|
4850
|
+
return resolved;
|
|
4851
|
+
}
|
|
4852
|
+
function isServerInstalled(command, workingDirectory, options = {}) {
|
|
4853
|
+
if (command.length === 0)
|
|
4854
|
+
return false;
|
|
4855
|
+
return resolveServerBinary(command, workingDirectory, options) !== null;
|
|
4592
4856
|
}
|
|
4593
4857
|
|
|
4594
4858
|
// ../lsp-core/src/lsp/server-resolution.ts
|
|
4859
|
+
function withResolvedCommand(command, binaryPath) {
|
|
4860
|
+
return [binaryPath, ...command.slice(1)];
|
|
4861
|
+
}
|
|
4595
4862
|
function findServerForExtension(ext) {
|
|
4596
4863
|
const servers = getMergedServers();
|
|
4864
|
+
const workingDirectory = contextCwd();
|
|
4597
4865
|
for (const server2 of servers) {
|
|
4598
|
-
if (server2.extensions.includes(ext)
|
|
4866
|
+
if (!server2.extensions.includes(ext))
|
|
4867
|
+
continue;
|
|
4868
|
+
const binaryPath = resolveServerBinary(server2.command, workingDirectory);
|
|
4869
|
+
if (binaryPath !== null) {
|
|
4599
4870
|
const resolvedServer = {
|
|
4600
4871
|
id: server2.id,
|
|
4601
|
-
command: server2.command,
|
|
4872
|
+
command: withResolvedCommand(server2.command, binaryPath),
|
|
4602
4873
|
extensions: server2.extensions,
|
|
4603
4874
|
priority: server2.priority
|
|
4604
4875
|
};
|
|
@@ -4645,6 +4916,7 @@ function findServerForExtension(ext) {
|
|
|
4645
4916
|
function getAllServers() {
|
|
4646
4917
|
const servers = getMergedServers();
|
|
4647
4918
|
const disabled = getDisabledServerIds();
|
|
4919
|
+
const workingDirectory = contextCwd();
|
|
4648
4920
|
const result = [];
|
|
4649
4921
|
const seen = new Set;
|
|
4650
4922
|
for (const server2 of servers) {
|
|
@@ -4652,7 +4924,7 @@ function getAllServers() {
|
|
|
4652
4924
|
continue;
|
|
4653
4925
|
result.push({
|
|
4654
4926
|
id: server2.id,
|
|
4655
|
-
installed: isServerInstalled(server2.command),
|
|
4927
|
+
installed: isServerInstalled(server2.command, workingDirectory),
|
|
4656
4928
|
extensions: server2.extensions,
|
|
4657
4929
|
disabled: false,
|
|
4658
4930
|
source: server2.source,
|
|
@@ -4666,7 +4938,7 @@ function getAllServers() {
|
|
|
4666
4938
|
const builtin = BUILTIN_SERVERS[id];
|
|
4667
4939
|
result.push({
|
|
4668
4940
|
id,
|
|
4669
|
-
installed: builtin ? isServerInstalled(builtin.command) : false,
|
|
4941
|
+
installed: builtin ? isServerInstalled(builtin.command, workingDirectory) : false,
|
|
4670
4942
|
extensions: builtin?.extensions ?? [],
|
|
4671
4943
|
disabled: true,
|
|
4672
4944
|
source: "disabled",
|
|
@@ -4677,7 +4949,6 @@ function getAllServers() {
|
|
|
4677
4949
|
}
|
|
4678
4950
|
|
|
4679
4951
|
// ../lsp-core/src/lsp/client-wrapper.ts
|
|
4680
|
-
var WORKSPACE_MARKERS = [".git", "package.json", "pyproject.toml", "Cargo.toml", "go.mod", "pom.xml", "build.gradle"];
|
|
4681
4952
|
function isDirectoryPath(filePath) {
|
|
4682
4953
|
try {
|
|
4683
4954
|
return statSync4(filePath).isDirectory();
|
|
@@ -4686,32 +4957,90 @@ function isDirectoryPath(filePath) {
|
|
|
4686
4957
|
}
|
|
4687
4958
|
}
|
|
4688
4959
|
function findWorkspaceRoot(filePath) {
|
|
4689
|
-
const
|
|
4960
|
+
const cwd = contextCwd();
|
|
4961
|
+
const abs = resolveReadablePathInsideContext(filePath);
|
|
4690
4962
|
let dir = abs;
|
|
4691
4963
|
if (!isDirectoryPath(dir)) {
|
|
4692
|
-
dir =
|
|
4693
|
-
}
|
|
4694
|
-
|
|
4695
|
-
|
|
4696
|
-
|
|
4697
|
-
|
|
4698
|
-
|
|
4964
|
+
dir = dirname10(dir);
|
|
4965
|
+
}
|
|
4966
|
+
if (!isPathInside(cwd, abs))
|
|
4967
|
+
return findWorkspaceRootOutsideContext(dir);
|
|
4968
|
+
const fallbackRoot = nearestExistingDirectoryInsideContext(dir, cwd) ?? cwd;
|
|
4969
|
+
let nearestPackageRoot;
|
|
4970
|
+
while (isPathInside(cwd, dir)) {
|
|
4971
|
+
const canonicalDir = existingDirectoryInsideContext(dir, cwd);
|
|
4972
|
+
if (canonicalDir !== undefined) {
|
|
4973
|
+
if (existsSync11(join5(dir, GIT_WORKSPACE_MARKER))) {
|
|
4974
|
+
return canonicalDir;
|
|
4975
|
+
}
|
|
4976
|
+
if (nearestPackageRoot === undefined && hasProjectWorkspaceMarker(dir)) {
|
|
4977
|
+
nearestPackageRoot = canonicalDir;
|
|
4699
4978
|
}
|
|
4700
4979
|
}
|
|
4701
|
-
|
|
4702
|
-
|
|
4980
|
+
if (dir === cwd)
|
|
4981
|
+
break;
|
|
4982
|
+
dir = dirname10(dir);
|
|
4703
4983
|
}
|
|
4704
|
-
return
|
|
4984
|
+
return nearestPackageRoot ?? fallbackRoot;
|
|
4985
|
+
}
|
|
4986
|
+
function hasProjectWorkspaceMarker(directory) {
|
|
4987
|
+
return PROJECT_WORKSPACE_MARKERS.some((marker) => existsSync11(join5(directory, marker)));
|
|
4988
|
+
}
|
|
4989
|
+
function resolveReadablePathInsideContext(filePath) {
|
|
4990
|
+
const cwd = contextCwd();
|
|
4991
|
+
const abs = resolve8(cwd, filePath);
|
|
4992
|
+
if (isPathInside(cwd, abs))
|
|
4993
|
+
return abs;
|
|
4994
|
+
const rebased = rebaseThroughCanonicalAncestor(abs, cwd);
|
|
4995
|
+
if (rebased !== undefined)
|
|
4996
|
+
return rebased;
|
|
4997
|
+
return canonicalizeExistingOrNearestAncestor(abs);
|
|
4705
4998
|
}
|
|
4706
4999
|
function resolvePathInsideContext(filePath) {
|
|
4707
5000
|
const cwd = contextCwd();
|
|
4708
|
-
const abs =
|
|
5001
|
+
const abs = resolveReadablePathInsideContext(filePath);
|
|
4709
5002
|
const canonical = canonicalizeExistingOrNearestAncestor(abs);
|
|
4710
5003
|
if (!isPathInside(cwd, canonical)) {
|
|
4711
5004
|
throw new LspInvalidPathError(`LSP file path must be inside request cwd: ${filePath}`);
|
|
4712
5005
|
}
|
|
4713
5006
|
return canonical;
|
|
4714
5007
|
}
|
|
5008
|
+
function rebaseThroughCanonicalAncestor(path2, cwd) {
|
|
5009
|
+
let current = path2;
|
|
5010
|
+
const suffix = [];
|
|
5011
|
+
while (true) {
|
|
5012
|
+
if (existsSync11(current)) {
|
|
5013
|
+
const canonical = realpathSync5(current);
|
|
5014
|
+
if (isPathInside(cwd, canonical))
|
|
5015
|
+
return suffix.length === 0 ? canonical : join5(canonical, ...suffix);
|
|
5016
|
+
}
|
|
5017
|
+
const parent = dirname10(current);
|
|
5018
|
+
if (parent === current)
|
|
5019
|
+
return;
|
|
5020
|
+
suffix.unshift(basename3(current));
|
|
5021
|
+
current = parent;
|
|
5022
|
+
}
|
|
5023
|
+
}
|
|
5024
|
+
function existingDirectoryInsideContext(directory, cwd) {
|
|
5025
|
+
if (!existsSync11(directory))
|
|
5026
|
+
return;
|
|
5027
|
+
const canonical = realpathSync5(directory);
|
|
5028
|
+
if (!statSync4(canonical).isDirectory())
|
|
5029
|
+
return;
|
|
5030
|
+
return isPathInside(cwd, canonical) ? canonical : undefined;
|
|
5031
|
+
}
|
|
5032
|
+
function nearestExistingDirectoryInsideContext(directory, cwd) {
|
|
5033
|
+
let current = directory;
|
|
5034
|
+
while (isPathInside(cwd, current)) {
|
|
5035
|
+
const canonical = existingDirectoryInsideContext(current, cwd);
|
|
5036
|
+
if (canonical !== undefined)
|
|
5037
|
+
return canonical;
|
|
5038
|
+
if (current === cwd)
|
|
5039
|
+
return;
|
|
5040
|
+
current = dirname10(current);
|
|
5041
|
+
}
|
|
5042
|
+
return;
|
|
5043
|
+
}
|
|
4715
5044
|
function formatServerLookupError(result) {
|
|
4716
5045
|
if (result.status === "not_installed") {
|
|
4717
5046
|
return formatNotInstalled(result);
|
|
@@ -4735,6 +5064,19 @@ function formatServerLookupError(result) {
|
|
|
4735
5064
|
].join(`
|
|
4736
5065
|
`);
|
|
4737
5066
|
}
|
|
5067
|
+
function formatInstallOptions(serverId, installHint) {
|
|
5068
|
+
const localHint = LSP_LOCAL_INSTALL_HINTS[serverId];
|
|
5069
|
+
if (localHint === undefined) {
|
|
5070
|
+
return ["To install, run:", ` ${installHint}`];
|
|
5071
|
+
}
|
|
5072
|
+
return [
|
|
5073
|
+
"To install in THIS repository (preferred — no global install needed):",
|
|
5074
|
+
` ${localHint}`,
|
|
5075
|
+
"",
|
|
5076
|
+
"Or install it globally:",
|
|
5077
|
+
` ${installHint}`
|
|
5078
|
+
];
|
|
5079
|
+
}
|
|
4738
5080
|
function formatNotInstalled(result) {
|
|
4739
5081
|
const { server: server2, installHint } = result;
|
|
4740
5082
|
const extensions = server2.extensions.join(", ");
|
|
@@ -4749,19 +5091,19 @@ function formatNotInstalled(result) {
|
|
|
4749
5091
|
`Command not found: ${server2.command[0]}`,
|
|
4750
5092
|
""
|
|
4751
5093
|
];
|
|
5094
|
+
const installOptions = formatInstallOptions(server2.id, installHint);
|
|
4752
5095
|
if (decision === "allowed") {
|
|
4753
5096
|
return [
|
|
4754
5097
|
...header,
|
|
4755
5098
|
"The user has pre-authorized LSP installation. Run the install command, then retry this tool:",
|
|
4756
|
-
|
|
5099
|
+
...installOptions.slice(1)
|
|
4757
5100
|
].join(`
|
|
4758
5101
|
`);
|
|
4759
5102
|
}
|
|
4760
5103
|
if (!context.capabilities.installDecisionTool) {
|
|
4761
5104
|
return [
|
|
4762
5105
|
...header,
|
|
4763
|
-
|
|
4764
|
-
` ${installHint}`,
|
|
5106
|
+
...installOptions,
|
|
4765
5107
|
"",
|
|
4766
5108
|
"ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
|
|
4767
5109
|
"Install-decision recording is unavailable in this harness; proceed without LSP if the user declines."
|
|
@@ -4770,8 +5112,7 @@ function formatNotInstalled(result) {
|
|
|
4770
5112
|
}
|
|
4771
5113
|
return [
|
|
4772
5114
|
...header,
|
|
4773
|
-
|
|
4774
|
-
` ${installHint}`,
|
|
5115
|
+
...installOptions,
|
|
4775
5116
|
"",
|
|
4776
5117
|
"ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
|
|
4777
5118
|
"- If the user agrees: run the install command above, then retry this tool.",
|
|
@@ -4782,7 +5123,7 @@ function formatNotInstalled(result) {
|
|
|
4782
5123
|
].join(`
|
|
4783
5124
|
`);
|
|
4784
5125
|
}
|
|
4785
|
-
var
|
|
5126
|
+
var READ_ONLY_TOOLS = new Set([
|
|
4786
5127
|
"diagnostics",
|
|
4787
5128
|
"definition",
|
|
4788
5129
|
"references",
|
|
@@ -4791,7 +5132,7 @@ var READ_ONLY_RETRY_TOOLS = new Set([
|
|
|
4791
5132
|
"prepareRename"
|
|
4792
5133
|
]);
|
|
4793
5134
|
async function withLspClient(filePath, fn, toolName, options = {}) {
|
|
4794
|
-
const absPath = resolvePathInsideContext(filePath);
|
|
5135
|
+
const absPath = READ_ONLY_TOOLS.has(toolName) ? resolveReadablePathInsideContext(filePath) : resolvePathInsideContext(filePath);
|
|
4795
5136
|
if (isDirectoryPath(absPath)) {
|
|
4796
5137
|
throw new LspInvalidPathError("Directory paths are not supported by this LSP tool. " + "Use lsp.diagnostics with a directory path for directory diagnostics.");
|
|
4797
5138
|
}
|
|
@@ -4806,9 +5147,9 @@ async function withLspClient(filePath, fn, toolName, options = {}) {
|
|
|
4806
5147
|
const acquireAndCall = async (allowRetry) => {
|
|
4807
5148
|
const client = await manager.getClient(root, server2, options.signal);
|
|
4808
5149
|
try {
|
|
4809
|
-
return await fn(client, root);
|
|
5150
|
+
return await fn(client, root, absPath);
|
|
4810
5151
|
} catch (err) {
|
|
4811
|
-
if (allowRetry &&
|
|
5152
|
+
if (allowRetry && READ_ONLY_TOOLS.has(toolName) && isLspDeadConnectionError(err)) {
|
|
4812
5153
|
manager.invalidateClient(root, server2.id, client);
|
|
4813
5154
|
return acquireAndCall(false);
|
|
4814
5155
|
}
|
|
@@ -4826,8 +5167,8 @@ async function withLspClient(filePath, fn, toolName, options = {}) {
|
|
|
4826
5167
|
}
|
|
4827
5168
|
|
|
4828
5169
|
// ../lsp-core/src/lsp/directory-diagnostics.ts
|
|
4829
|
-
import { existsSync as
|
|
4830
|
-
import { join as
|
|
5170
|
+
import { existsSync as existsSync12, lstatSync as lstatSync5, readdirSync as readdirSync3 } from "node:fs";
|
|
5171
|
+
import { join as join6, resolve as resolve9 } from "node:path";
|
|
4831
5172
|
|
|
4832
5173
|
// ../lsp-core/src/lsp/formatters.ts
|
|
4833
5174
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
@@ -4957,7 +5298,7 @@ function collectFilesWithExtension(dir, extension, maxFiles) {
|
|
|
4957
5298
|
for (const entry of entries) {
|
|
4958
5299
|
if (files.length >= maxFiles)
|
|
4959
5300
|
return;
|
|
4960
|
-
const fullPath =
|
|
5301
|
+
const fullPath = join6(currentDir, entry);
|
|
4961
5302
|
let stat;
|
|
4962
5303
|
try {
|
|
4963
5304
|
stat = lstatSync5(fullPath);
|
|
@@ -4982,8 +5323,8 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
|
|
|
4982
5323
|
if (!extension.startsWith(".")) {
|
|
4983
5324
|
throw new LspInvalidPathError(`Extension must start with a dot (e.g., ".ts", not "${extension}"). Use ".${extension}" instead.`);
|
|
4984
5325
|
}
|
|
4985
|
-
const absDir =
|
|
4986
|
-
if (!
|
|
5326
|
+
const absDir = resolve9(options.workspaceRoot ?? contextCwd(), directory);
|
|
5327
|
+
if (!existsSync12(absDir)) {
|
|
4987
5328
|
throw new LspInvalidPathError(`Directory does not exist: ${absDir}`);
|
|
4988
5329
|
}
|
|
4989
5330
|
const serverResult = options.server === undefined ? findServerForExtension(extension) : { status: "found", server: options.server };
|
|
@@ -5070,7 +5411,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
|
|
|
5070
5411
|
|
|
5071
5412
|
// ../lsp-core/src/lsp/infer-extension.ts
|
|
5072
5413
|
import { lstatSync as lstatSync6, readdirSync as readdirSync4 } from "node:fs";
|
|
5073
|
-
import { join as
|
|
5414
|
+
import { join as join7 } from "node:path";
|
|
5074
5415
|
var SKIP_DIRECTORIES2 = new Set(["node_modules", ".git", "dist", "build", ".next", "out"]);
|
|
5075
5416
|
var MAX_SCAN_ENTRIES = 500;
|
|
5076
5417
|
function inferExtensionFromDirectory(directory) {
|
|
@@ -5088,7 +5429,7 @@ function inferExtensionFromDirectory(directory) {
|
|
|
5088
5429
|
for (const entry of entries) {
|
|
5089
5430
|
if (scanned >= MAX_SCAN_ENTRIES)
|
|
5090
5431
|
return;
|
|
5091
|
-
const fullPath =
|
|
5432
|
+
const fullPath = join7(dir, entry);
|
|
5092
5433
|
let stat;
|
|
5093
5434
|
try {
|
|
5094
5435
|
stat = lstatSync6(fullPath);
|
|
@@ -5263,7 +5604,7 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
5263
5604
|
const filePath = requireString(params, "filePath");
|
|
5264
5605
|
const severity = severityFilter(params);
|
|
5265
5606
|
try {
|
|
5266
|
-
const absPath =
|
|
5607
|
+
const absPath = resolveReadablePathInsideContext(filePath);
|
|
5267
5608
|
if (isDirectoryPath(absPath)) {
|
|
5268
5609
|
const extension = inferExtensionFromDirectory(absPath);
|
|
5269
5610
|
if (!extension) {
|
|
@@ -5292,7 +5633,7 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
5292
5633
|
};
|
|
5293
5634
|
return text(output2.output, details2);
|
|
5294
5635
|
}
|
|
5295
|
-
const result = await withLspClient(filePath, async (client) => client.diagnostics(
|
|
5636
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.diagnostics(resolvedFilePath, signal), "diagnostics", clientOptions(signal));
|
|
5296
5637
|
if (result.transientError) {
|
|
5297
5638
|
const message = result.transientError.message;
|
|
5298
5639
|
const details2 = {
|
|
@@ -5339,6 +5680,96 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
5339
5680
|
throw error;
|
|
5340
5681
|
}
|
|
5341
5682
|
}
|
|
5683
|
+
// ../lsp-core/src/lsp/format-document.ts
|
|
5684
|
+
import { readFileSync as readFileSync6, renameSync as renameSync3, unlinkSync as unlinkSync2, writeFileSync as writeFileSync3 } from "node:fs";
|
|
5685
|
+
var DEFAULT_FORMATTING_OPTIONS = {
|
|
5686
|
+
tabSize: 4,
|
|
5687
|
+
insertSpaces: false,
|
|
5688
|
+
trimTrailingWhitespace: true,
|
|
5689
|
+
insertFinalNewline: true,
|
|
5690
|
+
trimFinalNewlines: true
|
|
5691
|
+
};
|
|
5692
|
+
var UNCHANGED = { status: "unchanged", linesAdded: 0, linesRemoved: 0 };
|
|
5693
|
+
async function formatDocumentWithClient(client, filePath, options = {}) {
|
|
5694
|
+
const edits = await client.formatDocument(filePath, options.formattingOptions ?? DEFAULT_FORMATTING_OPTIONS, options.signal);
|
|
5695
|
+
if (edits === null)
|
|
5696
|
+
return { status: "unavailable", reason: "capability_not_advertised" };
|
|
5697
|
+
if (edits.length === 0)
|
|
5698
|
+
return UNCHANGED;
|
|
5699
|
+
const before = readFileSync6(filePath, "utf-8");
|
|
5700
|
+
const normalized = normalizeTextEdits(before, edits, 0);
|
|
5701
|
+
if (normalized.text === before)
|
|
5702
|
+
return UNCHANGED;
|
|
5703
|
+
writeAtomically(filePath, normalized.text);
|
|
5704
|
+
await client.openFile(filePath);
|
|
5705
|
+
return {
|
|
5706
|
+
status: "formatted",
|
|
5707
|
+
...lineDelta(normalized.edits)
|
|
5708
|
+
};
|
|
5709
|
+
}
|
|
5710
|
+
function lineDelta(edits) {
|
|
5711
|
+
let linesAdded = 0;
|
|
5712
|
+
let linesRemoved = 0;
|
|
5713
|
+
for (const edit of edits) {
|
|
5714
|
+
linesRemoved += edit.range.end.line - edit.range.start.line + 1;
|
|
5715
|
+
linesAdded += edit.newText.split(`
|
|
5716
|
+
`).length;
|
|
5717
|
+
}
|
|
5718
|
+
return { linesAdded, linesRemoved };
|
|
5719
|
+
}
|
|
5720
|
+
function writeAtomically(filePath, content) {
|
|
5721
|
+
const tempPath = `${filePath}.omo-format.tmp`;
|
|
5722
|
+
writeFileSync3(tempPath, content, "utf-8");
|
|
5723
|
+
try {
|
|
5724
|
+
renameSync3(tempPath, filePath);
|
|
5725
|
+
} catch (error) {
|
|
5726
|
+
try {
|
|
5727
|
+
unlinkSync2(tempPath);
|
|
5728
|
+
} catch {}
|
|
5729
|
+
throw error;
|
|
5730
|
+
}
|
|
5731
|
+
}
|
|
5732
|
+
|
|
5733
|
+
// ../lsp-core/src/tools/format.ts
|
|
5734
|
+
async function executeLspFormat(params, signal) {
|
|
5735
|
+
const filePath = requireString(params, "filePath");
|
|
5736
|
+
try {
|
|
5737
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => formatDocumentWithClient(client, resolvedFilePath, signal === undefined ? {} : { signal }), "format", clientOptions(signal));
|
|
5738
|
+
return text(describeResult(filePath, result), formatDetails(filePath, result));
|
|
5739
|
+
} catch (error) {
|
|
5740
|
+
const missingDependency = missingDependencyResult(error, {
|
|
5741
|
+
filePath,
|
|
5742
|
+
status: "unavailable",
|
|
5743
|
+
reason: "server_unavailable",
|
|
5744
|
+
linesAdded: 0,
|
|
5745
|
+
linesRemoved: 0
|
|
5746
|
+
});
|
|
5747
|
+
if (missingDependency)
|
|
5748
|
+
return missingDependency;
|
|
5749
|
+
throw error;
|
|
5750
|
+
}
|
|
5751
|
+
}
|
|
5752
|
+
function formatDetails(filePath, result) {
|
|
5753
|
+
if (result.status === "unavailable") {
|
|
5754
|
+
return { filePath, status: "unavailable", reason: result.reason, linesAdded: 0, linesRemoved: 0 };
|
|
5755
|
+
}
|
|
5756
|
+
return {
|
|
5757
|
+
filePath,
|
|
5758
|
+
status: result.status,
|
|
5759
|
+
linesAdded: result.linesAdded,
|
|
5760
|
+
linesRemoved: result.linesRemoved
|
|
5761
|
+
};
|
|
5762
|
+
}
|
|
5763
|
+
function describeResult(filePath, result) {
|
|
5764
|
+
if (result.status === "unavailable") {
|
|
5765
|
+
return `Formatting unavailable for ${filePath}: the language server does not advertise documentFormattingProvider.`;
|
|
5766
|
+
}
|
|
5767
|
+
if (result.status === "unchanged") {
|
|
5768
|
+
return `Already formatted: ${filePath}`;
|
|
5769
|
+
}
|
|
5770
|
+
return `Formatted ${filePath} (+${result.linesAdded}/-${result.linesRemoved} lines)`;
|
|
5771
|
+
}
|
|
5772
|
+
|
|
5342
5773
|
// ../lsp-core/src/tools/install-decision.ts
|
|
5343
5774
|
async function executeLspInstallDecision(params) {
|
|
5344
5775
|
const serverId = requireString(params, "server_id");
|
|
@@ -5367,7 +5798,7 @@ async function executeLspGotoDefinition(params, signal) {
|
|
|
5367
5798
|
const line = requireNumber(params, "line");
|
|
5368
5799
|
const character = requireNumber(params, "character");
|
|
5369
5800
|
try {
|
|
5370
|
-
const result = await withLspClient(filePath, async (client) => client.definition(
|
|
5801
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.definition(resolvedFilePath, line, character, signal), "definition", clientOptions(signal));
|
|
5371
5802
|
const locations = !result ? [] : Array.isArray(result) ? result : [result];
|
|
5372
5803
|
const details = { filePath, line, character, locations };
|
|
5373
5804
|
if (locations.length === 0)
|
|
@@ -5392,7 +5823,7 @@ async function executeLspFindReferences(params, signal) {
|
|
|
5392
5823
|
const character = requireNumber(params, "character");
|
|
5393
5824
|
const includeDeclaration = optionalBoolean(params, "includeDeclaration") ?? true;
|
|
5394
5825
|
try {
|
|
5395
|
-
const result = await withLspClient(filePath, async (client) => client.references(
|
|
5826
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.references(resolvedFilePath, line, character, includeDeclaration, signal), "references", clientOptions(signal));
|
|
5396
5827
|
const references = Array.isArray(result) ? result : [];
|
|
5397
5828
|
const total = references.length;
|
|
5398
5829
|
const truncated = total > DEFAULT_MAX_REFERENCES;
|
|
@@ -5434,7 +5865,7 @@ async function executeLspPrepareRename(params, signal) {
|
|
|
5434
5865
|
const line = requireNumber(params, "line");
|
|
5435
5866
|
const character = requireNumber(params, "character");
|
|
5436
5867
|
try {
|
|
5437
|
-
const result = await withLspClient(filePath, async (client) => client.prepareRename(
|
|
5868
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.prepareRename(resolvedFilePath, line, character, signal), "prepareRename", clientOptions(signal));
|
|
5438
5869
|
const details = { filePath, line, character, result };
|
|
5439
5870
|
return text(formatPrepareRenameResult(result), details);
|
|
5440
5871
|
} catch (error) {
|
|
@@ -5455,7 +5886,7 @@ async function executeLspRename(params, signal) {
|
|
|
5455
5886
|
const character = requireNumber(params, "character");
|
|
5456
5887
|
const newName = requireString(params, "newName");
|
|
5457
5888
|
try {
|
|
5458
|
-
const result = await withLspClient(filePath, async (client) => client.rename(
|
|
5889
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.rename(resolvedFilePath, line, character, newName, signal), "rename", clientOptions(signal));
|
|
5459
5890
|
const details = { filePath, line, character, newName, apply: result.apply, edit: result.edit };
|
|
5460
5891
|
return text(formatApplyResult(result.apply), details, !result.apply.success);
|
|
5461
5892
|
} catch (error) {
|
|
@@ -5535,7 +5966,7 @@ async function executeLspSymbols(params, signal) {
|
|
|
5535
5966
|
const symbols2 = await withLspClient(filePath, async (client) => client.workspaceSymbols(query, signal), "workspaceSymbols", clientOptions(signal));
|
|
5536
5967
|
return formatSymbolsResult(filePath, scope, symbols2, limit, query);
|
|
5537
5968
|
}
|
|
5538
|
-
const symbols = await withLspClient(filePath, async (client) => client.documentSymbols(
|
|
5969
|
+
const symbols = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.documentSymbols(resolvedFilePath, signal), "documentSymbols", clientOptions(signal));
|
|
5539
5970
|
return formatSymbolsResult(filePath, scope, symbols, limit);
|
|
5540
5971
|
} catch (error) {
|
|
5541
5972
|
const query = optionalString(params, "query");
|
|
@@ -5671,6 +6102,16 @@ var LSP_MCP_TOOLS = [
|
|
|
5671
6102
|
}, ["filePath", "line", "character", "newName"]),
|
|
5672
6103
|
execute: executeLspRename
|
|
5673
6104
|
},
|
|
6105
|
+
{
|
|
6106
|
+
name: "format",
|
|
6107
|
+
aliases: ["lsp_format"],
|
|
6108
|
+
title: "LSP Format",
|
|
6109
|
+
description: "Format a source file with its language server and write the returned edits to disk.",
|
|
6110
|
+
inputSchema: objectSchema({
|
|
6111
|
+
filePath: { type: "string", description: "Source file path to format." }
|
|
6112
|
+
}, ["filePath"]),
|
|
6113
|
+
execute: executeLspFormat
|
|
6114
|
+
},
|
|
5674
6115
|
{
|
|
5675
6116
|
name: "install_decision",
|
|
5676
6117
|
aliases: ["lsp_install_decision"],
|
|
@@ -5771,7 +6212,10 @@ function requestedProtocolVersion(params) {
|
|
|
5771
6212
|
var CONTEXT_KEY = "_context";
|
|
5772
6213
|
|
|
5773
6214
|
class InvalidDaemonRequestError extends Error {
|
|
5774
|
-
|
|
6215
|
+
constructor() {
|
|
6216
|
+
super(...arguments);
|
|
6217
|
+
this.name = "InvalidDaemonRequestError";
|
|
6218
|
+
}
|
|
5775
6219
|
}
|
|
5776
6220
|
function extractRequestContext(raw) {
|
|
5777
6221
|
if (!isPlainRecord(raw) || raw["method"] !== "tools/call")
|
|
@@ -5887,14 +6331,17 @@ async function callToolViaDaemon(name, args, options) {
|
|
|
5887
6331
|
function callDiagnosticsViaDaemon(filePath, options) {
|
|
5888
6332
|
return callToolViaDaemon("diagnostics", { filePath, severity: "error" }, options);
|
|
5889
6333
|
}
|
|
6334
|
+
function callFormatViaDaemon(filePath, options) {
|
|
6335
|
+
return callToolViaDaemon("format", { filePath }, options);
|
|
6336
|
+
}
|
|
5890
6337
|
function currentRequestContext(env = process.env) {
|
|
5891
6338
|
const cwd = process.cwd();
|
|
5892
6339
|
const home = env["HOME"] ?? homedir3();
|
|
5893
6340
|
return parseLspRequestContext({
|
|
5894
6341
|
cwd,
|
|
5895
|
-
projectConfigPaths: [
|
|
5896
|
-
userConfigPath:
|
|
5897
|
-
installDecisionsPath:
|
|
6342
|
+
projectConfigPaths: [join8(cwd, ".codex", "lsp-client.json")],
|
|
6343
|
+
userConfigPath: join8(home, ".codex", "lsp-client.json"),
|
|
6344
|
+
installDecisionsPath: join8(home, ".codex", "lsp-install-decisions.json"),
|
|
5898
6345
|
capabilities: { installDecisionTool: true }
|
|
5899
6346
|
});
|
|
5900
6347
|
}
|
|
@@ -5909,7 +6356,7 @@ function withContext(args, context) {
|
|
|
5909
6356
|
function ensureDaemonAvailable(paths, ensure, signal) {
|
|
5910
6357
|
if (!signal)
|
|
5911
6358
|
return ensure(paths);
|
|
5912
|
-
return new Promise((
|
|
6359
|
+
return new Promise((resolve10, reject) => {
|
|
5913
6360
|
let settled = false;
|
|
5914
6361
|
const finish = (run) => {
|
|
5915
6362
|
if (settled)
|
|
@@ -5924,11 +6371,11 @@ function ensureDaemonAvailable(paths, ensure, signal) {
|
|
|
5924
6371
|
return;
|
|
5925
6372
|
}
|
|
5926
6373
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
5927
|
-
Promise.resolve().then(() => ensure(paths, signal)).then(() => finish(() =>
|
|
6374
|
+
Promise.resolve().then(() => ensure(paths, signal)).then(() => finish(() => resolve10()), (error) => finish(() => reject(signal.aborted ? new DaemonRequestCancelledError(false) : error)));
|
|
5928
6375
|
});
|
|
5929
6376
|
}
|
|
5930
6377
|
function sendToolCall(paths, token, name, args, options) {
|
|
5931
|
-
return new Promise((
|
|
6378
|
+
return new Promise((resolve10, reject) => {
|
|
5932
6379
|
const socket = connect(paths.socket);
|
|
5933
6380
|
const requestId = allocateProxyRequestId();
|
|
5934
6381
|
let settled = false;
|
|
@@ -5981,7 +6428,7 @@ function sendToolCall(paths, token, name, args, options) {
|
|
|
5981
6428
|
}
|
|
5982
6429
|
const result = toToolResult(message, requestId);
|
|
5983
6430
|
if (result)
|
|
5984
|
-
finish(() =>
|
|
6431
|
+
finish(() => resolve10(result));
|
|
5985
6432
|
else
|
|
5986
6433
|
finish(() => reject(new DaemonRequestError("invalid daemon response", requestWritten)));
|
|
5987
6434
|
});
|
|
@@ -6027,18 +6474,15 @@ function isRetryableTool(name) {
|
|
|
6027
6474
|
}
|
|
6028
6475
|
|
|
6029
6476
|
// src/client.ts
|
|
6030
|
-
import { statSync as statSync5 } from "node:fs";
|
|
6031
|
-
import { isAbsolute as isAbsolute5 } from "node:path";
|
|
6032
6477
|
var OMO_LSP_DAEMON_DIR2 = "OMO_LSP_DAEMON_DIR";
|
|
6033
6478
|
var OMO_LSP_DAEMON_CLI2 = "OMO_LSP_DAEMON_CLI";
|
|
6034
6479
|
var OMO_LSP_DAEMON_VERSION2 = "OMO_LSP_DAEMON_VERSION";
|
|
6035
6480
|
var DAEMON_VERSION_PATTERN2 = /^[A-Za-z0-9][A-Za-z0-9._+-]{0,127}$/;
|
|
6036
6481
|
|
|
6037
6482
|
class InvalidRuntimeOverrideError2 extends Error {
|
|
6038
|
-
code = "invalid_runtime_override";
|
|
6039
|
-
reason;
|
|
6040
6483
|
constructor(reason, message) {
|
|
6041
6484
|
super(message);
|
|
6485
|
+
this.code = "invalid_runtime_override";
|
|
6042
6486
|
this.name = "InvalidRuntimeOverrideError";
|
|
6043
6487
|
this.reason = reason;
|
|
6044
6488
|
}
|
|
@@ -6058,12 +6502,12 @@ function resolveDaemonRuntime2(env, defaults) {
|
|
|
6058
6502
|
throw new InvalidRuntimeOverrideError2("paired_values_required", `${OMO_LSP_DAEMON_CLI2} and ${OMO_LSP_DAEMON_VERSION2} must be set together`);
|
|
6059
6503
|
}
|
|
6060
6504
|
if (!hasCliOverride || !hasVersionOverride) {
|
|
6061
|
-
if (!
|
|
6505
|
+
if (!isAbsolute6(defaults.cliPath)) {
|
|
6062
6506
|
throw new InvalidRuntimeOverrideError2("packaged_cli_must_be_absolute", "Packaged LSP daemon CLI path must be absolute");
|
|
6063
6507
|
}
|
|
6064
6508
|
return { cliPath: defaults.cliPath, version: validateDaemonVersion2(defaults.version) };
|
|
6065
6509
|
}
|
|
6066
|
-
if (!
|
|
6510
|
+
if (!isAbsolute6(cliOverride)) {
|
|
6067
6511
|
throw new InvalidRuntimeOverrideError2("cli_must_be_absolute", `${OMO_LSP_DAEMON_CLI2} must be an absolute path to an existing regular file`);
|
|
6068
6512
|
}
|
|
6069
6513
|
const stat = statSync5(cliOverride, { throwIfNoEntry: false });
|
|
@@ -6081,17 +6525,21 @@ function callToolViaDaemon2(name, args, options) {
|
|
|
6081
6525
|
function callDiagnosticsViaDaemon2(filePath, options) {
|
|
6082
6526
|
return callDiagnosticsViaDaemon(filePath, options);
|
|
6083
6527
|
}
|
|
6528
|
+
function callFormatViaDaemon2(filePath, options) {
|
|
6529
|
+
return callFormatViaDaemon(filePath, options);
|
|
6530
|
+
}
|
|
6084
6531
|
function currentRequestContext2(env = process.env) {
|
|
6085
6532
|
return currentRequestContext(env);
|
|
6086
6533
|
}
|
|
6087
6534
|
export {
|
|
6088
|
-
|
|
6089
|
-
resolveDaemonRuntime2 as resolveDaemonRuntime,
|
|
6090
|
-
currentRequestContext2 as currentRequestContext,
|
|
6091
|
-
callToolViaDaemon2 as callToolViaDaemon,
|
|
6092
|
-
callDiagnosticsViaDaemon2 as callDiagnosticsViaDaemon,
|
|
6093
|
-
OMO_LSP_DAEMON_VERSION2 as OMO_LSP_DAEMON_VERSION,
|
|
6094
|
-
OMO_LSP_DAEMON_DIR2 as OMO_LSP_DAEMON_DIR,
|
|
6535
|
+
InvalidRuntimeOverrideError2 as InvalidRuntimeOverrideError,
|
|
6095
6536
|
OMO_LSP_DAEMON_CLI2 as OMO_LSP_DAEMON_CLI,
|
|
6096
|
-
|
|
6537
|
+
OMO_LSP_DAEMON_DIR2 as OMO_LSP_DAEMON_DIR,
|
|
6538
|
+
OMO_LSP_DAEMON_VERSION2 as OMO_LSP_DAEMON_VERSION,
|
|
6539
|
+
callDiagnosticsViaDaemon2 as callDiagnosticsViaDaemon,
|
|
6540
|
+
callFormatViaDaemon2 as callFormatViaDaemon,
|
|
6541
|
+
callToolViaDaemon2 as callToolViaDaemon,
|
|
6542
|
+
currentRequestContext2 as currentRequestContext,
|
|
6543
|
+
resolveDaemonRuntime2 as resolveDaemonRuntime,
|
|
6544
|
+
validateDaemonVersion2 as validateDaemonVersion
|
|
6097
6545
|
};
|