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
|
@@ -8,11 +8,13 @@ import { argv, execPath as execPath2, stderr } from "node:process";
|
|
|
8
8
|
import { stdin as processStdin } from "node:process";
|
|
9
9
|
|
|
10
10
|
// src/codex-hook.ts
|
|
11
|
-
import { readFileSync as
|
|
11
|
+
import { readFileSync as readFileSync10, realpathSync as realpathSync8 } from "node:fs";
|
|
12
12
|
import { homedir as homedir3 } from "node:os";
|
|
13
|
-
import { join as
|
|
13
|
+
import { join as join12, resolve as resolve12 } from "node:path";
|
|
14
14
|
|
|
15
15
|
// ../../../../lsp-daemon/dist/client.js
|
|
16
|
+
import { statSync as statSync5 } from "node:fs";
|
|
17
|
+
import { isAbsolute as isAbsolute6 } from "node:path";
|
|
16
18
|
import { connect } from "node:net";
|
|
17
19
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
18
20
|
import { existsSync, realpathSync, statSync } from "node:fs";
|
|
@@ -42,8 +44,8 @@ import * as path from "node:path";
|
|
|
42
44
|
import { fileURLToPath } from "node:url";
|
|
43
45
|
import { statSync as statSync2 } from "node:fs";
|
|
44
46
|
import { isAbsolute as isAbsolute2 } from "node:path";
|
|
45
|
-
import { existsSync as
|
|
46
|
-
import { dirname as
|
|
47
|
+
import { existsSync as existsSync11, realpathSync as realpathSync5, statSync as statSync4 } from "node:fs";
|
|
48
|
+
import { basename as basename3, dirname as dirname10, join as join5, resolve as resolve8 } from "node:path";
|
|
47
49
|
import { basename as basename2, extname } from "node:path";
|
|
48
50
|
import { resolve as resolve6 } from "node:path";
|
|
49
51
|
import { pathToFileURL as pathToFileURL3 } from "node:url";
|
|
@@ -62,32 +64,32 @@ import { createHash as createHash2 } from "node:crypto";
|
|
|
62
64
|
import { dirname as dirname5, relative as relative4, resolve as resolve4 } from "node:path";
|
|
63
65
|
import { existsSync as existsSync6, lstatSync as lstatSync4, readdirSync as readdirSync2 } from "node:fs";
|
|
64
66
|
import { dirname as dirname6, resolve as resolve5 } from "node:path";
|
|
65
|
-
import { existsSync as existsSync7,
|
|
66
|
-
import { dirname as dirname7 } from "node:path";
|
|
67
|
-
import { existsSync as existsSync8, readFileSync as
|
|
68
|
-
import {
|
|
69
|
-
import {
|
|
70
|
-
import { existsSync as
|
|
71
|
-
import { join as
|
|
67
|
+
import { existsSync as existsSync7, realpathSync as realpathSync4 } from "node:fs";
|
|
68
|
+
import { dirname as dirname7, join as join3 } from "node:path";
|
|
69
|
+
import { existsSync as existsSync8, mkdirSync as mkdirSync3, readFileSync as readFileSync4, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
70
|
+
import { dirname as dirname8 } from "node:path";
|
|
71
|
+
import { existsSync as existsSync9, readFileSync as readFileSync5 } from "node:fs";
|
|
72
|
+
import { existsSync as existsSync10 } from "node:fs";
|
|
73
|
+
import { delimiter as delimiter3, dirname as dirname9, isAbsolute as isAbsolute5, join as join4, resolve as resolve7 } from "node:path";
|
|
74
|
+
import { existsSync as existsSync12, lstatSync as lstatSync5, readdirSync as readdirSync3 } from "node:fs";
|
|
75
|
+
import { join as join6, resolve as resolve9 } from "node:path";
|
|
72
76
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
73
77
|
import { lstatSync as lstatSync6, readdirSync as readdirSync4 } from "node:fs";
|
|
74
|
-
import { join as
|
|
75
|
-
import {
|
|
76
|
-
import { isAbsolute as isAbsolute5 } from "node:path";
|
|
78
|
+
import { join as join7 } from "node:path";
|
|
79
|
+
import { readFileSync as readFileSync6, renameSync as renameSync3, unlinkSync as unlinkSync2, writeFileSync as writeFileSync3 } from "node:fs";
|
|
77
80
|
|
|
78
81
|
class LspRequestContextParseError extends Error {
|
|
79
|
-
code;
|
|
80
|
-
name = "LspRequestContextParseError";
|
|
81
82
|
constructor(code, message) {
|
|
82
83
|
super(message);
|
|
83
84
|
this.code = code;
|
|
85
|
+
this.name = "LspRequestContextParseError";
|
|
84
86
|
}
|
|
85
87
|
}
|
|
86
88
|
|
|
87
89
|
class LspRequestContextUnavailableError extends Error {
|
|
88
|
-
name = "LspRequestContextUnavailableError";
|
|
89
90
|
constructor() {
|
|
90
91
|
super("LSP request context is required. Standalone MCP startup must install one with runWithRequestContext(createStandaloneMcpRequestContext()).");
|
|
92
|
+
this.name = "LspRequestContextUnavailableError";
|
|
91
93
|
}
|
|
92
94
|
}
|
|
93
95
|
var storage = new AsyncLocalStorage;
|
|
@@ -214,7 +216,6 @@ function isPlainRecord(value) {
|
|
|
214
216
|
}
|
|
215
217
|
|
|
216
218
|
class DaemonRequestError extends Error {
|
|
217
|
-
requestWritten;
|
|
218
219
|
constructor(message, requestWritten) {
|
|
219
220
|
super(message);
|
|
220
221
|
this.name = "DaemonRequestError";
|
|
@@ -237,7 +238,6 @@ class DaemonRequestCancelledError extends DaemonRequestError {
|
|
|
237
238
|
}
|
|
238
239
|
|
|
239
240
|
class DaemonRequestTimedOutError extends DaemonRequestError {
|
|
240
|
-
timeoutMs;
|
|
241
241
|
constructor(requestWritten, timeoutMs) {
|
|
242
242
|
super("daemon request timed out", requestWritten);
|
|
243
243
|
this.name = "DaemonRequestTimedOutError";
|
|
@@ -314,20 +314,18 @@ var OMO_LSP_DAEMON_VERSION = "OMO_LSP_DAEMON_VERSION";
|
|
|
314
314
|
var DAEMON_VERSION_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._+-]{0,127}$/;
|
|
315
315
|
|
|
316
316
|
class InvalidRuntimeOverrideError extends Error {
|
|
317
|
-
code = "invalid_runtime_override";
|
|
318
|
-
reason;
|
|
319
317
|
constructor(reason, message) {
|
|
320
318
|
super(message);
|
|
319
|
+
this.code = "invalid_runtime_override";
|
|
321
320
|
this.name = "InvalidRuntimeOverrideError";
|
|
322
321
|
this.reason = reason;
|
|
323
322
|
}
|
|
324
323
|
}
|
|
325
324
|
|
|
326
325
|
class InvalidDaemonVersionError extends Error {
|
|
327
|
-
code = "invalid_daemon_version";
|
|
328
|
-
version;
|
|
329
326
|
constructor(version) {
|
|
330
327
|
super("LSP daemon version must match [A-Za-z0-9][A-Za-z0-9._+-]{0,127}");
|
|
328
|
+
this.code = "invalid_daemon_version";
|
|
331
329
|
this.name = "InvalidDaemonVersionError";
|
|
332
330
|
this.version = version;
|
|
333
331
|
}
|
|
@@ -371,10 +369,9 @@ var requireFromHere = createRequire(import.meta.url);
|
|
|
371
369
|
var MAX_SOCKET_PATH_LENGTH = 100;
|
|
372
370
|
|
|
373
371
|
class InvalidDaemonDirectoryError extends Error {
|
|
374
|
-
code = "invalid_daemon_directory";
|
|
375
|
-
directory;
|
|
376
372
|
constructor(directory) {
|
|
377
373
|
super(`${OMO_LSP_DAEMON_DIR} must be an absolute path`);
|
|
374
|
+
this.code = "invalid_daemon_directory";
|
|
378
375
|
this.name = "InvalidDaemonDirectoryError";
|
|
379
376
|
this.directory = directory;
|
|
380
377
|
}
|
|
@@ -565,7 +562,8 @@ function spawnDaemonProcess(paths) {
|
|
|
565
562
|
try {
|
|
566
563
|
const child = spawn(resolveDaemonNodeExecutable(), [paths.cliPath, "daemon"], {
|
|
567
564
|
detached: true,
|
|
568
|
-
stdio: ["ignore", logFd, logFd]
|
|
565
|
+
stdio: ["ignore", logFd, logFd],
|
|
566
|
+
windowsHide: true
|
|
569
567
|
});
|
|
570
568
|
child.once("spawn", () => closeSync2(logFd));
|
|
571
569
|
child.once("error", (error) => {
|
|
@@ -686,22 +684,15 @@ function effectiveExtension(filePath) {
|
|
|
686
684
|
}
|
|
687
685
|
|
|
688
686
|
class LspConnectionClosedError extends Error {
|
|
689
|
-
serverId;
|
|
690
|
-
root;
|
|
691
|
-
name = "LspConnectionClosedError";
|
|
692
687
|
constructor(serverId, root, message) {
|
|
693
688
|
super(message ?? `LSP connection closed for ${serverId} at ${root}`);
|
|
694
689
|
this.serverId = serverId;
|
|
695
690
|
this.root = root;
|
|
691
|
+
this.name = "LspConnectionClosedError";
|
|
696
692
|
}
|
|
697
693
|
}
|
|
698
694
|
|
|
699
695
|
class LspProcessExitedError extends Error {
|
|
700
|
-
serverId;
|
|
701
|
-
root;
|
|
702
|
-
exitCode;
|
|
703
|
-
stderrTail;
|
|
704
|
-
name = "LspProcessExitedError";
|
|
705
696
|
constructor(serverId, root, exitCode, stderrTail) {
|
|
706
697
|
const stderrSuffix = stderrTail ? `
|
|
707
698
|
stderr tail: ${stderrTail}` : "";
|
|
@@ -710,46 +701,59 @@ stderr tail: ${stderrTail}` : "";
|
|
|
710
701
|
this.root = root;
|
|
711
702
|
this.exitCode = exitCode;
|
|
712
703
|
this.stderrTail = stderrTail;
|
|
704
|
+
this.name = "LspProcessExitedError";
|
|
713
705
|
}
|
|
714
706
|
}
|
|
715
707
|
|
|
716
708
|
class LspRequestTimeoutError extends Error {
|
|
717
|
-
method;
|
|
718
|
-
stderrTail;
|
|
719
|
-
name = "LspRequestTimeoutError";
|
|
720
709
|
constructor(method, stderrTail) {
|
|
721
710
|
const stderrSuffix = stderrTail ? `
|
|
722
711
|
recent stderr: ${stderrTail}` : "";
|
|
723
712
|
super(`LSP request timeout (method: ${method})${stderrSuffix}`);
|
|
724
713
|
this.method = method;
|
|
725
714
|
this.stderrTail = stderrTail;
|
|
715
|
+
this.name = "LspRequestTimeoutError";
|
|
726
716
|
}
|
|
727
717
|
}
|
|
728
718
|
|
|
729
719
|
class LspInvalidPathError extends Error {
|
|
730
|
-
|
|
720
|
+
constructor() {
|
|
721
|
+
super(...arguments);
|
|
722
|
+
this.name = "LspInvalidPathError";
|
|
723
|
+
}
|
|
731
724
|
}
|
|
732
725
|
|
|
733
726
|
class LspServerLookupError extends Error {
|
|
734
|
-
lookup;
|
|
735
|
-
name = "LspServerLookupError";
|
|
736
727
|
constructor(message, lookup) {
|
|
737
728
|
super(message);
|
|
738
729
|
this.lookup = lookup;
|
|
730
|
+
this.name = "LspServerLookupError";
|
|
739
731
|
}
|
|
740
732
|
}
|
|
741
733
|
|
|
742
734
|
class LspServerInitializingError extends Error {
|
|
743
|
-
originalError;
|
|
744
|
-
name = "LspServerInitializingError";
|
|
745
735
|
constructor(originalError) {
|
|
746
736
|
super(`LSP server is still initializing. Please retry in a few seconds. Original error: ${originalError.message}`);
|
|
747
737
|
this.originalError = originalError;
|
|
738
|
+
this.name = "LspServerInitializingError";
|
|
748
739
|
}
|
|
749
740
|
}
|
|
750
741
|
|
|
751
742
|
class LspProcessSpawnError extends Error {
|
|
752
|
-
|
|
743
|
+
constructor() {
|
|
744
|
+
super(...arguments);
|
|
745
|
+
this.name = "LspProcessSpawnError";
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
class LspClientRespawnBudgetExceededError extends Error {
|
|
750
|
+
constructor(serverId, root, retryLimit) {
|
|
751
|
+
super(`LSP server ${serverId} at ${root} failed to stay alive; respawn budget exhausted ` + `(${retryLimit} consecutive dead generations). Retrying after the cooldown may succeed.`);
|
|
752
|
+
this.serverId = serverId;
|
|
753
|
+
this.root = root;
|
|
754
|
+
this.retryLimit = retryLimit;
|
|
755
|
+
this.name = "LspClientRespawnBudgetExceededError";
|
|
756
|
+
}
|
|
753
757
|
}
|
|
754
758
|
function isLspDeadConnectionError(err) {
|
|
755
759
|
return err instanceof LspConnectionClosedError || err instanceof LspProcessExitedError;
|
|
@@ -769,9 +773,12 @@ var DEFAULT_MAX_DIRECTORY_FILES = 50;
|
|
|
769
773
|
var REQUEST_TIMEOUT_MS = 15000;
|
|
770
774
|
var INIT_TIMEOUT_MS = 60000;
|
|
771
775
|
var IDLE_TIMEOUT_MS = 5 * 60000;
|
|
776
|
+
var MAX_RESIDENT_CLIENTS = 6;
|
|
772
777
|
var REAPER_INTERVAL_MS = 60000;
|
|
773
778
|
var STOP_HARD_KILL_TIMEOUT_MS = 5000;
|
|
774
779
|
var STOP_SIGKILL_GRACE_MS = 1000;
|
|
780
|
+
var CLIENT_RESPAWN_RETRY_LIMIT = 2;
|
|
781
|
+
var CLIENT_RESPAWN_COOLDOWN_MS = 60000;
|
|
775
782
|
var HEADER_SEPARATOR2 = `\r
|
|
776
783
|
\r
|
|
777
784
|
`;
|
|
@@ -781,20 +788,31 @@ var METHOD_NOT_FOUND = -32601;
|
|
|
781
788
|
var INTERNAL_ERROR = -32603;
|
|
782
789
|
|
|
783
790
|
class JsonRpcConnection {
|
|
784
|
-
reader;
|
|
785
|
-
writer;
|
|
786
|
-
pendingRequests = new Map;
|
|
787
|
-
notificationHandlers = new Map;
|
|
788
|
-
requestHandlers = new Map;
|
|
789
|
-
closeHandlers = [];
|
|
790
|
-
errorHandlers = [];
|
|
791
|
-
inputBuffer = Buffer.alloc(0);
|
|
792
|
-
nextRequestId = 1;
|
|
793
|
-
listening = false;
|
|
794
|
-
disposed = false;
|
|
795
791
|
constructor(reader, writer) {
|
|
796
792
|
this.reader = reader;
|
|
797
793
|
this.writer = writer;
|
|
794
|
+
this.pendingRequests = new Map;
|
|
795
|
+
this.notificationHandlers = new Map;
|
|
796
|
+
this.requestHandlers = new Map;
|
|
797
|
+
this.closeHandlers = [];
|
|
798
|
+
this.errorHandlers = [];
|
|
799
|
+
this.inputBuffer = Buffer.alloc(0);
|
|
800
|
+
this.nextRequestId = 1;
|
|
801
|
+
this.listening = false;
|
|
802
|
+
this.disposed = false;
|
|
803
|
+
this.handleData = (chunk) => {
|
|
804
|
+
const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
|
|
805
|
+
this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
|
|
806
|
+
this.drainInputBuffer();
|
|
807
|
+
};
|
|
808
|
+
this.handleClose = () => {
|
|
809
|
+
for (const handler of this.closeHandlers) {
|
|
810
|
+
handler();
|
|
811
|
+
}
|
|
812
|
+
};
|
|
813
|
+
this.handleStreamError = (error) => {
|
|
814
|
+
this.emitError(error);
|
|
815
|
+
};
|
|
798
816
|
}
|
|
799
817
|
listen() {
|
|
800
818
|
if (this.listening)
|
|
@@ -915,19 +933,6 @@ class JsonRpcConnection {
|
|
|
915
933
|
this.notificationHandlers.clear();
|
|
916
934
|
this.requestHandlers.clear();
|
|
917
935
|
}
|
|
918
|
-
handleData = (chunk) => {
|
|
919
|
-
const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
|
|
920
|
-
this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
|
|
921
|
-
this.drainInputBuffer();
|
|
922
|
-
};
|
|
923
|
-
handleClose = () => {
|
|
924
|
-
for (const handler of this.closeHandlers) {
|
|
925
|
-
handler();
|
|
926
|
-
}
|
|
927
|
-
};
|
|
928
|
-
handleStreamError = (error) => {
|
|
929
|
-
this.emitError(error);
|
|
930
|
-
};
|
|
931
936
|
drainInputBuffer() {
|
|
932
937
|
while (true) {
|
|
933
938
|
const headerEnd = this.inputBuffer.indexOf(HEADER_SEPARATOR2);
|
|
@@ -1267,31 +1272,26 @@ function isPosition(value) {
|
|
|
1267
1272
|
}
|
|
1268
1273
|
|
|
1269
1274
|
class LspClientNotStartedError extends Error {
|
|
1270
|
-
serverId;
|
|
1271
|
-
root;
|
|
1272
|
-
name = "LspClientNotStartedError";
|
|
1273
1275
|
constructor(serverId, root) {
|
|
1274
1276
|
super("LSP client not started");
|
|
1275
1277
|
this.serverId = serverId;
|
|
1276
1278
|
this.root = root;
|
|
1279
|
+
this.name = "LspClientNotStartedError";
|
|
1277
1280
|
}
|
|
1278
1281
|
}
|
|
1279
1282
|
|
|
1280
1283
|
class LspClientTransport {
|
|
1281
|
-
root;
|
|
1282
|
-
server;
|
|
1283
|
-
proc = null;
|
|
1284
|
-
connection = null;
|
|
1285
|
-
stderrBuffer = [];
|
|
1286
|
-
processExited = false;
|
|
1287
|
-
diagnosticsStore = new Map;
|
|
1288
|
-
requestTimeoutMs;
|
|
1289
|
-
initializeTimeoutMs;
|
|
1290
|
-
workspaceApplyEditHandler = null;
|
|
1291
|
-
diagnosticPullSupported = false;
|
|
1292
1284
|
constructor(root, server2, timeouts = {}) {
|
|
1293
1285
|
this.root = root;
|
|
1294
1286
|
this.server = server2;
|
|
1287
|
+
this.proc = null;
|
|
1288
|
+
this.connection = null;
|
|
1289
|
+
this.stderrBuffer = [];
|
|
1290
|
+
this.processExited = false;
|
|
1291
|
+
this.diagnosticsStore = new Map;
|
|
1292
|
+
this.workspaceApplyEditHandler = null;
|
|
1293
|
+
this.diagnosticPullSupported = false;
|
|
1294
|
+
this.documentFormattingSupported = false;
|
|
1295
1295
|
this.requestTimeoutMs = timeouts.requestTimeoutMs ?? REQUEST_TIMEOUT_MS;
|
|
1296
1296
|
this.initializeTimeoutMs = timeouts.initializeTimeoutMs ?? INIT_TIMEOUT_MS;
|
|
1297
1297
|
}
|
|
@@ -1313,6 +1313,12 @@ class LspClientTransport {
|
|
|
1313
1313
|
isDiagnosticPullSupported() {
|
|
1314
1314
|
return this.diagnosticPullSupported;
|
|
1315
1315
|
}
|
|
1316
|
+
setDocumentFormattingSupported(supported) {
|
|
1317
|
+
this.documentFormattingSupported = supported;
|
|
1318
|
+
}
|
|
1319
|
+
isDocumentFormattingSupported() {
|
|
1320
|
+
return this.documentFormattingSupported;
|
|
1321
|
+
}
|
|
1316
1322
|
handlePublishDiagnostics(params) {
|
|
1317
1323
|
this.diagnosticsStore.set(params.uri, [...params.diagnostics]);
|
|
1318
1324
|
}
|
|
@@ -1524,6 +1530,14 @@ function supportsDiagnosticPull(capabilities) {
|
|
|
1524
1530
|
return false;
|
|
1525
1531
|
return Object.hasOwn(capabilities, "diagnosticProvider");
|
|
1526
1532
|
}
|
|
1533
|
+
function supportsDocumentFormatting(capabilities) {
|
|
1534
|
+
if (capabilities === undefined)
|
|
1535
|
+
return false;
|
|
1536
|
+
const provider = capabilities.documentFormattingProvider;
|
|
1537
|
+
if (provider === undefined || provider === null || provider === false)
|
|
1538
|
+
return false;
|
|
1539
|
+
return provider === true || typeof provider === "object";
|
|
1540
|
+
}
|
|
1527
1541
|
|
|
1528
1542
|
class LspClientConnection extends LspClientTransport {
|
|
1529
1543
|
async initialize() {
|
|
@@ -1540,6 +1554,7 @@ class LspClientConnection extends LspClientTransport {
|
|
|
1540
1554
|
references: {},
|
|
1541
1555
|
documentSymbol: { hierarchicalDocumentSymbolSupport: true },
|
|
1542
1556
|
publishDiagnostics: {},
|
|
1557
|
+
formatting: { dynamicRegistration: false },
|
|
1543
1558
|
rename: {
|
|
1544
1559
|
prepareSupport: true,
|
|
1545
1560
|
prepareSupportDefaultBehavior: 1
|
|
@@ -1581,6 +1596,7 @@ class LspClientConnection extends LspClientTransport {
|
|
|
1581
1596
|
initializationOptions: this.server.initialization
|
|
1582
1597
|
}, { timeoutMs: this.initializeTimeoutMs });
|
|
1583
1598
|
this.setDiagnosticPullSupported(supportsDiagnosticPull(result?.capabilities));
|
|
1599
|
+
this.setDocumentFormattingSupported(supportsDocumentFormatting(result?.capabilities));
|
|
1584
1600
|
await this.sendNotification("initialized", {});
|
|
1585
1601
|
await this.sendNotification("workspace/didChangeConfiguration", {
|
|
1586
1602
|
settings: { json: { validate: { enable: true } } }
|
|
@@ -1777,16 +1793,12 @@ function movedPath(candidate, oldPath, newPath) {
|
|
|
1777
1793
|
}
|
|
1778
1794
|
|
|
1779
1795
|
class WorkspaceDocumentState {
|
|
1780
|
-
sendNotification;
|
|
1781
|
-
clearDiagnostics;
|
|
1782
|
-
openDocuments = new Map;
|
|
1783
|
-
openByUri = new Map;
|
|
1784
|
-
openPromises = new Map;
|
|
1785
|
-
now;
|
|
1786
|
-
versionlessPublishQuiescenceMs;
|
|
1787
1796
|
constructor(sendNotification, clearDiagnostics, options = {}) {
|
|
1788
1797
|
this.sendNotification = sendNotification;
|
|
1789
1798
|
this.clearDiagnostics = clearDiagnostics;
|
|
1799
|
+
this.openDocuments = new Map;
|
|
1800
|
+
this.openByUri = new Map;
|
|
1801
|
+
this.openPromises = new Map;
|
|
1790
1802
|
this.now = options.now ?? (() => Date.now());
|
|
1791
1803
|
this.versionlessPublishQuiescenceMs = options.versionlessPublishQuiescenceMs ?? DEFAULT_VERSIONLESS_PUBLISH_QUIESCENCE_MS;
|
|
1792
1804
|
}
|
|
@@ -2040,13 +2052,11 @@ function workspaceApplyEditConcurrentFailureReason(phase) {
|
|
|
2040
2052
|
}
|
|
2041
2053
|
|
|
2042
2054
|
class WorkspaceEditPathError extends Error {
|
|
2043
|
-
path;
|
|
2044
|
-
detail;
|
|
2045
|
-
name = "WorkspaceEditPathError";
|
|
2046
2055
|
constructor(path2, detail) {
|
|
2047
2056
|
super(`${detail}: ${path2}`);
|
|
2048
2057
|
this.path = path2;
|
|
2049
2058
|
this.detail = detail;
|
|
2059
|
+
this.name = "WorkspaceEditPathError";
|
|
2050
2060
|
}
|
|
2051
2061
|
}
|
|
2052
2062
|
function isPathInsideWorkspace(filePath, workspaceRoot) {
|
|
@@ -2332,13 +2342,11 @@ function canonicalFingerprint(operations) {
|
|
|
2332
2342
|
}
|
|
2333
2343
|
|
|
2334
2344
|
class WorkspaceEditValidationError extends Error {
|
|
2335
|
-
changeIndex;
|
|
2336
|
-
detail;
|
|
2337
|
-
name = "WorkspaceEditValidationError";
|
|
2338
2345
|
constructor(changeIndex, detail) {
|
|
2339
2346
|
super(`change ${changeIndex}: ${detail}`);
|
|
2340
2347
|
this.changeIndex = changeIndex;
|
|
2341
2348
|
this.detail = detail;
|
|
2349
|
+
this.name = "WorkspaceEditValidationError";
|
|
2342
2350
|
}
|
|
2343
2351
|
}
|
|
2344
2352
|
function isRecord3(value) {
|
|
@@ -2820,10 +2828,9 @@ function simulateDelete(operation, virtual) {
|
|
|
2820
2828
|
}
|
|
2821
2829
|
|
|
2822
2830
|
class WorkspaceSnapshotBuilder {
|
|
2823
|
-
workspaceRoot;
|
|
2824
|
-
snapshots = new Map;
|
|
2825
2831
|
constructor(workspaceRoot) {
|
|
2826
2832
|
this.workspaceRoot = workspaceRoot;
|
|
2833
|
+
this.snapshots = new Map;
|
|
2827
2834
|
}
|
|
2828
2835
|
build(operations) {
|
|
2829
2836
|
this.add(this.workspaceRoot, false);
|
|
@@ -2866,8 +2873,10 @@ function snapshotOperations(operations, workspaceRoot) {
|
|
|
2866
2873
|
}
|
|
2867
2874
|
|
|
2868
2875
|
class PlanPathIndex {
|
|
2869
|
-
|
|
2870
|
-
|
|
2876
|
+
constructor() {
|
|
2877
|
+
this.firstChangeByPath = new Map;
|
|
2878
|
+
this.reportedPathByCanonical = new Map;
|
|
2879
|
+
}
|
|
2871
2880
|
build(operations) {
|
|
2872
2881
|
for (const operation of operations) {
|
|
2873
2882
|
switch (operation.kind) {
|
|
@@ -2954,14 +2963,11 @@ function isRecord4(value) {
|
|
|
2954
2963
|
}
|
|
2955
2964
|
|
|
2956
2965
|
class WorkspaceMutationController {
|
|
2957
|
-
workspaceRoot;
|
|
2958
|
-
documents;
|
|
2959
|
-
activeLease = null;
|
|
2960
|
-
nextLeaseId = 1;
|
|
2961
|
-
io;
|
|
2962
2966
|
constructor(workspaceRoot, documents) {
|
|
2963
2967
|
this.workspaceRoot = workspaceRoot;
|
|
2964
2968
|
this.documents = documents;
|
|
2969
|
+
this.activeLease = null;
|
|
2970
|
+
this.nextLeaseId = 1;
|
|
2965
2971
|
}
|
|
2966
2972
|
setIo(io) {
|
|
2967
2973
|
this.io = io;
|
|
@@ -3072,12 +3078,9 @@ var DIAGNOSTICS_FRESHNESS_TIMEOUT_MS = 3000;
|
|
|
3072
3078
|
var VERSIONLESS_PUBLISH_QUIESCENCE_MS = 250;
|
|
3073
3079
|
|
|
3074
3080
|
class LspClient extends LspClientConnection {
|
|
3075
|
-
diagnosticPullErrors = [];
|
|
3076
|
-
documents;
|
|
3077
|
-
workspaceMutations;
|
|
3078
|
-
diagnosticsFreshnessTimeoutMs;
|
|
3079
3081
|
constructor(root, server2, options = {}) {
|
|
3080
3082
|
super(root, server2, options);
|
|
3083
|
+
this.diagnosticPullErrors = [];
|
|
3081
3084
|
this.diagnosticsFreshnessTimeoutMs = options.diagnosticsFreshnessTimeoutMs ?? DIAGNOSTICS_FRESHNESS_TIMEOUT_MS;
|
|
3082
3085
|
this.documents = new WorkspaceDocumentState((method, params) => this.sendNotification(method, params), (uri) => this.diagnosticsStore.delete(uri), {
|
|
3083
3086
|
versionlessPublishQuiescenceMs: options.versionlessPublishQuiescenceMs ?? VERSIONLESS_PUBLISH_QUIESCENCE_MS
|
|
@@ -3132,6 +3135,18 @@ class LspClient extends LspClientConnection {
|
|
|
3132
3135
|
textDocument: { uri: pathToFileURL3(absPath).href }
|
|
3133
3136
|
}, options);
|
|
3134
3137
|
}
|
|
3138
|
+
async formatDocument(filePath, options, signal) {
|
|
3139
|
+
if (!this.isDocumentFormattingSupported())
|
|
3140
|
+
return null;
|
|
3141
|
+
const absPath = this.resolveWorkspacePath(filePath);
|
|
3142
|
+
await this.openFile(absPath);
|
|
3143
|
+
const requestOptions = signal === undefined ? {} : { signal };
|
|
3144
|
+
const edits = await this.sendRequest("textDocument/formatting", {
|
|
3145
|
+
textDocument: { uri: pathToFileURL3(absPath).href },
|
|
3146
|
+
options
|
|
3147
|
+
}, requestOptions);
|
|
3148
|
+
return edits ?? [];
|
|
3149
|
+
}
|
|
3135
3150
|
async workspaceSymbols(query, signal) {
|
|
3136
3151
|
const options = signal === undefined ? {} : { signal };
|
|
3137
3152
|
return this.sendRequest("workspace/symbol", { query }, options);
|
|
@@ -3373,18 +3388,16 @@ function awaitWithSignal2(promise, signal) {
|
|
|
3373
3388
|
}
|
|
3374
3389
|
|
|
3375
3390
|
class LspManager {
|
|
3376
|
-
clients = new Map;
|
|
3377
|
-
reaperHandle = null;
|
|
3378
|
-
signalDisposer = null;
|
|
3379
|
-
disposed = false;
|
|
3380
|
-
idleTimeoutMs;
|
|
3381
|
-
initTimeoutMs;
|
|
3382
|
-
reaperIntervalMs;
|
|
3383
|
-
clientFactory;
|
|
3384
|
-
now;
|
|
3385
3391
|
constructor(options = {}) {
|
|
3392
|
+
this.clients = new Map;
|
|
3393
|
+
this.pendingStops = new Map;
|
|
3394
|
+
this.respawnBudgets = new Map;
|
|
3395
|
+
this.reaperHandle = null;
|
|
3396
|
+
this.signalDisposer = null;
|
|
3397
|
+
this.disposed = false;
|
|
3386
3398
|
this.idleTimeoutMs = options.idleTimeoutMs ?? IDLE_TIMEOUT_MS;
|
|
3387
3399
|
this.initTimeoutMs = options.initTimeoutMs ?? INIT_TIMEOUT_MS;
|
|
3400
|
+
this.maxResidentClients = options.maxResidentClients ?? MAX_RESIDENT_CLIENTS;
|
|
3388
3401
|
this.reaperIntervalMs = options.reaperIntervalMs ?? REAPER_INTERVAL_MS;
|
|
3389
3402
|
this.clientFactory = options.clientFactory ?? ((root, server2) => new LspClient(root, server2));
|
|
3390
3403
|
this.now = options.now ?? (() => Date.now());
|
|
@@ -3404,24 +3417,79 @@ class LspManager {
|
|
|
3404
3417
|
getKey(root, serverId) {
|
|
3405
3418
|
return `${root}::${serverId}`;
|
|
3406
3419
|
}
|
|
3420
|
+
tombstoneStop(key, client) {
|
|
3421
|
+
const stop = stopClientBestEffort(client);
|
|
3422
|
+
this.pendingStops.set(key, stop);
|
|
3423
|
+
stop.finally(() => {
|
|
3424
|
+
if (this.pendingStops.get(key) === stop) {
|
|
3425
|
+
this.pendingStops.delete(key);
|
|
3426
|
+
}
|
|
3427
|
+
});
|
|
3428
|
+
return stop;
|
|
3429
|
+
}
|
|
3430
|
+
recordDeadGeneration(key) {
|
|
3431
|
+
let budget = this.respawnBudgets.get(key);
|
|
3432
|
+
if (budget === undefined) {
|
|
3433
|
+
budget = { deadGenerations: 0, exhaustedAt: null };
|
|
3434
|
+
this.respawnBudgets.set(key, budget);
|
|
3435
|
+
}
|
|
3436
|
+
budget.deadGenerations += 1;
|
|
3437
|
+
}
|
|
3438
|
+
markHealthyGeneration(key) {
|
|
3439
|
+
this.respawnBudgets.delete(key);
|
|
3440
|
+
}
|
|
3441
|
+
ensureRespawnAllowed(key, root, serverId) {
|
|
3442
|
+
const budget = this.respawnBudgets.get(key);
|
|
3443
|
+
if (budget === undefined || budget.deadGenerations < CLIENT_RESPAWN_RETRY_LIMIT)
|
|
3444
|
+
return;
|
|
3445
|
+
if (budget.exhaustedAt === null) {
|
|
3446
|
+
budget.exhaustedAt = this.now();
|
|
3447
|
+
throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
|
|
3448
|
+
}
|
|
3449
|
+
if (this.now() - budget.exhaustedAt < CLIENT_RESPAWN_COOLDOWN_MS) {
|
|
3450
|
+
throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
|
|
3451
|
+
}
|
|
3452
|
+
budget.deadGenerations = 0;
|
|
3453
|
+
budget.exhaustedAt = null;
|
|
3454
|
+
}
|
|
3407
3455
|
reapStale() {
|
|
3408
3456
|
const t = this.now();
|
|
3409
3457
|
for (const [key, managed] of this.clients) {
|
|
3410
3458
|
if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
|
|
3411
|
-
stopClientBestEffort(managed.client);
|
|
3412
3459
|
this.clients.delete(key);
|
|
3460
|
+
this.tombstoneStop(key, managed.client);
|
|
3413
3461
|
continue;
|
|
3414
3462
|
}
|
|
3415
3463
|
if (!managed.isInitializing && managed.refCount === 0 && managed.pendingWaiters === 0 && t - managed.lastUsedAt > this.idleTimeoutMs) {
|
|
3416
|
-
stopClientBestEffort(managed.client);
|
|
3417
3464
|
this.clients.delete(key);
|
|
3465
|
+
this.tombstoneStop(key, managed.client);
|
|
3466
|
+
}
|
|
3467
|
+
}
|
|
3468
|
+
}
|
|
3469
|
+
evictForAdmission() {
|
|
3470
|
+
while (this.clients.size >= this.maxResidentClients) {
|
|
3471
|
+
const victim = this.leastRecentlyUsedIdleClient();
|
|
3472
|
+
if (!victim)
|
|
3473
|
+
return;
|
|
3474
|
+
this.clients.delete(victim.key);
|
|
3475
|
+
this.tombstoneStop(victim.key, victim.managed.client);
|
|
3476
|
+
}
|
|
3477
|
+
}
|
|
3478
|
+
leastRecentlyUsedIdleClient() {
|
|
3479
|
+
let candidate = null;
|
|
3480
|
+
for (const [key, managed] of this.clients) {
|
|
3481
|
+
if (managed.refCount > 0 || managed.pendingWaiters > 0 || managed.isInitializing)
|
|
3482
|
+
continue;
|
|
3483
|
+
if (candidate === null || managed.lastUsedAt < candidate.managed.lastUsedAt) {
|
|
3484
|
+
candidate = { key, managed };
|
|
3418
3485
|
}
|
|
3419
3486
|
}
|
|
3487
|
+
return candidate;
|
|
3420
3488
|
}
|
|
3421
3489
|
async tryDeleteIfOrphaned(key, managed) {
|
|
3422
3490
|
if (managed.refCount === 0 && managed.pendingWaiters === 0 && !managed.isInitializing && this.clients.get(key) === managed) {
|
|
3423
3491
|
this.clients.delete(key);
|
|
3424
|
-
await
|
|
3492
|
+
await this.tombstoneStop(key, managed.client);
|
|
3425
3493
|
}
|
|
3426
3494
|
}
|
|
3427
3495
|
async getClient(root, server2, signal) {
|
|
@@ -3430,12 +3498,22 @@ class LspManager {
|
|
|
3430
3498
|
}
|
|
3431
3499
|
signal?.throwIfAborted();
|
|
3432
3500
|
const key = this.getKey(root, server2.id);
|
|
3501
|
+
for (;; ) {
|
|
3502
|
+
const pendingStop = this.pendingStops.get(key);
|
|
3503
|
+
if (pendingStop === undefined)
|
|
3504
|
+
break;
|
|
3505
|
+
await awaitWithSignal2(pendingStop, signal);
|
|
3506
|
+
signal?.throwIfAborted();
|
|
3507
|
+
}
|
|
3508
|
+
if (this.disposed) {
|
|
3509
|
+
throw new Error("LspManager has been disposed");
|
|
3510
|
+
}
|
|
3433
3511
|
let managed = this.clients.get(key);
|
|
3434
3512
|
if (managed) {
|
|
3435
3513
|
const t = this.now();
|
|
3436
3514
|
if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
|
|
3437
|
-
await stopClientBestEffort(managed.client);
|
|
3438
3515
|
this.clients.delete(key);
|
|
3516
|
+
await this.tombstoneStop(key, managed.client);
|
|
3439
3517
|
managed = undefined;
|
|
3440
3518
|
}
|
|
3441
3519
|
}
|
|
@@ -3456,14 +3534,20 @@ class LspManager {
|
|
|
3456
3534
|
signal.throwIfAborted();
|
|
3457
3535
|
}
|
|
3458
3536
|
if (!managed.client.isAlive()) {
|
|
3459
|
-
|
|
3460
|
-
this.clients.
|
|
3537
|
+
this.recordDeadGeneration(key);
|
|
3538
|
+
if (this.clients.get(key) === managed) {
|
|
3539
|
+
this.clients.delete(key);
|
|
3540
|
+
}
|
|
3541
|
+
await this.tombstoneStop(key, managed.client);
|
|
3461
3542
|
return this.getClient(root, server2, signal);
|
|
3462
3543
|
}
|
|
3544
|
+
this.markHealthyGeneration(key);
|
|
3463
3545
|
managed.refCount++;
|
|
3464
3546
|
managed.lastUsedAt = this.now();
|
|
3465
3547
|
return managed.client;
|
|
3466
3548
|
}
|
|
3549
|
+
this.evictForAdmission();
|
|
3550
|
+
this.ensureRespawnAllowed(key, root, server2.id);
|
|
3467
3551
|
const client = this.clientFactory(root, server2);
|
|
3468
3552
|
const initStartedAt = this.now();
|
|
3469
3553
|
const initPromise = (async () => {
|
|
@@ -3487,7 +3571,7 @@ class LspManager {
|
|
|
3487
3571
|
if (this.clients.get(key) === newManaged) {
|
|
3488
3572
|
this.clients.delete(key);
|
|
3489
3573
|
}
|
|
3490
|
-
await
|
|
3574
|
+
await this.tombstoneStop(key, client);
|
|
3491
3575
|
throw err;
|
|
3492
3576
|
}
|
|
3493
3577
|
newManaged.pendingWaiters--;
|
|
@@ -3498,6 +3582,15 @@ class LspManager {
|
|
|
3498
3582
|
await this.tryDeleteIfOrphaned(key, newManaged);
|
|
3499
3583
|
signal.throwIfAborted();
|
|
3500
3584
|
}
|
|
3585
|
+
if (!client.isAlive()) {
|
|
3586
|
+
this.recordDeadGeneration(key);
|
|
3587
|
+
if (this.clients.get(key) === newManaged) {
|
|
3588
|
+
this.clients.delete(key);
|
|
3589
|
+
}
|
|
3590
|
+
await this.tombstoneStop(key, client);
|
|
3591
|
+
return this.getClient(root, server2, signal);
|
|
3592
|
+
}
|
|
3593
|
+
this.markHealthyGeneration(key);
|
|
3501
3594
|
newManaged.refCount++;
|
|
3502
3595
|
newManaged.lastUsedAt = this.now();
|
|
3503
3596
|
return client;
|
|
@@ -3518,14 +3611,20 @@ class LspManager {
|
|
|
3518
3611
|
if (client && managed.client !== client)
|
|
3519
3612
|
return;
|
|
3520
3613
|
this.clients.delete(key);
|
|
3521
|
-
|
|
3614
|
+
this.tombstoneStop(key, managed.client);
|
|
3522
3615
|
}
|
|
3523
3616
|
warmupClient(root, server2) {
|
|
3524
3617
|
if (this.disposed)
|
|
3525
3618
|
return;
|
|
3526
3619
|
const key = this.getKey(root, server2.id);
|
|
3527
|
-
if (this.clients.has(key))
|
|
3620
|
+
if (this.clients.has(key) || this.pendingStops.has(key))
|
|
3528
3621
|
return;
|
|
3622
|
+
this.evictForAdmission();
|
|
3623
|
+
try {
|
|
3624
|
+
this.ensureRespawnAllowed(key, root, server2.id);
|
|
3625
|
+
} catch {
|
|
3626
|
+
return;
|
|
3627
|
+
}
|
|
3529
3628
|
const client = this.clientFactory(root, server2);
|
|
3530
3629
|
const initStartedAt = this.now();
|
|
3531
3630
|
const initPromise = (async () => {
|
|
@@ -3551,7 +3650,7 @@ class LspManager {
|
|
|
3551
3650
|
if (this.clients.get(key) === managed) {
|
|
3552
3651
|
this.clients.delete(key);
|
|
3553
3652
|
}
|
|
3554
|
-
|
|
3653
|
+
this.tombstoneStop(key, client);
|
|
3555
3654
|
});
|
|
3556
3655
|
}
|
|
3557
3656
|
isServerInitializing(root, serverId) {
|
|
@@ -3595,8 +3694,11 @@ class LspManager {
|
|
|
3595
3694
|
for (const managed of this.clients.values()) {
|
|
3596
3695
|
stopPromises.push(stopClientBestEffort(managed.client));
|
|
3597
3696
|
}
|
|
3697
|
+
const tombstonedStops = [...this.pendingStops.values()];
|
|
3598
3698
|
this.clients.clear();
|
|
3599
|
-
|
|
3699
|
+
this.respawnBudgets.clear();
|
|
3700
|
+
await Promise.allSettled([...stopPromises, ...tombstonedStops]);
|
|
3701
|
+
this.pendingStops.clear();
|
|
3600
3702
|
}
|
|
3601
3703
|
}
|
|
3602
3704
|
var _defaultInstance = null;
|
|
@@ -3606,49 +3708,43 @@ function getLspManager() {
|
|
|
3606
3708
|
}
|
|
3607
3709
|
return _defaultInstance;
|
|
3608
3710
|
}
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
|
|
3711
|
+
var GIT_WORKSPACE_MARKER = ".git";
|
|
3712
|
+
var PROJECT_WORKSPACE_MARKERS = [
|
|
3713
|
+
"package.json",
|
|
3714
|
+
"pyproject.toml",
|
|
3715
|
+
"Cargo.toml",
|
|
3716
|
+
"go.mod",
|
|
3717
|
+
"pom.xml",
|
|
3718
|
+
"build.gradle"
|
|
3719
|
+
];
|
|
3720
|
+
var WORKSPACE_MARKERS = [GIT_WORKSPACE_MARKER, ...PROJECT_WORKSPACE_MARKERS];
|
|
3721
|
+
function findWorkspaceRootOutsideContext(directory) {
|
|
3722
|
+
const marked = nearestMarkedAncestor(directory);
|
|
3723
|
+
if (marked !== undefined)
|
|
3724
|
+
return marked;
|
|
3725
|
+
return realpathSync4(nearestExistingAncestor(directory));
|
|
3726
|
+
}
|
|
3727
|
+
function nearestMarkedAncestor(directory) {
|
|
3728
|
+
let current = directory;
|
|
3729
|
+
for (;; ) {
|
|
3730
|
+
if (existsSync7(current) && WORKSPACE_MARKERS.some((marker) => existsSync7(join3(current, marker)))) {
|
|
3731
|
+
return realpathSync4(current);
|
|
3732
|
+
}
|
|
3733
|
+
const parent = dirname7(current);
|
|
3734
|
+
if (parent === current)
|
|
3735
|
+
return;
|
|
3736
|
+
current = parent;
|
|
3621
3737
|
}
|
|
3622
3738
|
}
|
|
3623
|
-
function
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
|
|
3629
|
-
|
|
3630
|
-
}
|
|
3631
|
-
|
|
3632
|
-
return value === "declined" || value === "allowed";
|
|
3633
|
-
}
|
|
3634
|
-
function writeInstallDecisions(decisions) {
|
|
3635
|
-
const path2 = getInstallDecisionsPath();
|
|
3636
|
-
mkdirSync3(dirname7(path2), { recursive: true });
|
|
3637
|
-
const tmpPath = `${path2}.tmp`;
|
|
3638
|
-
writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
|
|
3639
|
-
`, "utf8");
|
|
3640
|
-
renameSync2(tmpPath, path2);
|
|
3641
|
-
}
|
|
3642
|
-
function isInstallDecisions(value) {
|
|
3643
|
-
return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
|
|
3644
|
-
}
|
|
3645
|
-
function isInstallDecisionRecord(value) {
|
|
3646
|
-
if (!isRecord5(value))
|
|
3647
|
-
return false;
|
|
3648
|
-
return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
|
|
3649
|
-
}
|
|
3650
|
-
function isRecord5(value) {
|
|
3651
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3739
|
+
function nearestExistingAncestor(directory) {
|
|
3740
|
+
let current = directory;
|
|
3741
|
+
while (!existsSync7(current)) {
|
|
3742
|
+
const parent = dirname7(current);
|
|
3743
|
+
if (parent === current)
|
|
3744
|
+
return current;
|
|
3745
|
+
current = parent;
|
|
3746
|
+
}
|
|
3747
|
+
return current;
|
|
3652
3748
|
}
|
|
3653
3749
|
var LSP_INSTALL_HINTS = {
|
|
3654
3750
|
typescript: "npm install -g typescript-language-server typescript",
|
|
@@ -3694,6 +3790,26 @@ var LSP_INSTALL_HINTS = {
|
|
|
3694
3790
|
julials: `julia -e 'using Pkg; Pkg.add("LanguageServer")'`,
|
|
3695
3791
|
razor: "Razor runs through the Roslyn language server (cohosting). " + "Install: dotnet tool install -g roslyn-language-server --prerelease (requires v5.8.0+). See https://github.com/dotnet/razor"
|
|
3696
3792
|
};
|
|
3793
|
+
var LSP_LOCAL_INSTALL_HINTS = {
|
|
3794
|
+
typescript: "bun add -d typescript-language-server typescript",
|
|
3795
|
+
vue: "bun add -d @vue/language-server",
|
|
3796
|
+
eslint: "bun add -d vscode-langservers-extracted",
|
|
3797
|
+
oxlint: "bun add -d oxlint",
|
|
3798
|
+
biome: "bun add -d @biomejs/biome",
|
|
3799
|
+
svelte: "bun add -d svelte-language-server",
|
|
3800
|
+
astro: "bun add -d @astrojs/language-server",
|
|
3801
|
+
bash: "bun add -d bash-language-server",
|
|
3802
|
+
"bash-ls": "bun add -d bash-language-server",
|
|
3803
|
+
"yaml-ls": "bun add -d yaml-language-server",
|
|
3804
|
+
php: "bun add -d intelephense",
|
|
3805
|
+
prisma: "bun add -d prisma",
|
|
3806
|
+
dockerfile: "bun add -d dockerfile-language-server-nodejs",
|
|
3807
|
+
pyright: "uv add --dev pyright",
|
|
3808
|
+
basedpyright: "uv add --dev basedpyright",
|
|
3809
|
+
ruff: "uv add --dev ruff",
|
|
3810
|
+
ty: "uv add --dev ty",
|
|
3811
|
+
"ruby-lsp": "bundle add ruby-lsp --group development"
|
|
3812
|
+
};
|
|
3697
3813
|
var BUILTIN_SERVERS = {
|
|
3698
3814
|
typescript: {
|
|
3699
3815
|
command: ["typescript-language-server", "--stdio"],
|
|
@@ -3795,6 +3911,50 @@ var BUILTIN_SERVERS = {
|
|
|
3795
3911
|
extensions: [".razor", ".cshtml"]
|
|
3796
3912
|
}
|
|
3797
3913
|
};
|
|
3914
|
+
function getInstallDecisionsPath() {
|
|
3915
|
+
return lspRequestContext().installDecisionsPath;
|
|
3916
|
+
}
|
|
3917
|
+
function loadInstallDecisions() {
|
|
3918
|
+
const path2 = getInstallDecisionsPath();
|
|
3919
|
+
if (!existsSync8(path2))
|
|
3920
|
+
return {};
|
|
3921
|
+
try {
|
|
3922
|
+
const parsed = JSON.parse(readFileSync4(path2, "utf8"));
|
|
3923
|
+
return isInstallDecisions(parsed) ? parsed : {};
|
|
3924
|
+
} catch {
|
|
3925
|
+
return {};
|
|
3926
|
+
}
|
|
3927
|
+
}
|
|
3928
|
+
function loadInstallDecision(serverId) {
|
|
3929
|
+
return loadInstallDecisions()[serverId];
|
|
3930
|
+
}
|
|
3931
|
+
function recordInstallDecision(serverId, decision, decidedAt = new Date().toISOString()) {
|
|
3932
|
+
const decisions = loadInstallDecisions();
|
|
3933
|
+
decisions[serverId] = { decision, decidedAt };
|
|
3934
|
+
writeInstallDecisions(decisions);
|
|
3935
|
+
}
|
|
3936
|
+
function isInstallDecision(value) {
|
|
3937
|
+
return value === "declined" || value === "allowed";
|
|
3938
|
+
}
|
|
3939
|
+
function writeInstallDecisions(decisions) {
|
|
3940
|
+
const path2 = getInstallDecisionsPath();
|
|
3941
|
+
mkdirSync3(dirname8(path2), { recursive: true });
|
|
3942
|
+
const tmpPath = `${path2}.tmp`;
|
|
3943
|
+
writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
|
|
3944
|
+
`, "utf8");
|
|
3945
|
+
renameSync2(tmpPath, path2);
|
|
3946
|
+
}
|
|
3947
|
+
function isInstallDecisions(value) {
|
|
3948
|
+
return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
|
|
3949
|
+
}
|
|
3950
|
+
function isInstallDecisionRecord(value) {
|
|
3951
|
+
if (!isRecord5(value))
|
|
3952
|
+
return false;
|
|
3953
|
+
return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
|
|
3954
|
+
}
|
|
3955
|
+
function isRecord5(value) {
|
|
3956
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3957
|
+
}
|
|
3798
3958
|
function getProjectConfigPaths() {
|
|
3799
3959
|
return lspRequestContext().projectConfigPaths;
|
|
3800
3960
|
}
|
|
@@ -3802,7 +3962,7 @@ function getUserConfigPath() {
|
|
|
3802
3962
|
return lspRequestContext().userConfigPath;
|
|
3803
3963
|
}
|
|
3804
3964
|
function loadJsonFile(path2) {
|
|
3805
|
-
if (!
|
|
3965
|
+
if (!existsSync9(path2))
|
|
3806
3966
|
return null;
|
|
3807
3967
|
try {
|
|
3808
3968
|
const parsed = JSON.parse(readFileSync5(path2, "utf-8"));
|
|
@@ -3988,50 +4148,151 @@ function getDisabledServerIds() {
|
|
|
3988
4148
|
}
|
|
3989
4149
|
return disabled;
|
|
3990
4150
|
}
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
|
-
|
|
3994
|
-
|
|
3995
|
-
|
|
3996
|
-
|
|
3997
|
-
|
|
3998
|
-
|
|
3999
|
-
|
|
4151
|
+
var LOCAL_BIN_RULES = [
|
|
4152
|
+
{
|
|
4153
|
+
markers: ["package.json", "bun.lock", "bun.lockb", "package-lock.json", "yarn.lock", "pnpm-lock.yaml"],
|
|
4154
|
+
binDirs: [join4("node_modules", ".bin")]
|
|
4155
|
+
},
|
|
4156
|
+
{
|
|
4157
|
+
markers: [
|
|
4158
|
+
"pyproject.toml",
|
|
4159
|
+
"ty.toml",
|
|
4160
|
+
"requirements.txt",
|
|
4161
|
+
"setup.py",
|
|
4162
|
+
"setup.cfg",
|
|
4163
|
+
"Pipfile",
|
|
4164
|
+
"pyrightconfig.json",
|
|
4165
|
+
"ruff.toml",
|
|
4166
|
+
".ruff.toml"
|
|
4167
|
+
],
|
|
4168
|
+
binDirs: [
|
|
4169
|
+
join4(".venv", "bin"),
|
|
4170
|
+
join4(".venv", "Scripts"),
|
|
4171
|
+
join4("venv", "bin"),
|
|
4172
|
+
join4("venv", "Scripts"),
|
|
4173
|
+
join4(".env", "bin"),
|
|
4174
|
+
join4(".env", "Scripts")
|
|
4175
|
+
]
|
|
4176
|
+
},
|
|
4177
|
+
{
|
|
4178
|
+
markers: ["Gemfile", "Gemfile.lock"],
|
|
4179
|
+
binDirs: [join4("vendor", "bundle", "bin"), "bin"]
|
|
4180
|
+
},
|
|
4181
|
+
{
|
|
4182
|
+
markers: ["go.mod", "go.sum", "go.work"],
|
|
4183
|
+
binDirs: ["bin"]
|
|
4184
|
+
}
|
|
4185
|
+
];
|
|
4186
|
+
var resolutionCache = new Map;
|
|
4187
|
+
var probeCount = 0;
|
|
4188
|
+
function probe(path2) {
|
|
4189
|
+
probeCount += 1;
|
|
4190
|
+
return existsSync10(path2);
|
|
4191
|
+
}
|
|
4192
|
+
function executableSuffixes(platform, pathExt) {
|
|
4193
|
+
if (platform !== "win32")
|
|
4194
|
+
return [""];
|
|
4195
|
+
const configured = pathExt ?? process.env["PATHEXT"] ?? "";
|
|
4196
|
+
const systemExts = configured.split(";").filter((entry) => entry.length > 0).map((entry) => entry.toLowerCase());
|
|
4197
|
+
return [...new Set(["", ...systemExts, ".exe", ".cmd", ".bat", ".ps1"])];
|
|
4198
|
+
}
|
|
4199
|
+
function probeWithSuffixes(directory, command, suffixes) {
|
|
4200
|
+
for (const suffix of suffixes) {
|
|
4201
|
+
const candidate = join4(directory, command + suffix);
|
|
4202
|
+
if (probe(candidate))
|
|
4203
|
+
return candidate;
|
|
4000
4204
|
}
|
|
4001
|
-
|
|
4002
|
-
|
|
4003
|
-
|
|
4004
|
-
|
|
4005
|
-
|
|
4006
|
-
|
|
4007
|
-
|
|
4008
|
-
|
|
4009
|
-
|
|
4205
|
+
return null;
|
|
4206
|
+
}
|
|
4207
|
+
function resolveLocal(command, workingDirectory, suffixes, stopAt) {
|
|
4208
|
+
const boundary = stopAt === undefined ? undefined : resolve7(stopAt);
|
|
4209
|
+
let current = resolve7(workingDirectory);
|
|
4210
|
+
while (true) {
|
|
4211
|
+
for (const rule of LOCAL_BIN_RULES) {
|
|
4212
|
+
if (!rule.markers.some((marker) => probe(join4(current, marker))))
|
|
4213
|
+
continue;
|
|
4214
|
+
for (const binDir of rule.binDirs) {
|
|
4215
|
+
const found = probeWithSuffixes(join4(current, binDir), command, suffixes);
|
|
4216
|
+
if (found !== null)
|
|
4217
|
+
return found;
|
|
4218
|
+
}
|
|
4010
4219
|
}
|
|
4220
|
+
if (probe(join4(current, ".git")))
|
|
4221
|
+
return null;
|
|
4222
|
+
if (boundary !== undefined && current === boundary)
|
|
4223
|
+
return null;
|
|
4224
|
+
const parent = dirname9(current);
|
|
4225
|
+
if (parent === current)
|
|
4226
|
+
return null;
|
|
4227
|
+
current = parent;
|
|
4011
4228
|
}
|
|
4012
|
-
|
|
4013
|
-
|
|
4229
|
+
}
|
|
4230
|
+
function resolveFromPath(command, suffixes, platform, pathEnvOverride) {
|
|
4231
|
+
let pathEnv = pathEnvOverride ?? process.env["PATH"] ?? "";
|
|
4232
|
+
if (platform === "win32" && !pathEnv) {
|
|
4014
4233
|
pathEnv = process.env["Path"] ?? "";
|
|
4015
4234
|
}
|
|
4016
|
-
const
|
|
4017
|
-
|
|
4018
|
-
|
|
4019
|
-
|
|
4020
|
-
|
|
4021
|
-
|
|
4022
|
-
}
|
|
4235
|
+
for (const entry of pathEnv.split(delimiter3)) {
|
|
4236
|
+
if (entry.length === 0)
|
|
4237
|
+
continue;
|
|
4238
|
+
const found = probeWithSuffixes(entry, command, suffixes);
|
|
4239
|
+
if (found !== null)
|
|
4240
|
+
return found;
|
|
4023
4241
|
}
|
|
4024
|
-
|
|
4025
|
-
|
|
4026
|
-
|
|
4242
|
+
return null;
|
|
4243
|
+
}
|
|
4244
|
+
function resolveServerBinary(command, workingDirectory, options = {}) {
|
|
4245
|
+
if (command.length === 0)
|
|
4246
|
+
return null;
|
|
4247
|
+
const [cmd] = command;
|
|
4248
|
+
if (cmd === undefined || cmd.length === 0)
|
|
4249
|
+
return null;
|
|
4250
|
+
const platform = options.platform ?? process.platform;
|
|
4251
|
+
const suffixes = executableSuffixes(platform, options.pathExt);
|
|
4252
|
+
if (cmd.includes("/") || cmd.includes("\\")) {
|
|
4253
|
+
const explicit = isAbsolute5(cmd) ? cmd : resolve7(workingDirectory ?? process.cwd(), cmd);
|
|
4254
|
+
return probe(explicit) ? explicit : null;
|
|
4255
|
+
}
|
|
4256
|
+
const cacheKey = JSON.stringify([
|
|
4257
|
+
workingDirectory ?? "",
|
|
4258
|
+
cmd,
|
|
4259
|
+
platform,
|
|
4260
|
+
options.stopAt ?? "",
|
|
4261
|
+
options.pathExt ?? "",
|
|
4262
|
+
options.pathEnv ?? process.env["PATH"] ?? ""
|
|
4263
|
+
]);
|
|
4264
|
+
const cached = resolutionCache.get(cacheKey);
|
|
4265
|
+
if (cached !== undefined)
|
|
4266
|
+
return cached;
|
|
4267
|
+
let resolved = null;
|
|
4268
|
+
if (workingDirectory !== undefined && workingDirectory.length > 0) {
|
|
4269
|
+
resolved = resolveLocal(cmd, workingDirectory, suffixes, options.stopAt);
|
|
4270
|
+
}
|
|
4271
|
+
resolved ??= resolveFromPath(cmd, suffixes, platform, options.pathEnv);
|
|
4272
|
+
if (resolved === null && cmd === "node")
|
|
4273
|
+
resolved = cmd;
|
|
4274
|
+
resolutionCache.set(cacheKey, resolved);
|
|
4275
|
+
return resolved;
|
|
4276
|
+
}
|
|
4277
|
+
function isServerInstalled(command, workingDirectory, options = {}) {
|
|
4278
|
+
if (command.length === 0)
|
|
4279
|
+
return false;
|
|
4280
|
+
return resolveServerBinary(command, workingDirectory, options) !== null;
|
|
4281
|
+
}
|
|
4282
|
+
function withResolvedCommand(command, binaryPath) {
|
|
4283
|
+
return [binaryPath, ...command.slice(1)];
|
|
4027
4284
|
}
|
|
4028
4285
|
function findServerForExtension(ext) {
|
|
4029
4286
|
const servers = getMergedServers();
|
|
4287
|
+
const workingDirectory = contextCwd();
|
|
4030
4288
|
for (const server2 of servers) {
|
|
4031
|
-
if (server2.extensions.includes(ext)
|
|
4289
|
+
if (!server2.extensions.includes(ext))
|
|
4290
|
+
continue;
|
|
4291
|
+
const binaryPath = resolveServerBinary(server2.command, workingDirectory);
|
|
4292
|
+
if (binaryPath !== null) {
|
|
4032
4293
|
const resolvedServer = {
|
|
4033
4294
|
id: server2.id,
|
|
4034
|
-
command: server2.command,
|
|
4295
|
+
command: withResolvedCommand(server2.command, binaryPath),
|
|
4035
4296
|
extensions: server2.extensions,
|
|
4036
4297
|
priority: server2.priority
|
|
4037
4298
|
};
|
|
@@ -4078,6 +4339,7 @@ function findServerForExtension(ext) {
|
|
|
4078
4339
|
function getAllServers() {
|
|
4079
4340
|
const servers = getMergedServers();
|
|
4080
4341
|
const disabled = getDisabledServerIds();
|
|
4342
|
+
const workingDirectory = contextCwd();
|
|
4081
4343
|
const result = [];
|
|
4082
4344
|
const seen = new Set;
|
|
4083
4345
|
for (const server2 of servers) {
|
|
@@ -4085,7 +4347,7 @@ function getAllServers() {
|
|
|
4085
4347
|
continue;
|
|
4086
4348
|
result.push({
|
|
4087
4349
|
id: server2.id,
|
|
4088
|
-
installed: isServerInstalled(server2.command),
|
|
4350
|
+
installed: isServerInstalled(server2.command, workingDirectory),
|
|
4089
4351
|
extensions: server2.extensions,
|
|
4090
4352
|
disabled: false,
|
|
4091
4353
|
source: server2.source,
|
|
@@ -4099,7 +4361,7 @@ function getAllServers() {
|
|
|
4099
4361
|
const builtin = BUILTIN_SERVERS[id];
|
|
4100
4362
|
result.push({
|
|
4101
4363
|
id,
|
|
4102
|
-
installed: builtin ? isServerInstalled(builtin.command) : false,
|
|
4364
|
+
installed: builtin ? isServerInstalled(builtin.command, workingDirectory) : false,
|
|
4103
4365
|
extensions: builtin?.extensions ?? [],
|
|
4104
4366
|
disabled: true,
|
|
4105
4367
|
source: "disabled",
|
|
@@ -4108,7 +4370,6 @@ function getAllServers() {
|
|
|
4108
4370
|
}
|
|
4109
4371
|
return result;
|
|
4110
4372
|
}
|
|
4111
|
-
var WORKSPACE_MARKERS = [".git", "package.json", "pyproject.toml", "Cargo.toml", "go.mod", "pom.xml", "build.gradle"];
|
|
4112
4373
|
function isDirectoryPath(filePath) {
|
|
4113
4374
|
try {
|
|
4114
4375
|
return statSync4(filePath).isDirectory();
|
|
@@ -4117,32 +4378,90 @@ function isDirectoryPath(filePath) {
|
|
|
4117
4378
|
}
|
|
4118
4379
|
}
|
|
4119
4380
|
function findWorkspaceRoot(filePath) {
|
|
4120
|
-
const
|
|
4381
|
+
const cwd = contextCwd();
|
|
4382
|
+
const abs = resolveReadablePathInsideContext(filePath);
|
|
4121
4383
|
let dir = abs;
|
|
4122
4384
|
if (!isDirectoryPath(dir)) {
|
|
4123
|
-
dir =
|
|
4124
|
-
}
|
|
4125
|
-
|
|
4126
|
-
|
|
4127
|
-
|
|
4128
|
-
|
|
4129
|
-
|
|
4385
|
+
dir = dirname10(dir);
|
|
4386
|
+
}
|
|
4387
|
+
if (!isPathInside(cwd, abs))
|
|
4388
|
+
return findWorkspaceRootOutsideContext(dir);
|
|
4389
|
+
const fallbackRoot = nearestExistingDirectoryInsideContext(dir, cwd) ?? cwd;
|
|
4390
|
+
let nearestPackageRoot;
|
|
4391
|
+
while (isPathInside(cwd, dir)) {
|
|
4392
|
+
const canonicalDir = existingDirectoryInsideContext(dir, cwd);
|
|
4393
|
+
if (canonicalDir !== undefined) {
|
|
4394
|
+
if (existsSync11(join5(dir, GIT_WORKSPACE_MARKER))) {
|
|
4395
|
+
return canonicalDir;
|
|
4396
|
+
}
|
|
4397
|
+
if (nearestPackageRoot === undefined && hasProjectWorkspaceMarker(dir)) {
|
|
4398
|
+
nearestPackageRoot = canonicalDir;
|
|
4130
4399
|
}
|
|
4131
4400
|
}
|
|
4132
|
-
|
|
4133
|
-
|
|
4401
|
+
if (dir === cwd)
|
|
4402
|
+
break;
|
|
4403
|
+
dir = dirname10(dir);
|
|
4134
4404
|
}
|
|
4135
|
-
return
|
|
4405
|
+
return nearestPackageRoot ?? fallbackRoot;
|
|
4406
|
+
}
|
|
4407
|
+
function hasProjectWorkspaceMarker(directory) {
|
|
4408
|
+
return PROJECT_WORKSPACE_MARKERS.some((marker) => existsSync11(join5(directory, marker)));
|
|
4409
|
+
}
|
|
4410
|
+
function resolveReadablePathInsideContext(filePath) {
|
|
4411
|
+
const cwd = contextCwd();
|
|
4412
|
+
const abs = resolve8(cwd, filePath);
|
|
4413
|
+
if (isPathInside(cwd, abs))
|
|
4414
|
+
return abs;
|
|
4415
|
+
const rebased = rebaseThroughCanonicalAncestor(abs, cwd);
|
|
4416
|
+
if (rebased !== undefined)
|
|
4417
|
+
return rebased;
|
|
4418
|
+
return canonicalizeExistingOrNearestAncestor(abs);
|
|
4136
4419
|
}
|
|
4137
4420
|
function resolvePathInsideContext(filePath) {
|
|
4138
4421
|
const cwd = contextCwd();
|
|
4139
|
-
const abs =
|
|
4422
|
+
const abs = resolveReadablePathInsideContext(filePath);
|
|
4140
4423
|
const canonical = canonicalizeExistingOrNearestAncestor(abs);
|
|
4141
4424
|
if (!isPathInside(cwd, canonical)) {
|
|
4142
4425
|
throw new LspInvalidPathError(`LSP file path must be inside request cwd: ${filePath}`);
|
|
4143
4426
|
}
|
|
4144
4427
|
return canonical;
|
|
4145
4428
|
}
|
|
4429
|
+
function rebaseThroughCanonicalAncestor(path2, cwd) {
|
|
4430
|
+
let current = path2;
|
|
4431
|
+
const suffix = [];
|
|
4432
|
+
while (true) {
|
|
4433
|
+
if (existsSync11(current)) {
|
|
4434
|
+
const canonical = realpathSync5(current);
|
|
4435
|
+
if (isPathInside(cwd, canonical))
|
|
4436
|
+
return suffix.length === 0 ? canonical : join5(canonical, ...suffix);
|
|
4437
|
+
}
|
|
4438
|
+
const parent = dirname10(current);
|
|
4439
|
+
if (parent === current)
|
|
4440
|
+
return;
|
|
4441
|
+
suffix.unshift(basename3(current));
|
|
4442
|
+
current = parent;
|
|
4443
|
+
}
|
|
4444
|
+
}
|
|
4445
|
+
function existingDirectoryInsideContext(directory, cwd) {
|
|
4446
|
+
if (!existsSync11(directory))
|
|
4447
|
+
return;
|
|
4448
|
+
const canonical = realpathSync5(directory);
|
|
4449
|
+
if (!statSync4(canonical).isDirectory())
|
|
4450
|
+
return;
|
|
4451
|
+
return isPathInside(cwd, canonical) ? canonical : undefined;
|
|
4452
|
+
}
|
|
4453
|
+
function nearestExistingDirectoryInsideContext(directory, cwd) {
|
|
4454
|
+
let current = directory;
|
|
4455
|
+
while (isPathInside(cwd, current)) {
|
|
4456
|
+
const canonical = existingDirectoryInsideContext(current, cwd);
|
|
4457
|
+
if (canonical !== undefined)
|
|
4458
|
+
return canonical;
|
|
4459
|
+
if (current === cwd)
|
|
4460
|
+
return;
|
|
4461
|
+
current = dirname10(current);
|
|
4462
|
+
}
|
|
4463
|
+
return;
|
|
4464
|
+
}
|
|
4146
4465
|
function formatServerLookupError(result) {
|
|
4147
4466
|
if (result.status === "not_installed") {
|
|
4148
4467
|
return formatNotInstalled(result);
|
|
@@ -4166,6 +4485,19 @@ function formatServerLookupError(result) {
|
|
|
4166
4485
|
].join(`
|
|
4167
4486
|
`);
|
|
4168
4487
|
}
|
|
4488
|
+
function formatInstallOptions(serverId, installHint) {
|
|
4489
|
+
const localHint = LSP_LOCAL_INSTALL_HINTS[serverId];
|
|
4490
|
+
if (localHint === undefined) {
|
|
4491
|
+
return ["To install, run:", ` ${installHint}`];
|
|
4492
|
+
}
|
|
4493
|
+
return [
|
|
4494
|
+
"To install in THIS repository (preferred — no global install needed):",
|
|
4495
|
+
` ${localHint}`,
|
|
4496
|
+
"",
|
|
4497
|
+
"Or install it globally:",
|
|
4498
|
+
` ${installHint}`
|
|
4499
|
+
];
|
|
4500
|
+
}
|
|
4169
4501
|
function formatNotInstalled(result) {
|
|
4170
4502
|
const { server: server2, installHint } = result;
|
|
4171
4503
|
const extensions = server2.extensions.join(", ");
|
|
@@ -4180,19 +4512,19 @@ function formatNotInstalled(result) {
|
|
|
4180
4512
|
`Command not found: ${server2.command[0]}`,
|
|
4181
4513
|
""
|
|
4182
4514
|
];
|
|
4515
|
+
const installOptions = formatInstallOptions(server2.id, installHint);
|
|
4183
4516
|
if (decision === "allowed") {
|
|
4184
4517
|
return [
|
|
4185
4518
|
...header,
|
|
4186
4519
|
"The user has pre-authorized LSP installation. Run the install command, then retry this tool:",
|
|
4187
|
-
|
|
4520
|
+
...installOptions.slice(1)
|
|
4188
4521
|
].join(`
|
|
4189
4522
|
`);
|
|
4190
4523
|
}
|
|
4191
4524
|
if (!context.capabilities.installDecisionTool) {
|
|
4192
4525
|
return [
|
|
4193
4526
|
...header,
|
|
4194
|
-
|
|
4195
|
-
` ${installHint}`,
|
|
4527
|
+
...installOptions,
|
|
4196
4528
|
"",
|
|
4197
4529
|
"ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
|
|
4198
4530
|
"Install-decision recording is unavailable in this harness; proceed without LSP if the user declines."
|
|
@@ -4201,8 +4533,7 @@ function formatNotInstalled(result) {
|
|
|
4201
4533
|
}
|
|
4202
4534
|
return [
|
|
4203
4535
|
...header,
|
|
4204
|
-
|
|
4205
|
-
` ${installHint}`,
|
|
4536
|
+
...installOptions,
|
|
4206
4537
|
"",
|
|
4207
4538
|
"ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
|
|
4208
4539
|
"- If the user agrees: run the install command above, then retry this tool.",
|
|
@@ -4213,7 +4544,7 @@ function formatNotInstalled(result) {
|
|
|
4213
4544
|
].join(`
|
|
4214
4545
|
`);
|
|
4215
4546
|
}
|
|
4216
|
-
var
|
|
4547
|
+
var READ_ONLY_TOOLS = new Set([
|
|
4217
4548
|
"diagnostics",
|
|
4218
4549
|
"definition",
|
|
4219
4550
|
"references",
|
|
@@ -4222,7 +4553,7 @@ var READ_ONLY_RETRY_TOOLS = new Set([
|
|
|
4222
4553
|
"prepareRename"
|
|
4223
4554
|
]);
|
|
4224
4555
|
async function withLspClient(filePath, fn, toolName, options = {}) {
|
|
4225
|
-
const absPath = resolvePathInsideContext(filePath);
|
|
4556
|
+
const absPath = READ_ONLY_TOOLS.has(toolName) ? resolveReadablePathInsideContext(filePath) : resolvePathInsideContext(filePath);
|
|
4226
4557
|
if (isDirectoryPath(absPath)) {
|
|
4227
4558
|
throw new LspInvalidPathError("Directory paths are not supported by this LSP tool. " + "Use lsp.diagnostics with a directory path for directory diagnostics.");
|
|
4228
4559
|
}
|
|
@@ -4237,9 +4568,9 @@ async function withLspClient(filePath, fn, toolName, options = {}) {
|
|
|
4237
4568
|
const acquireAndCall = async (allowRetry) => {
|
|
4238
4569
|
const client = await manager.getClient(root, server2, options.signal);
|
|
4239
4570
|
try {
|
|
4240
|
-
return await fn(client, root);
|
|
4571
|
+
return await fn(client, root, absPath);
|
|
4241
4572
|
} catch (err) {
|
|
4242
|
-
if (allowRetry &&
|
|
4573
|
+
if (allowRetry && READ_ONLY_TOOLS.has(toolName) && isLspDeadConnectionError(err)) {
|
|
4243
4574
|
manager.invalidateClient(root, server2.id, client);
|
|
4244
4575
|
return acquireAndCall(false);
|
|
4245
4576
|
}
|
|
@@ -4379,7 +4710,7 @@ function collectFilesWithExtension(dir, extension, maxFiles) {
|
|
|
4379
4710
|
for (const entry of entries) {
|
|
4380
4711
|
if (files.length >= maxFiles)
|
|
4381
4712
|
return;
|
|
4382
|
-
const fullPath =
|
|
4713
|
+
const fullPath = join6(currentDir, entry);
|
|
4383
4714
|
let stat;
|
|
4384
4715
|
try {
|
|
4385
4716
|
stat = lstatSync5(fullPath);
|
|
@@ -4404,8 +4735,8 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
|
|
|
4404
4735
|
if (!extension.startsWith(".")) {
|
|
4405
4736
|
throw new LspInvalidPathError(`Extension must start with a dot (e.g., ".ts", not "${extension}"). Use ".${extension}" instead.`);
|
|
4406
4737
|
}
|
|
4407
|
-
const absDir =
|
|
4408
|
-
if (!
|
|
4738
|
+
const absDir = resolve9(options.workspaceRoot ?? contextCwd(), directory);
|
|
4739
|
+
if (!existsSync12(absDir)) {
|
|
4409
4740
|
throw new LspInvalidPathError(`Directory does not exist: ${absDir}`);
|
|
4410
4741
|
}
|
|
4411
4742
|
const serverResult = options.server === undefined ? findServerForExtension(extension) : { status: "found", server: options.server };
|
|
@@ -4506,7 +4837,7 @@ function inferExtensionFromDirectory(directory) {
|
|
|
4506
4837
|
for (const entry of entries) {
|
|
4507
4838
|
if (scanned >= MAX_SCAN_ENTRIES)
|
|
4508
4839
|
return;
|
|
4509
|
-
const fullPath =
|
|
4840
|
+
const fullPath = join7(dir, entry);
|
|
4510
4841
|
let stat;
|
|
4511
4842
|
try {
|
|
4512
4843
|
stat = lstatSync6(fullPath);
|
|
@@ -4669,7 +5000,7 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
4669
5000
|
const filePath = requireString(params, "filePath");
|
|
4670
5001
|
const severity = severityFilter(params);
|
|
4671
5002
|
try {
|
|
4672
|
-
const absPath =
|
|
5003
|
+
const absPath = resolveReadablePathInsideContext(filePath);
|
|
4673
5004
|
if (isDirectoryPath(absPath)) {
|
|
4674
5005
|
const extension = inferExtensionFromDirectory(absPath);
|
|
4675
5006
|
if (!extension) {
|
|
@@ -4698,7 +5029,7 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
4698
5029
|
};
|
|
4699
5030
|
return text(output2.output, details2);
|
|
4700
5031
|
}
|
|
4701
|
-
const result = await withLspClient(filePath, async (client) => client.diagnostics(
|
|
5032
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.diagnostics(resolvedFilePath, signal), "diagnostics", clientOptions(signal));
|
|
4702
5033
|
if (result.transientError) {
|
|
4703
5034
|
const message = result.transientError.message;
|
|
4704
5035
|
const details2 = {
|
|
@@ -4745,6 +5076,91 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
4745
5076
|
throw error;
|
|
4746
5077
|
}
|
|
4747
5078
|
}
|
|
5079
|
+
var DEFAULT_FORMATTING_OPTIONS = {
|
|
5080
|
+
tabSize: 4,
|
|
5081
|
+
insertSpaces: false,
|
|
5082
|
+
trimTrailingWhitespace: true,
|
|
5083
|
+
insertFinalNewline: true,
|
|
5084
|
+
trimFinalNewlines: true
|
|
5085
|
+
};
|
|
5086
|
+
var UNCHANGED = { status: "unchanged", linesAdded: 0, linesRemoved: 0 };
|
|
5087
|
+
async function formatDocumentWithClient(client, filePath, options = {}) {
|
|
5088
|
+
const edits = await client.formatDocument(filePath, options.formattingOptions ?? DEFAULT_FORMATTING_OPTIONS, options.signal);
|
|
5089
|
+
if (edits === null)
|
|
5090
|
+
return { status: "unavailable", reason: "capability_not_advertised" };
|
|
5091
|
+
if (edits.length === 0)
|
|
5092
|
+
return UNCHANGED;
|
|
5093
|
+
const before = readFileSync6(filePath, "utf-8");
|
|
5094
|
+
const normalized = normalizeTextEdits(before, edits, 0);
|
|
5095
|
+
if (normalized.text === before)
|
|
5096
|
+
return UNCHANGED;
|
|
5097
|
+
writeAtomically(filePath, normalized.text);
|
|
5098
|
+
await client.openFile(filePath);
|
|
5099
|
+
return {
|
|
5100
|
+
status: "formatted",
|
|
5101
|
+
...lineDelta(normalized.edits)
|
|
5102
|
+
};
|
|
5103
|
+
}
|
|
5104
|
+
function lineDelta(edits) {
|
|
5105
|
+
let linesAdded = 0;
|
|
5106
|
+
let linesRemoved = 0;
|
|
5107
|
+
for (const edit of edits) {
|
|
5108
|
+
linesRemoved += edit.range.end.line - edit.range.start.line + 1;
|
|
5109
|
+
linesAdded += edit.newText.split(`
|
|
5110
|
+
`).length;
|
|
5111
|
+
}
|
|
5112
|
+
return { linesAdded, linesRemoved };
|
|
5113
|
+
}
|
|
5114
|
+
function writeAtomically(filePath, content) {
|
|
5115
|
+
const tempPath = `${filePath}.omo-format.tmp`;
|
|
5116
|
+
writeFileSync3(tempPath, content, "utf-8");
|
|
5117
|
+
try {
|
|
5118
|
+
renameSync3(tempPath, filePath);
|
|
5119
|
+
} catch (error) {
|
|
5120
|
+
try {
|
|
5121
|
+
unlinkSync2(tempPath);
|
|
5122
|
+
} catch {}
|
|
5123
|
+
throw error;
|
|
5124
|
+
}
|
|
5125
|
+
}
|
|
5126
|
+
async function executeLspFormat(params, signal) {
|
|
5127
|
+
const filePath = requireString(params, "filePath");
|
|
5128
|
+
try {
|
|
5129
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => formatDocumentWithClient(client, resolvedFilePath, signal === undefined ? {} : { signal }), "format", clientOptions(signal));
|
|
5130
|
+
return text(describeResult(filePath, result), formatDetails(filePath, result));
|
|
5131
|
+
} catch (error) {
|
|
5132
|
+
const missingDependency = missingDependencyResult(error, {
|
|
5133
|
+
filePath,
|
|
5134
|
+
status: "unavailable",
|
|
5135
|
+
reason: "server_unavailable",
|
|
5136
|
+
linesAdded: 0,
|
|
5137
|
+
linesRemoved: 0
|
|
5138
|
+
});
|
|
5139
|
+
if (missingDependency)
|
|
5140
|
+
return missingDependency;
|
|
5141
|
+
throw error;
|
|
5142
|
+
}
|
|
5143
|
+
}
|
|
5144
|
+
function formatDetails(filePath, result) {
|
|
5145
|
+
if (result.status === "unavailable") {
|
|
5146
|
+
return { filePath, status: "unavailable", reason: result.reason, linesAdded: 0, linesRemoved: 0 };
|
|
5147
|
+
}
|
|
5148
|
+
return {
|
|
5149
|
+
filePath,
|
|
5150
|
+
status: result.status,
|
|
5151
|
+
linesAdded: result.linesAdded,
|
|
5152
|
+
linesRemoved: result.linesRemoved
|
|
5153
|
+
};
|
|
5154
|
+
}
|
|
5155
|
+
function describeResult(filePath, result) {
|
|
5156
|
+
if (result.status === "unavailable") {
|
|
5157
|
+
return `Formatting unavailable for ${filePath}: the language server does not advertise documentFormattingProvider.`;
|
|
5158
|
+
}
|
|
5159
|
+
if (result.status === "unchanged") {
|
|
5160
|
+
return `Already formatted: ${filePath}`;
|
|
5161
|
+
}
|
|
5162
|
+
return `Formatted ${filePath} (+${result.linesAdded}/-${result.linesRemoved} lines)`;
|
|
5163
|
+
}
|
|
4748
5164
|
async function executeLspInstallDecision(params) {
|
|
4749
5165
|
const serverId = requireString(params, "server_id");
|
|
4750
5166
|
const decision = params["decision"];
|
|
@@ -4770,7 +5186,7 @@ async function executeLspGotoDefinition(params, signal) {
|
|
|
4770
5186
|
const line = requireNumber(params, "line");
|
|
4771
5187
|
const character = requireNumber(params, "character");
|
|
4772
5188
|
try {
|
|
4773
|
-
const result = await withLspClient(filePath, async (client) => client.definition(
|
|
5189
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.definition(resolvedFilePath, line, character, signal), "definition", clientOptions(signal));
|
|
4774
5190
|
const locations = !result ? [] : Array.isArray(result) ? result : [result];
|
|
4775
5191
|
const details = { filePath, line, character, locations };
|
|
4776
5192
|
if (locations.length === 0)
|
|
@@ -4795,7 +5211,7 @@ async function executeLspFindReferences(params, signal) {
|
|
|
4795
5211
|
const character = requireNumber(params, "character");
|
|
4796
5212
|
const includeDeclaration = optionalBoolean(params, "includeDeclaration") ?? true;
|
|
4797
5213
|
try {
|
|
4798
|
-
const result = await withLspClient(filePath, async (client) => client.references(
|
|
5214
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.references(resolvedFilePath, line, character, includeDeclaration, signal), "references", clientOptions(signal));
|
|
4799
5215
|
const references = Array.isArray(result) ? result : [];
|
|
4800
5216
|
const total = references.length;
|
|
4801
5217
|
const truncated = total > DEFAULT_MAX_REFERENCES;
|
|
@@ -4835,7 +5251,7 @@ async function executeLspPrepareRename(params, signal) {
|
|
|
4835
5251
|
const line = requireNumber(params, "line");
|
|
4836
5252
|
const character = requireNumber(params, "character");
|
|
4837
5253
|
try {
|
|
4838
|
-
const result = await withLspClient(filePath, async (client) => client.prepareRename(
|
|
5254
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.prepareRename(resolvedFilePath, line, character, signal), "prepareRename", clientOptions(signal));
|
|
4839
5255
|
const details = { filePath, line, character, result };
|
|
4840
5256
|
return text(formatPrepareRenameResult(result), details);
|
|
4841
5257
|
} catch (error) {
|
|
@@ -4856,7 +5272,7 @@ async function executeLspRename(params, signal) {
|
|
|
4856
5272
|
const character = requireNumber(params, "character");
|
|
4857
5273
|
const newName = requireString(params, "newName");
|
|
4858
5274
|
try {
|
|
4859
|
-
const result = await withLspClient(filePath, async (client) => client.rename(
|
|
5275
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.rename(resolvedFilePath, line, character, newName, signal), "rename", clientOptions(signal));
|
|
4860
5276
|
const details = { filePath, line, character, newName, apply: result.apply, edit: result.edit };
|
|
4861
5277
|
return text(formatApplyResult(result.apply), details, !result.apply.success);
|
|
4862
5278
|
} catch (error) {
|
|
@@ -4930,7 +5346,7 @@ async function executeLspSymbols(params, signal) {
|
|
|
4930
5346
|
const symbols2 = await withLspClient(filePath, async (client) => client.workspaceSymbols(query, signal), "workspaceSymbols", clientOptions(signal));
|
|
4931
5347
|
return formatSymbolsResult(filePath, scope, symbols2, limit, query);
|
|
4932
5348
|
}
|
|
4933
|
-
const symbols = await withLspClient(filePath, async (client) => client.documentSymbols(
|
|
5349
|
+
const symbols = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.documentSymbols(resolvedFilePath, signal), "documentSymbols", clientOptions(signal));
|
|
4934
5350
|
return formatSymbolsResult(filePath, scope, symbols, limit);
|
|
4935
5351
|
} catch (error) {
|
|
4936
5352
|
const query = optionalString(params, "query");
|
|
@@ -5064,6 +5480,16 @@ var LSP_MCP_TOOLS = [
|
|
|
5064
5480
|
}, ["filePath", "line", "character", "newName"]),
|
|
5065
5481
|
execute: executeLspRename
|
|
5066
5482
|
},
|
|
5483
|
+
{
|
|
5484
|
+
name: "format",
|
|
5485
|
+
aliases: ["lsp_format"],
|
|
5486
|
+
title: "LSP Format",
|
|
5487
|
+
description: "Format a source file with its language server and write the returned edits to disk.",
|
|
5488
|
+
inputSchema: objectSchema({
|
|
5489
|
+
filePath: { type: "string", description: "Source file path to format." }
|
|
5490
|
+
}, ["filePath"]),
|
|
5491
|
+
execute: executeLspFormat
|
|
5492
|
+
},
|
|
5067
5493
|
{
|
|
5068
5494
|
name: "install_decision",
|
|
5069
5495
|
aliases: ["lsp_install_decision"],
|
|
@@ -5130,7 +5556,7 @@ function withContext(args, context) {
|
|
|
5130
5556
|
function ensureDaemonAvailable(paths, ensure, signal) {
|
|
5131
5557
|
if (!signal)
|
|
5132
5558
|
return ensure(paths);
|
|
5133
|
-
return new Promise((
|
|
5559
|
+
return new Promise((resolve10, reject) => {
|
|
5134
5560
|
let settled = false;
|
|
5135
5561
|
const finish = (run) => {
|
|
5136
5562
|
if (settled)
|
|
@@ -5145,11 +5571,11 @@ function ensureDaemonAvailable(paths, ensure, signal) {
|
|
|
5145
5571
|
return;
|
|
5146
5572
|
}
|
|
5147
5573
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
5148
|
-
Promise.resolve().then(() => ensure(paths, signal)).then(() => finish(() =>
|
|
5574
|
+
Promise.resolve().then(() => ensure(paths, signal)).then(() => finish(() => resolve10()), (error) => finish(() => reject(signal.aborted ? new DaemonRequestCancelledError(false) : error)));
|
|
5149
5575
|
});
|
|
5150
5576
|
}
|
|
5151
5577
|
function sendToolCall(paths, token, name, args, options) {
|
|
5152
|
-
return new Promise((
|
|
5578
|
+
return new Promise((resolve10, reject) => {
|
|
5153
5579
|
const socket = connect(paths.socket);
|
|
5154
5580
|
const requestId = allocateProxyRequestId();
|
|
5155
5581
|
let settled = false;
|
|
@@ -5202,7 +5628,7 @@ function sendToolCall(paths, token, name, args, options) {
|
|
|
5202
5628
|
}
|
|
5203
5629
|
const result = toToolResult(message, requestId);
|
|
5204
5630
|
if (result)
|
|
5205
|
-
finish(() =>
|
|
5631
|
+
finish(() => resolve10(result));
|
|
5206
5632
|
else
|
|
5207
5633
|
finish(() => reject(new DaemonRequestError("invalid daemon response", requestWritten)));
|
|
5208
5634
|
});
|
|
@@ -5251,10 +5677,9 @@ var OMO_LSP_DAEMON_VERSION2 = "OMO_LSP_DAEMON_VERSION";
|
|
|
5251
5677
|
var DAEMON_VERSION_PATTERN2 = /^[A-Za-z0-9][A-Za-z0-9._+-]{0,127}$/;
|
|
5252
5678
|
|
|
5253
5679
|
class InvalidRuntimeOverrideError2 extends Error {
|
|
5254
|
-
code = "invalid_runtime_override";
|
|
5255
|
-
reason;
|
|
5256
5680
|
constructor(reason, message) {
|
|
5257
5681
|
super(message);
|
|
5682
|
+
this.code = "invalid_runtime_override";
|
|
5258
5683
|
this.name = "InvalidRuntimeOverrideError";
|
|
5259
5684
|
this.reason = reason;
|
|
5260
5685
|
}
|
|
@@ -5274,12 +5699,12 @@ function resolveDaemonRuntime2(env, defaults) {
|
|
|
5274
5699
|
throw new InvalidRuntimeOverrideError2("paired_values_required", `${OMO_LSP_DAEMON_CLI2} and ${OMO_LSP_DAEMON_VERSION2} must be set together`);
|
|
5275
5700
|
}
|
|
5276
5701
|
if (!hasCliOverride || !hasVersionOverride) {
|
|
5277
|
-
if (!
|
|
5702
|
+
if (!isAbsolute6(defaults.cliPath)) {
|
|
5278
5703
|
throw new InvalidRuntimeOverrideError2("packaged_cli_must_be_absolute", "Packaged LSP daemon CLI path must be absolute");
|
|
5279
5704
|
}
|
|
5280
5705
|
return { cliPath: defaults.cliPath, version: validateDaemonVersion2(defaults.version) };
|
|
5281
5706
|
}
|
|
5282
|
-
if (!
|
|
5707
|
+
if (!isAbsolute6(cliOverride)) {
|
|
5283
5708
|
throw new InvalidRuntimeOverrideError2("cli_must_be_absolute", `${OMO_LSP_DAEMON_CLI2} must be an absolute path to an existing regular file`);
|
|
5284
5709
|
}
|
|
5285
5710
|
const stat = statSync5(cliOverride, { throwIfNoEntry: false });
|
|
@@ -5400,15 +5825,14 @@ function extensionKey(filePath) {
|
|
|
5400
5825
|
}
|
|
5401
5826
|
// ../../../../lsp-core/src/request-context.ts
|
|
5402
5827
|
import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
|
|
5403
|
-
import { existsSync as
|
|
5404
|
-
import { basename as
|
|
5828
|
+
import { existsSync as existsSync13, realpathSync as realpathSync6, statSync as statSync6 } from "node:fs";
|
|
5829
|
+
import { basename as basename4, delimiter as delimiter4, dirname as dirname2, isAbsolute as isAbsolute7, join as join8, relative as relative5, resolve as resolve10 } from "node:path";
|
|
5405
5830
|
|
|
5406
5831
|
class LspRequestContextParseError2 extends Error {
|
|
5407
|
-
code;
|
|
5408
|
-
name = "LspRequestContextParseError";
|
|
5409
5832
|
constructor(code, message) {
|
|
5410
5833
|
super(message);
|
|
5411
5834
|
this.code = code;
|
|
5835
|
+
this.name = "LspRequestContextParseError";
|
|
5412
5836
|
}
|
|
5413
5837
|
}
|
|
5414
5838
|
var storage2 = new AsyncLocalStorage2;
|
|
@@ -5443,26 +5867,26 @@ function parseLspRequestContext2(value) {
|
|
|
5443
5867
|
};
|
|
5444
5868
|
}
|
|
5445
5869
|
function canonicalCwd2(cwd) {
|
|
5446
|
-
const resolved =
|
|
5447
|
-
if (!
|
|
5870
|
+
const resolved = resolve10(cwd);
|
|
5871
|
+
if (!existsSync13(resolved) || !statSync6(resolved).isDirectory()) {
|
|
5448
5872
|
throw new LspRequestContextParseError2("invalid_cwd", `LSP request cwd must be an existing directory: ${cwd}`);
|
|
5449
5873
|
}
|
|
5450
|
-
return
|
|
5874
|
+
return realpathSync6(resolved);
|
|
5451
5875
|
}
|
|
5452
5876
|
function canonicalizeExistingOrNearestAncestor2(path2) {
|
|
5453
|
-
let current =
|
|
5877
|
+
let current = resolve10(path2);
|
|
5454
5878
|
const suffix = [];
|
|
5455
5879
|
while (true) {
|
|
5456
5880
|
try {
|
|
5457
|
-
const existing =
|
|
5458
|
-
return suffix.length === 0 ? existing :
|
|
5881
|
+
const existing = realpathSync6(current);
|
|
5882
|
+
return suffix.length === 0 ? existing : join8(existing, ...suffix);
|
|
5459
5883
|
} catch (error) {
|
|
5460
5884
|
if (!isMissingPathError2(error))
|
|
5461
5885
|
throw error;
|
|
5462
5886
|
const parent = dirname2(current);
|
|
5463
5887
|
if (parent === current)
|
|
5464
5888
|
throw error;
|
|
5465
|
-
suffix.unshift(
|
|
5889
|
+
suffix.unshift(basename4(current));
|
|
5466
5890
|
current = parent;
|
|
5467
5891
|
}
|
|
5468
5892
|
}
|
|
@@ -5493,14 +5917,14 @@ function stringArrayField2(value, field) {
|
|
|
5493
5917
|
return fieldValue;
|
|
5494
5918
|
}
|
|
5495
5919
|
function requireAbsolutePath2(path2, field) {
|
|
5496
|
-
if (!
|
|
5920
|
+
if (!isAbsolute7(path2)) {
|
|
5497
5921
|
throw new LspRequestContextParseError2("relative_path", `LSP request context.${field} must be absolute: ${path2}`);
|
|
5498
5922
|
}
|
|
5499
5923
|
}
|
|
5500
5924
|
function isPathInside2(parent, child) {
|
|
5501
|
-
const childPath =
|
|
5925
|
+
const childPath = resolve10(child);
|
|
5502
5926
|
const relativePath = relative5(parent, childPath);
|
|
5503
|
-
return relativePath === "" || !relativePath.startsWith("..") && !
|
|
5927
|
+
return relativePath === "" || !relativePath.startsWith("..") && !isAbsolute7(relativePath);
|
|
5504
5928
|
}
|
|
5505
5929
|
function isMissingPathError2(error) {
|
|
5506
5930
|
const code = errorCode2(error);
|
|
@@ -5523,9 +5947,9 @@ function errorCode2(error) {
|
|
|
5523
5947
|
}
|
|
5524
5948
|
|
|
5525
5949
|
// src/daemon-cli-path.ts
|
|
5526
|
-
import { existsSync as
|
|
5950
|
+
import { existsSync as existsSync15, readFileSync as readFileSync7 } from "node:fs";
|
|
5527
5951
|
import { createRequire as createRequire2 } from "node:module";
|
|
5528
|
-
import { dirname as
|
|
5952
|
+
import { dirname as dirname11, join as join10 } from "node:path";
|
|
5529
5953
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
5530
5954
|
var requireFromHere2 = createRequire2(import.meta.url);
|
|
5531
5955
|
var PACKAGE_LSP_DAEMON_CLI = "@code-yeongyu/lsp-daemon/cli";
|
|
@@ -5547,7 +5971,7 @@ function resolveLspDaemonCli() {
|
|
|
5547
5971
|
if (packageCli !== null)
|
|
5548
5972
|
return resolveConfiguredLspDaemonCli(packageCli);
|
|
5549
5973
|
const bundledCli = fileURLToPath4(new URL("../../lsp-daemon/dist/cli.js", import.meta.url));
|
|
5550
|
-
if (
|
|
5974
|
+
if (existsSync15(bundledCli))
|
|
5551
5975
|
return resolveConfiguredLspDaemonCli(bundledCli);
|
|
5552
5976
|
return resolveConfiguredLspDaemonCli(bundledCli);
|
|
5553
5977
|
}
|
|
@@ -5572,7 +5996,7 @@ function resolveConfiguredLspDaemonCli(cliPath) {
|
|
|
5572
5996
|
}
|
|
5573
5997
|
function readDaemonPackageVersion(cliPath) {
|
|
5574
5998
|
try {
|
|
5575
|
-
const parsed = JSON.parse(
|
|
5999
|
+
const parsed = JSON.parse(readFileSync7(join10(dirname11(cliPath), "package.json"), "utf8"));
|
|
5576
6000
|
if (isRecord9(parsed) && typeof parsed["version"] === "string" && parsed["version"].length > 0) {
|
|
5577
6001
|
return parsed["version"];
|
|
5578
6002
|
}
|
|
@@ -5587,9 +6011,9 @@ function isRecord9(value) {
|
|
|
5587
6011
|
}
|
|
5588
6012
|
|
|
5589
6013
|
// src/lsp-session-state.ts
|
|
5590
|
-
import { mkdirSync as mkdirSync4, readFileSync as
|
|
6014
|
+
import { mkdirSync as mkdirSync4, readFileSync as readFileSync9, writeFileSync as writeFileSync4 } from "node:fs";
|
|
5591
6015
|
import { homedir } from "node:os";
|
|
5592
|
-
import { dirname as
|
|
6016
|
+
import { dirname as dirname13, join as join11 } from "node:path";
|
|
5593
6017
|
function sessionIdFrom(input) {
|
|
5594
6018
|
return typeof input.session_id === "string" && input.session_id.length > 0 ? input.session_id : undefined;
|
|
5595
6019
|
}
|
|
@@ -5615,12 +6039,12 @@ function isLspDaemonUnreachableDiagnostics(diagnostics) {
|
|
|
5615
6039
|
return diagnostics.includes("LSP daemon unreachable");
|
|
5616
6040
|
}
|
|
5617
6041
|
function sessionStatePath(sessionId) {
|
|
5618
|
-
const root = process.env["PLUGIN_DATA"] ??
|
|
5619
|
-
return
|
|
6042
|
+
const root = process.env["PLUGIN_DATA"] ?? join11(homedir(), ".codex", "codex-lsp");
|
|
6043
|
+
return join11(root, "sessions", `${safePathSegment(sessionId)}.json`);
|
|
5620
6044
|
}
|
|
5621
6045
|
function readSessionState(path2) {
|
|
5622
6046
|
try {
|
|
5623
|
-
const parsed = JSON.parse(
|
|
6047
|
+
const parsed = JSON.parse(readFileSync9(path2, "utf8"));
|
|
5624
6048
|
if (isRecord10(parsed) && isLspSessionState(parsed))
|
|
5625
6049
|
return normalizeSessionState(parsed);
|
|
5626
6050
|
return emptyState();
|
|
@@ -5631,8 +6055,8 @@ function readSessionState(path2) {
|
|
|
5631
6055
|
}
|
|
5632
6056
|
}
|
|
5633
6057
|
function writeSessionState(path2, state) {
|
|
5634
|
-
mkdirSync4(
|
|
5635
|
-
|
|
6058
|
+
mkdirSync4(dirname13(path2), { recursive: true });
|
|
6059
|
+
writeFileSync4(path2, `${JSON.stringify(state)}
|
|
5636
6060
|
`);
|
|
5637
6061
|
}
|
|
5638
6062
|
function emptyState() {
|
|
@@ -5775,13 +6199,13 @@ function notConfiguredAvailability(details) {
|
|
|
5775
6199
|
return typeof extension === "string" && extension.length > 0 ? { extension } : undefined;
|
|
5776
6200
|
}
|
|
5777
6201
|
function codexLspRequestContext(env = process.env, cwd = process.cwd()) {
|
|
5778
|
-
const canonicalCwd3 =
|
|
5779
|
-
const codexHome =
|
|
6202
|
+
const canonicalCwd3 = realpathSync8(resolve12(cwd));
|
|
6203
|
+
const codexHome = resolve12(env["CODEX_HOME"]?.trim() || join12(homedir3(), ".codex"));
|
|
5780
6204
|
return parseLspRequestContext2({
|
|
5781
6205
|
cwd: canonicalCwd3,
|
|
5782
|
-
projectConfigPaths: [
|
|
5783
|
-
userConfigPath:
|
|
5784
|
-
installDecisionsPath:
|
|
6206
|
+
projectConfigPaths: [join12(canonicalCwd3, ".codex", "lsp-client.json")],
|
|
6207
|
+
userConfigPath: join12(codexHome, "lsp-client.json"),
|
|
6208
|
+
installDecisionsPath: join12(codexHome, "lsp-install-decisions.json"),
|
|
5785
6209
|
capabilities: { installDecisionTool: true }
|
|
5786
6210
|
});
|
|
5787
6211
|
}
|
|
@@ -5875,7 +6299,7 @@ function isContextPressureTranscript(transcriptPath) {
|
|
|
5875
6299
|
if (typeof transcriptPath !== "string")
|
|
5876
6300
|
return false;
|
|
5877
6301
|
try {
|
|
5878
|
-
return hasContextPressureMarker(
|
|
6302
|
+
return hasContextPressureMarker(readFileSync10(transcriptPath, "utf8"));
|
|
5879
6303
|
} catch (error) {
|
|
5880
6304
|
if (error instanceof Error)
|
|
5881
6305
|
return false;
|
|
@@ -5957,15 +6381,15 @@ main().catch((error) => {
|
|
|
5957
6381
|
});
|
|
5958
6382
|
async function runPackageLspMcpCli() {
|
|
5959
6383
|
const cliPath = resolveLspDaemonCliPath();
|
|
5960
|
-
const child = spawn3(execPath2, [cliPath, "mcp"], { stdio: "inherit" });
|
|
5961
|
-
await new Promise((
|
|
6384
|
+
const child = spawn3(execPath2, [cliPath, "mcp"], { stdio: "inherit", windowsHide: true });
|
|
6385
|
+
await new Promise((resolve11, reject) => {
|
|
5962
6386
|
child.once("error", reject);
|
|
5963
6387
|
child.once("exit", (code, signal) => {
|
|
5964
6388
|
if (code !== null && code !== 0)
|
|
5965
6389
|
process.exitCode = code;
|
|
5966
6390
|
if (code === null && signal !== null)
|
|
5967
6391
|
process.exitCode = 1;
|
|
5968
|
-
|
|
6392
|
+
resolve11();
|
|
5969
6393
|
});
|
|
5970
6394
|
});
|
|
5971
6395
|
}
|