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
|
@@ -175,6 +175,7 @@ async function runJsonRpcStdioServer(config) {
|
|
|
175
175
|
const idleTimer = createIdleTimer(idleTimeoutMs, log, () => {
|
|
176
176
|
isClosed = true;
|
|
177
177
|
config.onIdleTimeout?.();
|
|
178
|
+
config.input.destroy();
|
|
178
179
|
});
|
|
179
180
|
const watchdog = createParentWatchdog(config.parentWatchdog, (parentPid, pollIntervalMs) => {
|
|
180
181
|
isClosed = true;
|
|
@@ -271,7 +272,11 @@ function createParentWatchdog(config, onDeadParent) {
|
|
|
271
272
|
const probeAlive = config.probeAlive ?? isProcessAlive;
|
|
272
273
|
let fired = false;
|
|
273
274
|
const timer = setInterval(() => {
|
|
274
|
-
if (fired
|
|
275
|
+
if (fired)
|
|
276
|
+
return;
|
|
277
|
+
const alive = probeAlive(parentPid);
|
|
278
|
+
config.onPoll?.(alive);
|
|
279
|
+
if (alive)
|
|
275
280
|
return;
|
|
276
281
|
fired = true;
|
|
277
282
|
onDeadParent(parentPid, pollIntervalMs);
|
|
@@ -306,8 +311,8 @@ function createIdleTimer(idleTimeoutMs, log, onTimeout) {
|
|
|
306
311
|
};
|
|
307
312
|
}
|
|
308
313
|
// ../lsp-core/src/lsp/client-wrapper.ts
|
|
309
|
-
import { existsSync as
|
|
310
|
-
import { dirname as
|
|
314
|
+
import { existsSync as existsSync10, realpathSync as realpathSync5, statSync as statSync3 } from "node:fs";
|
|
315
|
+
import { basename as basename3, dirname as dirname8, join as join5, resolve as resolve8 } from "node:path";
|
|
311
316
|
|
|
312
317
|
// ../lsp-core/src/request-context.ts
|
|
313
318
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
@@ -316,18 +321,17 @@ import { homedir } from "node:os";
|
|
|
316
321
|
import { basename, delimiter, dirname, isAbsolute, join, relative, resolve } from "node:path";
|
|
317
322
|
|
|
318
323
|
class LspRequestContextParseError extends Error {
|
|
319
|
-
code;
|
|
320
|
-
name = "LspRequestContextParseError";
|
|
321
324
|
constructor(code, message) {
|
|
322
325
|
super(message);
|
|
323
326
|
this.code = code;
|
|
327
|
+
this.name = "LspRequestContextParseError";
|
|
324
328
|
}
|
|
325
329
|
}
|
|
326
330
|
|
|
327
331
|
class LspRequestContextUnavailableError extends Error {
|
|
328
|
-
name = "LspRequestContextUnavailableError";
|
|
329
332
|
constructor() {
|
|
330
333
|
super("LSP request context is required. Standalone MCP startup must install one with runWithRequestContext(createStandaloneMcpRequestContext()).");
|
|
334
|
+
this.name = "LspRequestContextUnavailableError";
|
|
331
335
|
}
|
|
332
336
|
}
|
|
333
337
|
var storage = new AsyncLocalStorage;
|
|
@@ -357,7 +361,7 @@ function contextEnv(key) {
|
|
|
357
361
|
}
|
|
358
362
|
function createStandaloneMcpRequestContext(input = {}) {
|
|
359
363
|
const env = input.env ?? process.env;
|
|
360
|
-
const cwd = canonicalCwd(input.cwd ?? process.cwd());
|
|
364
|
+
const cwd = canonicalCwd(input.cwd ?? env["LSP_TOOLS_MCP_CWD"] ?? process.cwd());
|
|
361
365
|
const home = input.homeDir ?? homedir();
|
|
362
366
|
const projectConfigPaths = translateProjectConfigEnv(env["LSP_TOOLS_MCP_PROJECT_CONFIG"], cwd);
|
|
363
367
|
const userConfigPath = translateHomeConfigEnv(env["LSP_TOOLS_MCP_USER_CONFIG"], home, ".codex/lsp-client.json");
|
|
@@ -500,22 +504,15 @@ function effectiveExtension(filePath) {
|
|
|
500
504
|
|
|
501
505
|
// ../lsp-core/src/lsp/errors.ts
|
|
502
506
|
class LspConnectionClosedError extends Error {
|
|
503
|
-
serverId;
|
|
504
|
-
root;
|
|
505
|
-
name = "LspConnectionClosedError";
|
|
506
507
|
constructor(serverId, root, message) {
|
|
507
508
|
super(message ?? `LSP connection closed for ${serverId} at ${root}`);
|
|
508
509
|
this.serverId = serverId;
|
|
509
510
|
this.root = root;
|
|
511
|
+
this.name = "LspConnectionClosedError";
|
|
510
512
|
}
|
|
511
513
|
}
|
|
512
514
|
|
|
513
515
|
class LspProcessExitedError extends Error {
|
|
514
|
-
serverId;
|
|
515
|
-
root;
|
|
516
|
-
exitCode;
|
|
517
|
-
stderrTail;
|
|
518
|
-
name = "LspProcessExitedError";
|
|
519
516
|
constructor(serverId, root, exitCode, stderrTail) {
|
|
520
517
|
const stderrSuffix = stderrTail ? `
|
|
521
518
|
stderr tail: ${stderrTail}` : "";
|
|
@@ -524,46 +521,59 @@ stderr tail: ${stderrTail}` : "";
|
|
|
524
521
|
this.root = root;
|
|
525
522
|
this.exitCode = exitCode;
|
|
526
523
|
this.stderrTail = stderrTail;
|
|
524
|
+
this.name = "LspProcessExitedError";
|
|
527
525
|
}
|
|
528
526
|
}
|
|
529
527
|
|
|
530
528
|
class LspRequestTimeoutError extends Error {
|
|
531
|
-
method;
|
|
532
|
-
stderrTail;
|
|
533
|
-
name = "LspRequestTimeoutError";
|
|
534
529
|
constructor(method, stderrTail) {
|
|
535
530
|
const stderrSuffix = stderrTail ? `
|
|
536
531
|
recent stderr: ${stderrTail}` : "";
|
|
537
532
|
super(`LSP request timeout (method: ${method})${stderrSuffix}`);
|
|
538
533
|
this.method = method;
|
|
539
534
|
this.stderrTail = stderrTail;
|
|
535
|
+
this.name = "LspRequestTimeoutError";
|
|
540
536
|
}
|
|
541
537
|
}
|
|
542
538
|
|
|
543
539
|
class LspInvalidPathError extends Error {
|
|
544
|
-
|
|
540
|
+
constructor() {
|
|
541
|
+
super(...arguments);
|
|
542
|
+
this.name = "LspInvalidPathError";
|
|
543
|
+
}
|
|
545
544
|
}
|
|
546
545
|
|
|
547
546
|
class LspServerLookupError extends Error {
|
|
548
|
-
lookup;
|
|
549
|
-
name = "LspServerLookupError";
|
|
550
547
|
constructor(message, lookup) {
|
|
551
548
|
super(message);
|
|
552
549
|
this.lookup = lookup;
|
|
550
|
+
this.name = "LspServerLookupError";
|
|
553
551
|
}
|
|
554
552
|
}
|
|
555
553
|
|
|
556
554
|
class LspServerInitializingError extends Error {
|
|
557
|
-
originalError;
|
|
558
|
-
name = "LspServerInitializingError";
|
|
559
555
|
constructor(originalError) {
|
|
560
556
|
super(`LSP server is still initializing. Please retry in a few seconds. Original error: ${originalError.message}`);
|
|
561
557
|
this.originalError = originalError;
|
|
558
|
+
this.name = "LspServerInitializingError";
|
|
562
559
|
}
|
|
563
560
|
}
|
|
564
561
|
|
|
565
562
|
class LspProcessSpawnError extends Error {
|
|
566
|
-
|
|
563
|
+
constructor() {
|
|
564
|
+
super(...arguments);
|
|
565
|
+
this.name = "LspProcessSpawnError";
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
class LspClientRespawnBudgetExceededError extends Error {
|
|
570
|
+
constructor(serverId, root, retryLimit) {
|
|
571
|
+
super(`LSP server ${serverId} at ${root} failed to stay alive; respawn budget exhausted ` + `(${retryLimit} consecutive dead generations). Retrying after the cooldown may succeed.`);
|
|
572
|
+
this.serverId = serverId;
|
|
573
|
+
this.root = root;
|
|
574
|
+
this.retryLimit = retryLimit;
|
|
575
|
+
this.name = "LspClientRespawnBudgetExceededError";
|
|
576
|
+
}
|
|
567
577
|
}
|
|
568
578
|
function isLspDeadConnectionError(err) {
|
|
569
579
|
return err instanceof LspConnectionClosedError || err instanceof LspProcessExitedError;
|
|
@@ -594,9 +604,12 @@ var DEFAULT_MAX_DIRECTORY_FILES = 50;
|
|
|
594
604
|
var REQUEST_TIMEOUT_MS = 15000;
|
|
595
605
|
var INIT_TIMEOUT_MS = 60000;
|
|
596
606
|
var IDLE_TIMEOUT_MS = 5 * 60000;
|
|
607
|
+
var MAX_RESIDENT_CLIENTS = 6;
|
|
597
608
|
var REAPER_INTERVAL_MS = 60000;
|
|
598
609
|
var STOP_HARD_KILL_TIMEOUT_MS = 5000;
|
|
599
610
|
var STOP_SIGKILL_GRACE_MS = 1000;
|
|
611
|
+
var CLIENT_RESPAWN_RETRY_LIMIT = 2;
|
|
612
|
+
var CLIENT_RESPAWN_COOLDOWN_MS = 60000;
|
|
600
613
|
|
|
601
614
|
// ../lsp-core/src/lsp/json-rpc-connection.ts
|
|
602
615
|
var HEADER_SEPARATOR2 = `\r
|
|
@@ -608,20 +621,31 @@ var METHOD_NOT_FOUND = -32601;
|
|
|
608
621
|
var INTERNAL_ERROR = -32603;
|
|
609
622
|
|
|
610
623
|
class JsonRpcConnection {
|
|
611
|
-
reader;
|
|
612
|
-
writer;
|
|
613
|
-
pendingRequests = new Map;
|
|
614
|
-
notificationHandlers = new Map;
|
|
615
|
-
requestHandlers = new Map;
|
|
616
|
-
closeHandlers = [];
|
|
617
|
-
errorHandlers = [];
|
|
618
|
-
inputBuffer = Buffer.alloc(0);
|
|
619
|
-
nextRequestId = 1;
|
|
620
|
-
listening = false;
|
|
621
|
-
disposed = false;
|
|
622
624
|
constructor(reader, writer) {
|
|
623
625
|
this.reader = reader;
|
|
624
626
|
this.writer = writer;
|
|
627
|
+
this.pendingRequests = new Map;
|
|
628
|
+
this.notificationHandlers = new Map;
|
|
629
|
+
this.requestHandlers = new Map;
|
|
630
|
+
this.closeHandlers = [];
|
|
631
|
+
this.errorHandlers = [];
|
|
632
|
+
this.inputBuffer = Buffer.alloc(0);
|
|
633
|
+
this.nextRequestId = 1;
|
|
634
|
+
this.listening = false;
|
|
635
|
+
this.disposed = false;
|
|
636
|
+
this.handleData = (chunk) => {
|
|
637
|
+
const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
|
|
638
|
+
this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
|
|
639
|
+
this.drainInputBuffer();
|
|
640
|
+
};
|
|
641
|
+
this.handleClose = () => {
|
|
642
|
+
for (const handler of this.closeHandlers) {
|
|
643
|
+
handler();
|
|
644
|
+
}
|
|
645
|
+
};
|
|
646
|
+
this.handleStreamError = (error) => {
|
|
647
|
+
this.emitError(error);
|
|
648
|
+
};
|
|
625
649
|
}
|
|
626
650
|
listen() {
|
|
627
651
|
if (this.listening)
|
|
@@ -742,19 +766,6 @@ class JsonRpcConnection {
|
|
|
742
766
|
this.notificationHandlers.clear();
|
|
743
767
|
this.requestHandlers.clear();
|
|
744
768
|
}
|
|
745
|
-
handleData = (chunk) => {
|
|
746
|
-
const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
|
|
747
|
-
this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
|
|
748
|
-
this.drainInputBuffer();
|
|
749
|
-
};
|
|
750
|
-
handleClose = () => {
|
|
751
|
-
for (const handler of this.closeHandlers) {
|
|
752
|
-
handler();
|
|
753
|
-
}
|
|
754
|
-
};
|
|
755
|
-
handleStreamError = (error) => {
|
|
756
|
-
this.emitError(error);
|
|
757
|
-
};
|
|
758
769
|
drainInputBuffer() {
|
|
759
770
|
while (true) {
|
|
760
771
|
const headerEnd = this.inputBuffer.indexOf(HEADER_SEPARATOR2);
|
|
@@ -1102,31 +1113,26 @@ function isPosition(value) {
|
|
|
1102
1113
|
|
|
1103
1114
|
// ../lsp-core/src/lsp/transport.ts
|
|
1104
1115
|
class LspClientNotStartedError extends Error {
|
|
1105
|
-
serverId;
|
|
1106
|
-
root;
|
|
1107
|
-
name = "LspClientNotStartedError";
|
|
1108
1116
|
constructor(serverId, root) {
|
|
1109
1117
|
super("LSP client not started");
|
|
1110
1118
|
this.serverId = serverId;
|
|
1111
1119
|
this.root = root;
|
|
1120
|
+
this.name = "LspClientNotStartedError";
|
|
1112
1121
|
}
|
|
1113
1122
|
}
|
|
1114
1123
|
|
|
1115
1124
|
class LspClientTransport {
|
|
1116
|
-
root;
|
|
1117
|
-
server;
|
|
1118
|
-
proc = null;
|
|
1119
|
-
connection = null;
|
|
1120
|
-
stderrBuffer = [];
|
|
1121
|
-
processExited = false;
|
|
1122
|
-
diagnosticsStore = new Map;
|
|
1123
|
-
requestTimeoutMs;
|
|
1124
|
-
initializeTimeoutMs;
|
|
1125
|
-
workspaceApplyEditHandler = null;
|
|
1126
|
-
diagnosticPullSupported = false;
|
|
1127
1125
|
constructor(root, server2, timeouts = {}) {
|
|
1128
1126
|
this.root = root;
|
|
1129
1127
|
this.server = server2;
|
|
1128
|
+
this.proc = null;
|
|
1129
|
+
this.connection = null;
|
|
1130
|
+
this.stderrBuffer = [];
|
|
1131
|
+
this.processExited = false;
|
|
1132
|
+
this.diagnosticsStore = new Map;
|
|
1133
|
+
this.workspaceApplyEditHandler = null;
|
|
1134
|
+
this.diagnosticPullSupported = false;
|
|
1135
|
+
this.documentFormattingSupported = false;
|
|
1130
1136
|
this.requestTimeoutMs = timeouts.requestTimeoutMs ?? REQUEST_TIMEOUT_MS;
|
|
1131
1137
|
this.initializeTimeoutMs = timeouts.initializeTimeoutMs ?? INIT_TIMEOUT_MS;
|
|
1132
1138
|
}
|
|
@@ -1148,6 +1154,12 @@ class LspClientTransport {
|
|
|
1148
1154
|
isDiagnosticPullSupported() {
|
|
1149
1155
|
return this.diagnosticPullSupported;
|
|
1150
1156
|
}
|
|
1157
|
+
setDocumentFormattingSupported(supported) {
|
|
1158
|
+
this.documentFormattingSupported = supported;
|
|
1159
|
+
}
|
|
1160
|
+
isDocumentFormattingSupported() {
|
|
1161
|
+
return this.documentFormattingSupported;
|
|
1162
|
+
}
|
|
1151
1163
|
handlePublishDiagnostics(params) {
|
|
1152
1164
|
this.diagnosticsStore.set(params.uri, [...params.diagnostics]);
|
|
1153
1165
|
}
|
|
@@ -1361,6 +1373,14 @@ function supportsDiagnosticPull(capabilities) {
|
|
|
1361
1373
|
return false;
|
|
1362
1374
|
return Object.hasOwn(capabilities, "diagnosticProvider");
|
|
1363
1375
|
}
|
|
1376
|
+
function supportsDocumentFormatting(capabilities) {
|
|
1377
|
+
if (capabilities === undefined)
|
|
1378
|
+
return false;
|
|
1379
|
+
const provider = capabilities.documentFormattingProvider;
|
|
1380
|
+
if (provider === undefined || provider === null || provider === false)
|
|
1381
|
+
return false;
|
|
1382
|
+
return provider === true || typeof provider === "object";
|
|
1383
|
+
}
|
|
1364
1384
|
|
|
1365
1385
|
class LspClientConnection extends LspClientTransport {
|
|
1366
1386
|
async initialize() {
|
|
@@ -1377,6 +1397,7 @@ class LspClientConnection extends LspClientTransport {
|
|
|
1377
1397
|
references: {},
|
|
1378
1398
|
documentSymbol: { hierarchicalDocumentSymbolSupport: true },
|
|
1379
1399
|
publishDiagnostics: {},
|
|
1400
|
+
formatting: { dynamicRegistration: false },
|
|
1380
1401
|
rename: {
|
|
1381
1402
|
prepareSupport: true,
|
|
1382
1403
|
prepareSupportDefaultBehavior: 1
|
|
@@ -1418,6 +1439,7 @@ class LspClientConnection extends LspClientTransport {
|
|
|
1418
1439
|
initializationOptions: this.server.initialization
|
|
1419
1440
|
}, { timeoutMs: this.initializeTimeoutMs });
|
|
1420
1441
|
this.setDiagnosticPullSupported(supportsDiagnosticPull(result?.capabilities));
|
|
1442
|
+
this.setDocumentFormattingSupported(supportsDocumentFormatting(result?.capabilities));
|
|
1421
1443
|
await this.sendNotification("initialized", {});
|
|
1422
1444
|
await this.sendNotification("workspace/didChangeConfiguration", {
|
|
1423
1445
|
settings: { json: { validate: { enable: true } } }
|
|
@@ -1623,16 +1645,12 @@ function movedPath(candidate, oldPath, newPath) {
|
|
|
1623
1645
|
}
|
|
1624
1646
|
|
|
1625
1647
|
class WorkspaceDocumentState {
|
|
1626
|
-
sendNotification;
|
|
1627
|
-
clearDiagnostics;
|
|
1628
|
-
openDocuments = new Map;
|
|
1629
|
-
openByUri = new Map;
|
|
1630
|
-
openPromises = new Map;
|
|
1631
|
-
now;
|
|
1632
|
-
versionlessPublishQuiescenceMs;
|
|
1633
1648
|
constructor(sendNotification, clearDiagnostics, options = {}) {
|
|
1634
1649
|
this.sendNotification = sendNotification;
|
|
1635
1650
|
this.clearDiagnostics = clearDiagnostics;
|
|
1651
|
+
this.openDocuments = new Map;
|
|
1652
|
+
this.openByUri = new Map;
|
|
1653
|
+
this.openPromises = new Map;
|
|
1636
1654
|
this.now = options.now ?? (() => Date.now());
|
|
1637
1655
|
this.versionlessPublishQuiescenceMs = options.versionlessPublishQuiescenceMs ?? DEFAULT_VERSIONLESS_PUBLISH_QUIESCENCE_MS;
|
|
1638
1656
|
}
|
|
@@ -1896,13 +1914,11 @@ import { dirname as dirname2, isAbsolute as isAbsolute2, relative as relative3,
|
|
|
1896
1914
|
import { fileURLToPath } from "node:url";
|
|
1897
1915
|
|
|
1898
1916
|
class WorkspaceEditPathError extends Error {
|
|
1899
|
-
path;
|
|
1900
|
-
detail;
|
|
1901
|
-
name = "WorkspaceEditPathError";
|
|
1902
1917
|
constructor(path, detail) {
|
|
1903
1918
|
super(`${detail}: ${path}`);
|
|
1904
1919
|
this.path = path;
|
|
1905
1920
|
this.detail = detail;
|
|
1921
|
+
this.name = "WorkspaceEditPathError";
|
|
1906
1922
|
}
|
|
1907
1923
|
}
|
|
1908
1924
|
function isPathInsideWorkspace(filePath, workspaceRoot) {
|
|
@@ -2194,13 +2210,11 @@ function canonicalFingerprint(operations) {
|
|
|
2194
2210
|
|
|
2195
2211
|
// ../lsp-core/src/lsp/workspace-edit-types.ts
|
|
2196
2212
|
class WorkspaceEditValidationError extends Error {
|
|
2197
|
-
changeIndex;
|
|
2198
|
-
detail;
|
|
2199
|
-
name = "WorkspaceEditValidationError";
|
|
2200
2213
|
constructor(changeIndex, detail) {
|
|
2201
2214
|
super(`change ${changeIndex}: ${detail}`);
|
|
2202
2215
|
this.changeIndex = changeIndex;
|
|
2203
2216
|
this.detail = detail;
|
|
2217
|
+
this.name = "WorkspaceEditValidationError";
|
|
2204
2218
|
}
|
|
2205
2219
|
}
|
|
2206
2220
|
|
|
@@ -2698,10 +2712,9 @@ function simulateDelete(operation, virtual) {
|
|
|
2698
2712
|
import { existsSync as existsSync5, lstatSync as lstatSync3, readdirSync as readdirSync2 } from "node:fs";
|
|
2699
2713
|
import { dirname as dirname4, resolve as resolve5 } from "node:path";
|
|
2700
2714
|
class WorkspaceSnapshotBuilder {
|
|
2701
|
-
workspaceRoot;
|
|
2702
|
-
snapshots = new Map;
|
|
2703
2715
|
constructor(workspaceRoot) {
|
|
2704
2716
|
this.workspaceRoot = workspaceRoot;
|
|
2717
|
+
this.snapshots = new Map;
|
|
2705
2718
|
}
|
|
2706
2719
|
build(operations) {
|
|
2707
2720
|
this.add(this.workspaceRoot, false);
|
|
@@ -2745,8 +2758,10 @@ function snapshotOperations(operations, workspaceRoot) {
|
|
|
2745
2758
|
|
|
2746
2759
|
// ../lsp-core/src/lsp/workspace-edit-plan.ts
|
|
2747
2760
|
class PlanPathIndex {
|
|
2748
|
-
|
|
2749
|
-
|
|
2761
|
+
constructor() {
|
|
2762
|
+
this.firstChangeByPath = new Map;
|
|
2763
|
+
this.reportedPathByCanonical = new Map;
|
|
2764
|
+
}
|
|
2750
2765
|
build(operations) {
|
|
2751
2766
|
for (const operation of operations) {
|
|
2752
2767
|
switch (operation.kind) {
|
|
@@ -2835,14 +2850,11 @@ function isRecord4(value) {
|
|
|
2835
2850
|
}
|
|
2836
2851
|
|
|
2837
2852
|
class WorkspaceMutationController {
|
|
2838
|
-
workspaceRoot;
|
|
2839
|
-
documents;
|
|
2840
|
-
activeLease = null;
|
|
2841
|
-
nextLeaseId = 1;
|
|
2842
|
-
io;
|
|
2843
2853
|
constructor(workspaceRoot, documents) {
|
|
2844
2854
|
this.workspaceRoot = workspaceRoot;
|
|
2845
2855
|
this.documents = documents;
|
|
2856
|
+
this.activeLease = null;
|
|
2857
|
+
this.nextLeaseId = 1;
|
|
2846
2858
|
}
|
|
2847
2859
|
setIo(io) {
|
|
2848
2860
|
this.io = io;
|
|
@@ -2955,12 +2967,9 @@ var DIAGNOSTICS_FRESHNESS_TIMEOUT_MS = 3000;
|
|
|
2955
2967
|
var VERSIONLESS_PUBLISH_QUIESCENCE_MS = 250;
|
|
2956
2968
|
|
|
2957
2969
|
class LspClient extends LspClientConnection {
|
|
2958
|
-
diagnosticPullErrors = [];
|
|
2959
|
-
documents;
|
|
2960
|
-
workspaceMutations;
|
|
2961
|
-
diagnosticsFreshnessTimeoutMs;
|
|
2962
2970
|
constructor(root, server2, options = {}) {
|
|
2963
2971
|
super(root, server2, options);
|
|
2972
|
+
this.diagnosticPullErrors = [];
|
|
2964
2973
|
this.diagnosticsFreshnessTimeoutMs = options.diagnosticsFreshnessTimeoutMs ?? DIAGNOSTICS_FRESHNESS_TIMEOUT_MS;
|
|
2965
2974
|
this.documents = new WorkspaceDocumentState((method, params) => this.sendNotification(method, params), (uri) => this.diagnosticsStore.delete(uri), {
|
|
2966
2975
|
versionlessPublishQuiescenceMs: options.versionlessPublishQuiescenceMs ?? VERSIONLESS_PUBLISH_QUIESCENCE_MS
|
|
@@ -3015,6 +3024,18 @@ class LspClient extends LspClientConnection {
|
|
|
3015
3024
|
textDocument: { uri: pathToFileURL3(absPath).href }
|
|
3016
3025
|
}, options);
|
|
3017
3026
|
}
|
|
3027
|
+
async formatDocument(filePath, options, signal) {
|
|
3028
|
+
if (!this.isDocumentFormattingSupported())
|
|
3029
|
+
return null;
|
|
3030
|
+
const absPath = this.resolveWorkspacePath(filePath);
|
|
3031
|
+
await this.openFile(absPath);
|
|
3032
|
+
const requestOptions = signal === undefined ? {} : { signal };
|
|
3033
|
+
const edits = await this.sendRequest("textDocument/formatting", {
|
|
3034
|
+
textDocument: { uri: pathToFileURL3(absPath).href },
|
|
3035
|
+
options
|
|
3036
|
+
}, requestOptions);
|
|
3037
|
+
return edits ?? [];
|
|
3038
|
+
}
|
|
3018
3039
|
async workspaceSymbols(query, signal) {
|
|
3019
3040
|
const options = signal === undefined ? {} : { signal };
|
|
3020
3041
|
return this.sendRequest("workspace/symbol", { query }, options);
|
|
@@ -3260,18 +3281,16 @@ function awaitWithSignal(promise, signal) {
|
|
|
3260
3281
|
}
|
|
3261
3282
|
|
|
3262
3283
|
class LspManager {
|
|
3263
|
-
clients = new Map;
|
|
3264
|
-
reaperHandle = null;
|
|
3265
|
-
signalDisposer = null;
|
|
3266
|
-
disposed = false;
|
|
3267
|
-
idleTimeoutMs;
|
|
3268
|
-
initTimeoutMs;
|
|
3269
|
-
reaperIntervalMs;
|
|
3270
|
-
clientFactory;
|
|
3271
|
-
now;
|
|
3272
3284
|
constructor(options = {}) {
|
|
3285
|
+
this.clients = new Map;
|
|
3286
|
+
this.pendingStops = new Map;
|
|
3287
|
+
this.respawnBudgets = new Map;
|
|
3288
|
+
this.reaperHandle = null;
|
|
3289
|
+
this.signalDisposer = null;
|
|
3290
|
+
this.disposed = false;
|
|
3273
3291
|
this.idleTimeoutMs = options.idleTimeoutMs ?? IDLE_TIMEOUT_MS;
|
|
3274
3292
|
this.initTimeoutMs = options.initTimeoutMs ?? INIT_TIMEOUT_MS;
|
|
3293
|
+
this.maxResidentClients = options.maxResidentClients ?? MAX_RESIDENT_CLIENTS;
|
|
3275
3294
|
this.reaperIntervalMs = options.reaperIntervalMs ?? REAPER_INTERVAL_MS;
|
|
3276
3295
|
this.clientFactory = options.clientFactory ?? ((root, server2) => new LspClient(root, server2));
|
|
3277
3296
|
this.now = options.now ?? (() => Date.now());
|
|
@@ -3291,24 +3310,79 @@ class LspManager {
|
|
|
3291
3310
|
getKey(root, serverId) {
|
|
3292
3311
|
return `${root}::${serverId}`;
|
|
3293
3312
|
}
|
|
3313
|
+
tombstoneStop(key, client) {
|
|
3314
|
+
const stop = stopClientBestEffort(client);
|
|
3315
|
+
this.pendingStops.set(key, stop);
|
|
3316
|
+
stop.finally(() => {
|
|
3317
|
+
if (this.pendingStops.get(key) === stop) {
|
|
3318
|
+
this.pendingStops.delete(key);
|
|
3319
|
+
}
|
|
3320
|
+
});
|
|
3321
|
+
return stop;
|
|
3322
|
+
}
|
|
3323
|
+
recordDeadGeneration(key) {
|
|
3324
|
+
let budget = this.respawnBudgets.get(key);
|
|
3325
|
+
if (budget === undefined) {
|
|
3326
|
+
budget = { deadGenerations: 0, exhaustedAt: null };
|
|
3327
|
+
this.respawnBudgets.set(key, budget);
|
|
3328
|
+
}
|
|
3329
|
+
budget.deadGenerations += 1;
|
|
3330
|
+
}
|
|
3331
|
+
markHealthyGeneration(key) {
|
|
3332
|
+
this.respawnBudgets.delete(key);
|
|
3333
|
+
}
|
|
3334
|
+
ensureRespawnAllowed(key, root, serverId) {
|
|
3335
|
+
const budget = this.respawnBudgets.get(key);
|
|
3336
|
+
if (budget === undefined || budget.deadGenerations < CLIENT_RESPAWN_RETRY_LIMIT)
|
|
3337
|
+
return;
|
|
3338
|
+
if (budget.exhaustedAt === null) {
|
|
3339
|
+
budget.exhaustedAt = this.now();
|
|
3340
|
+
throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
|
|
3341
|
+
}
|
|
3342
|
+
if (this.now() - budget.exhaustedAt < CLIENT_RESPAWN_COOLDOWN_MS) {
|
|
3343
|
+
throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
|
|
3344
|
+
}
|
|
3345
|
+
budget.deadGenerations = 0;
|
|
3346
|
+
budget.exhaustedAt = null;
|
|
3347
|
+
}
|
|
3294
3348
|
reapStale() {
|
|
3295
3349
|
const t = this.now();
|
|
3296
3350
|
for (const [key, managed] of this.clients) {
|
|
3297
3351
|
if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
|
|
3298
|
-
stopClientBestEffort(managed.client);
|
|
3299
3352
|
this.clients.delete(key);
|
|
3353
|
+
this.tombstoneStop(key, managed.client);
|
|
3300
3354
|
continue;
|
|
3301
3355
|
}
|
|
3302
3356
|
if (!managed.isInitializing && managed.refCount === 0 && managed.pendingWaiters === 0 && t - managed.lastUsedAt > this.idleTimeoutMs) {
|
|
3303
|
-
stopClientBestEffort(managed.client);
|
|
3304
3357
|
this.clients.delete(key);
|
|
3358
|
+
this.tombstoneStop(key, managed.client);
|
|
3359
|
+
}
|
|
3360
|
+
}
|
|
3361
|
+
}
|
|
3362
|
+
evictForAdmission() {
|
|
3363
|
+
while (this.clients.size >= this.maxResidentClients) {
|
|
3364
|
+
const victim = this.leastRecentlyUsedIdleClient();
|
|
3365
|
+
if (!victim)
|
|
3366
|
+
return;
|
|
3367
|
+
this.clients.delete(victim.key);
|
|
3368
|
+
this.tombstoneStop(victim.key, victim.managed.client);
|
|
3369
|
+
}
|
|
3370
|
+
}
|
|
3371
|
+
leastRecentlyUsedIdleClient() {
|
|
3372
|
+
let candidate = null;
|
|
3373
|
+
for (const [key, managed] of this.clients) {
|
|
3374
|
+
if (managed.refCount > 0 || managed.pendingWaiters > 0 || managed.isInitializing)
|
|
3375
|
+
continue;
|
|
3376
|
+
if (candidate === null || managed.lastUsedAt < candidate.managed.lastUsedAt) {
|
|
3377
|
+
candidate = { key, managed };
|
|
3305
3378
|
}
|
|
3306
3379
|
}
|
|
3380
|
+
return candidate;
|
|
3307
3381
|
}
|
|
3308
3382
|
async tryDeleteIfOrphaned(key, managed) {
|
|
3309
3383
|
if (managed.refCount === 0 && managed.pendingWaiters === 0 && !managed.isInitializing && this.clients.get(key) === managed) {
|
|
3310
3384
|
this.clients.delete(key);
|
|
3311
|
-
await
|
|
3385
|
+
await this.tombstoneStop(key, managed.client);
|
|
3312
3386
|
}
|
|
3313
3387
|
}
|
|
3314
3388
|
async getClient(root, server2, signal) {
|
|
@@ -3317,12 +3391,22 @@ class LspManager {
|
|
|
3317
3391
|
}
|
|
3318
3392
|
signal?.throwIfAborted();
|
|
3319
3393
|
const key = this.getKey(root, server2.id);
|
|
3394
|
+
for (;; ) {
|
|
3395
|
+
const pendingStop = this.pendingStops.get(key);
|
|
3396
|
+
if (pendingStop === undefined)
|
|
3397
|
+
break;
|
|
3398
|
+
await awaitWithSignal(pendingStop, signal);
|
|
3399
|
+
signal?.throwIfAborted();
|
|
3400
|
+
}
|
|
3401
|
+
if (this.disposed) {
|
|
3402
|
+
throw new Error("LspManager has been disposed");
|
|
3403
|
+
}
|
|
3320
3404
|
let managed = this.clients.get(key);
|
|
3321
3405
|
if (managed) {
|
|
3322
3406
|
const t = this.now();
|
|
3323
3407
|
if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
|
|
3324
|
-
await stopClientBestEffort(managed.client);
|
|
3325
3408
|
this.clients.delete(key);
|
|
3409
|
+
await this.tombstoneStop(key, managed.client);
|
|
3326
3410
|
managed = undefined;
|
|
3327
3411
|
}
|
|
3328
3412
|
}
|
|
@@ -3343,14 +3427,20 @@ class LspManager {
|
|
|
3343
3427
|
signal.throwIfAborted();
|
|
3344
3428
|
}
|
|
3345
3429
|
if (!managed.client.isAlive()) {
|
|
3346
|
-
|
|
3347
|
-
this.clients.
|
|
3430
|
+
this.recordDeadGeneration(key);
|
|
3431
|
+
if (this.clients.get(key) === managed) {
|
|
3432
|
+
this.clients.delete(key);
|
|
3433
|
+
}
|
|
3434
|
+
await this.tombstoneStop(key, managed.client);
|
|
3348
3435
|
return this.getClient(root, server2, signal);
|
|
3349
3436
|
}
|
|
3437
|
+
this.markHealthyGeneration(key);
|
|
3350
3438
|
managed.refCount++;
|
|
3351
3439
|
managed.lastUsedAt = this.now();
|
|
3352
3440
|
return managed.client;
|
|
3353
3441
|
}
|
|
3442
|
+
this.evictForAdmission();
|
|
3443
|
+
this.ensureRespawnAllowed(key, root, server2.id);
|
|
3354
3444
|
const client = this.clientFactory(root, server2);
|
|
3355
3445
|
const initStartedAt = this.now();
|
|
3356
3446
|
const initPromise = (async () => {
|
|
@@ -3374,7 +3464,7 @@ class LspManager {
|
|
|
3374
3464
|
if (this.clients.get(key) === newManaged) {
|
|
3375
3465
|
this.clients.delete(key);
|
|
3376
3466
|
}
|
|
3377
|
-
await
|
|
3467
|
+
await this.tombstoneStop(key, client);
|
|
3378
3468
|
throw err;
|
|
3379
3469
|
}
|
|
3380
3470
|
newManaged.pendingWaiters--;
|
|
@@ -3385,6 +3475,15 @@ class LspManager {
|
|
|
3385
3475
|
await this.tryDeleteIfOrphaned(key, newManaged);
|
|
3386
3476
|
signal.throwIfAborted();
|
|
3387
3477
|
}
|
|
3478
|
+
if (!client.isAlive()) {
|
|
3479
|
+
this.recordDeadGeneration(key);
|
|
3480
|
+
if (this.clients.get(key) === newManaged) {
|
|
3481
|
+
this.clients.delete(key);
|
|
3482
|
+
}
|
|
3483
|
+
await this.tombstoneStop(key, client);
|
|
3484
|
+
return this.getClient(root, server2, signal);
|
|
3485
|
+
}
|
|
3486
|
+
this.markHealthyGeneration(key);
|
|
3388
3487
|
newManaged.refCount++;
|
|
3389
3488
|
newManaged.lastUsedAt = this.now();
|
|
3390
3489
|
return client;
|
|
@@ -3405,14 +3504,20 @@ class LspManager {
|
|
|
3405
3504
|
if (client && managed.client !== client)
|
|
3406
3505
|
return;
|
|
3407
3506
|
this.clients.delete(key);
|
|
3408
|
-
|
|
3507
|
+
this.tombstoneStop(key, managed.client);
|
|
3409
3508
|
}
|
|
3410
3509
|
warmupClient(root, server2) {
|
|
3411
3510
|
if (this.disposed)
|
|
3412
3511
|
return;
|
|
3413
3512
|
const key = this.getKey(root, server2.id);
|
|
3414
|
-
if (this.clients.has(key))
|
|
3513
|
+
if (this.clients.has(key) || this.pendingStops.has(key))
|
|
3514
|
+
return;
|
|
3515
|
+
this.evictForAdmission();
|
|
3516
|
+
try {
|
|
3517
|
+
this.ensureRespawnAllowed(key, root, server2.id);
|
|
3518
|
+
} catch {
|
|
3415
3519
|
return;
|
|
3520
|
+
}
|
|
3416
3521
|
const client = this.clientFactory(root, server2);
|
|
3417
3522
|
const initStartedAt = this.now();
|
|
3418
3523
|
const initPromise = (async () => {
|
|
@@ -3438,7 +3543,7 @@ class LspManager {
|
|
|
3438
3543
|
if (this.clients.get(key) === managed) {
|
|
3439
3544
|
this.clients.delete(key);
|
|
3440
3545
|
}
|
|
3441
|
-
|
|
3546
|
+
this.tombstoneStop(key, client);
|
|
3442
3547
|
});
|
|
3443
3548
|
}
|
|
3444
3549
|
isServerInitializing(root, serverId) {
|
|
@@ -3482,8 +3587,11 @@ class LspManager {
|
|
|
3482
3587
|
for (const managed of this.clients.values()) {
|
|
3483
3588
|
stopPromises.push(stopClientBestEffort(managed.client));
|
|
3484
3589
|
}
|
|
3590
|
+
const tombstonedStops = [...this.pendingStops.values()];
|
|
3485
3591
|
this.clients.clear();
|
|
3486
|
-
|
|
3592
|
+
this.respawnBudgets.clear();
|
|
3593
|
+
await Promise.allSettled([...stopPromises, ...tombstonedStops]);
|
|
3594
|
+
this.pendingStops.clear();
|
|
3487
3595
|
}
|
|
3488
3596
|
}
|
|
3489
3597
|
var _defaultInstance = null;
|
|
@@ -3501,57 +3609,52 @@ async function disposeDefaultLspManager() {
|
|
|
3501
3609
|
}
|
|
3502
3610
|
}
|
|
3503
3611
|
|
|
3504
|
-
// ../lsp-core/src/lsp/
|
|
3505
|
-
import { existsSync as existsSync6,
|
|
3506
|
-
import { dirname as dirname5 } from "node:path";
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
|
|
3512
|
-
|
|
3513
|
-
|
|
3514
|
-
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
|
|
3518
|
-
|
|
3612
|
+
// ../lsp-core/src/lsp/outside-context-workspace.ts
|
|
3613
|
+
import { existsSync as existsSync6, realpathSync as realpathSync4 } from "node:fs";
|
|
3614
|
+
import { dirname as dirname5, join as join3 } from "node:path";
|
|
3615
|
+
|
|
3616
|
+
// ../lsp-core/src/lsp/workspace-markers.ts
|
|
3617
|
+
var GIT_WORKSPACE_MARKER = ".git";
|
|
3618
|
+
var PROJECT_WORKSPACE_MARKERS = [
|
|
3619
|
+
"package.json",
|
|
3620
|
+
"pyproject.toml",
|
|
3621
|
+
"Cargo.toml",
|
|
3622
|
+
"go.mod",
|
|
3623
|
+
"pom.xml",
|
|
3624
|
+
"build.gradle"
|
|
3625
|
+
];
|
|
3626
|
+
var WORKSPACE_MARKERS = [GIT_WORKSPACE_MARKER, ...PROJECT_WORKSPACE_MARKERS];
|
|
3627
|
+
|
|
3628
|
+
// ../lsp-core/src/lsp/outside-context-workspace.ts
|
|
3629
|
+
function findWorkspaceRootOutsideContext(directory) {
|
|
3630
|
+
const marked = nearestMarkedAncestor(directory);
|
|
3631
|
+
if (marked !== undefined)
|
|
3632
|
+
return marked;
|
|
3633
|
+
return realpathSync4(nearestExistingAncestor(directory));
|
|
3634
|
+
}
|
|
3635
|
+
function nearestMarkedAncestor(directory) {
|
|
3636
|
+
let current = directory;
|
|
3637
|
+
for (;; ) {
|
|
3638
|
+
if (existsSync6(current) && WORKSPACE_MARKERS.some((marker) => existsSync6(join3(current, marker)))) {
|
|
3639
|
+
return realpathSync4(current);
|
|
3640
|
+
}
|
|
3641
|
+
const parent = dirname5(current);
|
|
3642
|
+
if (parent === current)
|
|
3643
|
+
return;
|
|
3644
|
+
current = parent;
|
|
3519
3645
|
}
|
|
3520
3646
|
}
|
|
3521
|
-
function
|
|
3522
|
-
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
|
|
3526
|
-
|
|
3527
|
-
|
|
3528
|
-
}
|
|
3529
|
-
|
|
3530
|
-
return value === "declined" || value === "allowed";
|
|
3531
|
-
}
|
|
3532
|
-
function writeInstallDecisions(decisions) {
|
|
3533
|
-
const path = getInstallDecisionsPath();
|
|
3534
|
-
mkdirSync(dirname5(path), { recursive: true });
|
|
3535
|
-
const tmpPath = `${path}.tmp`;
|
|
3536
|
-
writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
|
|
3537
|
-
`, "utf8");
|
|
3538
|
-
renameSync2(tmpPath, path);
|
|
3539
|
-
}
|
|
3540
|
-
function isInstallDecisions(value) {
|
|
3541
|
-
return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
|
|
3542
|
-
}
|
|
3543
|
-
function isInstallDecisionRecord(value) {
|
|
3544
|
-
if (!isRecord5(value))
|
|
3545
|
-
return false;
|
|
3546
|
-
return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
|
|
3547
|
-
}
|
|
3548
|
-
function isRecord5(value) {
|
|
3549
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3647
|
+
function nearestExistingAncestor(directory) {
|
|
3648
|
+
let current = directory;
|
|
3649
|
+
while (!existsSync6(current)) {
|
|
3650
|
+
const parent = dirname5(current);
|
|
3651
|
+
if (parent === current)
|
|
3652
|
+
return current;
|
|
3653
|
+
current = parent;
|
|
3654
|
+
}
|
|
3655
|
+
return current;
|
|
3550
3656
|
}
|
|
3551
3657
|
|
|
3552
|
-
// ../lsp-core/src/lsp/config-loader.ts
|
|
3553
|
-
import { existsSync as existsSync7, readFileSync as readFileSync4 } from "node:fs";
|
|
3554
|
-
|
|
3555
3658
|
// ../lsp-core/src/lsp/server-definitions.ts
|
|
3556
3659
|
var LSP_INSTALL_HINTS = {
|
|
3557
3660
|
typescript: "npm install -g typescript-language-server typescript",
|
|
@@ -3597,6 +3700,26 @@ var LSP_INSTALL_HINTS = {
|
|
|
3597
3700
|
julials: `julia -e 'using Pkg; Pkg.add("LanguageServer")'`,
|
|
3598
3701
|
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"
|
|
3599
3702
|
};
|
|
3703
|
+
var LSP_LOCAL_INSTALL_HINTS = {
|
|
3704
|
+
typescript: "bun add -d typescript-language-server typescript",
|
|
3705
|
+
vue: "bun add -d @vue/language-server",
|
|
3706
|
+
eslint: "bun add -d vscode-langservers-extracted",
|
|
3707
|
+
oxlint: "bun add -d oxlint",
|
|
3708
|
+
biome: "bun add -d @biomejs/biome",
|
|
3709
|
+
svelte: "bun add -d svelte-language-server",
|
|
3710
|
+
astro: "bun add -d @astrojs/language-server",
|
|
3711
|
+
bash: "bun add -d bash-language-server",
|
|
3712
|
+
"bash-ls": "bun add -d bash-language-server",
|
|
3713
|
+
"yaml-ls": "bun add -d yaml-language-server",
|
|
3714
|
+
php: "bun add -d intelephense",
|
|
3715
|
+
prisma: "bun add -d prisma",
|
|
3716
|
+
dockerfile: "bun add -d dockerfile-language-server-nodejs",
|
|
3717
|
+
pyright: "uv add --dev pyright",
|
|
3718
|
+
basedpyright: "uv add --dev basedpyright",
|
|
3719
|
+
ruff: "uv add --dev ruff",
|
|
3720
|
+
ty: "uv add --dev ty",
|
|
3721
|
+
"ruby-lsp": "bundle add ruby-lsp --group development"
|
|
3722
|
+
};
|
|
3600
3723
|
var BUILTIN_SERVERS = {
|
|
3601
3724
|
typescript: {
|
|
3602
3725
|
command: ["typescript-language-server", "--stdio"],
|
|
@@ -3699,7 +3822,56 @@ var BUILTIN_SERVERS = {
|
|
|
3699
3822
|
}
|
|
3700
3823
|
};
|
|
3701
3824
|
|
|
3825
|
+
// ../lsp-core/src/lsp/server-install-state.ts
|
|
3826
|
+
import { existsSync as existsSync7, mkdirSync, readFileSync as readFileSync3, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
3827
|
+
import { dirname as dirname6 } from "node:path";
|
|
3828
|
+
function getInstallDecisionsPath() {
|
|
3829
|
+
return lspRequestContext().installDecisionsPath;
|
|
3830
|
+
}
|
|
3831
|
+
function loadInstallDecisions() {
|
|
3832
|
+
const path = getInstallDecisionsPath();
|
|
3833
|
+
if (!existsSync7(path))
|
|
3834
|
+
return {};
|
|
3835
|
+
try {
|
|
3836
|
+
const parsed = JSON.parse(readFileSync3(path, "utf8"));
|
|
3837
|
+
return isInstallDecisions(parsed) ? parsed : {};
|
|
3838
|
+
} catch {
|
|
3839
|
+
return {};
|
|
3840
|
+
}
|
|
3841
|
+
}
|
|
3842
|
+
function loadInstallDecision(serverId) {
|
|
3843
|
+
return loadInstallDecisions()[serverId];
|
|
3844
|
+
}
|
|
3845
|
+
function recordInstallDecision(serverId, decision, decidedAt = new Date().toISOString()) {
|
|
3846
|
+
const decisions = loadInstallDecisions();
|
|
3847
|
+
decisions[serverId] = { decision, decidedAt };
|
|
3848
|
+
writeInstallDecisions(decisions);
|
|
3849
|
+
}
|
|
3850
|
+
function isInstallDecision(value) {
|
|
3851
|
+
return value === "declined" || value === "allowed";
|
|
3852
|
+
}
|
|
3853
|
+
function writeInstallDecisions(decisions) {
|
|
3854
|
+
const path = getInstallDecisionsPath();
|
|
3855
|
+
mkdirSync(dirname6(path), { recursive: true });
|
|
3856
|
+
const tmpPath = `${path}.tmp`;
|
|
3857
|
+
writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
|
|
3858
|
+
`, "utf8");
|
|
3859
|
+
renameSync2(tmpPath, path);
|
|
3860
|
+
}
|
|
3861
|
+
function isInstallDecisions(value) {
|
|
3862
|
+
return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
|
|
3863
|
+
}
|
|
3864
|
+
function isInstallDecisionRecord(value) {
|
|
3865
|
+
if (!isRecord5(value))
|
|
3866
|
+
return false;
|
|
3867
|
+
return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
|
|
3868
|
+
}
|
|
3869
|
+
function isRecord5(value) {
|
|
3870
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3871
|
+
}
|
|
3872
|
+
|
|
3702
3873
|
// ../lsp-core/src/lsp/config-loader.ts
|
|
3874
|
+
import { existsSync as existsSync8, readFileSync as readFileSync4 } from "node:fs";
|
|
3703
3875
|
function getProjectConfigPaths() {
|
|
3704
3876
|
return lspRequestContext().projectConfigPaths;
|
|
3705
3877
|
}
|
|
@@ -3707,7 +3879,7 @@ function getUserConfigPath() {
|
|
|
3707
3879
|
return lspRequestContext().userConfigPath;
|
|
3708
3880
|
}
|
|
3709
3881
|
function loadJsonFile(path) {
|
|
3710
|
-
if (!
|
|
3882
|
+
if (!existsSync8(path))
|
|
3711
3883
|
return null;
|
|
3712
3884
|
try {
|
|
3713
3885
|
const parsed = JSON.parse(readFileSync4(path, "utf-8"));
|
|
@@ -3895,54 +4067,155 @@ function getDisabledServerIds() {
|
|
|
3895
4067
|
}
|
|
3896
4068
|
|
|
3897
4069
|
// ../lsp-core/src/lsp/server-installation.ts
|
|
3898
|
-
import { existsSync as
|
|
3899
|
-
import { delimiter as delimiter3, join as
|
|
3900
|
-
|
|
3901
|
-
|
|
3902
|
-
|
|
3903
|
-
|
|
3904
|
-
|
|
3905
|
-
|
|
3906
|
-
|
|
3907
|
-
|
|
3908
|
-
|
|
4070
|
+
import { existsSync as existsSync9 } from "node:fs";
|
|
4071
|
+
import { delimiter as delimiter3, dirname as dirname7, isAbsolute as isAbsolute3, join as join4, resolve as resolve7 } from "node:path";
|
|
4072
|
+
var LOCAL_BIN_RULES = [
|
|
4073
|
+
{
|
|
4074
|
+
markers: ["package.json", "bun.lock", "bun.lockb", "package-lock.json", "yarn.lock", "pnpm-lock.yaml"],
|
|
4075
|
+
binDirs: [join4("node_modules", ".bin")]
|
|
4076
|
+
},
|
|
4077
|
+
{
|
|
4078
|
+
markers: [
|
|
4079
|
+
"pyproject.toml",
|
|
4080
|
+
"ty.toml",
|
|
4081
|
+
"requirements.txt",
|
|
4082
|
+
"setup.py",
|
|
4083
|
+
"setup.cfg",
|
|
4084
|
+
"Pipfile",
|
|
4085
|
+
"pyrightconfig.json",
|
|
4086
|
+
"ruff.toml",
|
|
4087
|
+
".ruff.toml"
|
|
4088
|
+
],
|
|
4089
|
+
binDirs: [
|
|
4090
|
+
join4(".venv", "bin"),
|
|
4091
|
+
join4(".venv", "Scripts"),
|
|
4092
|
+
join4("venv", "bin"),
|
|
4093
|
+
join4("venv", "Scripts"),
|
|
4094
|
+
join4(".env", "bin"),
|
|
4095
|
+
join4(".env", "Scripts")
|
|
4096
|
+
]
|
|
4097
|
+
},
|
|
4098
|
+
{
|
|
4099
|
+
markers: ["Gemfile", "Gemfile.lock"],
|
|
4100
|
+
binDirs: [join4("vendor", "bundle", "bin"), "bin"]
|
|
4101
|
+
},
|
|
4102
|
+
{
|
|
4103
|
+
markers: ["go.mod", "go.sum", "go.work"],
|
|
4104
|
+
binDirs: ["bin"]
|
|
4105
|
+
}
|
|
4106
|
+
];
|
|
4107
|
+
var resolutionCache = new Map;
|
|
4108
|
+
var probeCount = 0;
|
|
4109
|
+
function probe(path) {
|
|
4110
|
+
probeCount += 1;
|
|
4111
|
+
return existsSync9(path);
|
|
4112
|
+
}
|
|
4113
|
+
function executableSuffixes(platform, pathExt) {
|
|
4114
|
+
if (platform !== "win32")
|
|
4115
|
+
return [""];
|
|
4116
|
+
const configured = pathExt ?? process.env["PATHEXT"] ?? "";
|
|
4117
|
+
const systemExts = configured.split(";").filter((entry) => entry.length > 0).map((entry) => entry.toLowerCase());
|
|
4118
|
+
return [...new Set(["", ...systemExts, ".exe", ".cmd", ".bat", ".ps1"])];
|
|
4119
|
+
}
|
|
4120
|
+
function probeWithSuffixes(directory, command, suffixes) {
|
|
4121
|
+
for (const suffix of suffixes) {
|
|
4122
|
+
const candidate = join4(directory, command + suffix);
|
|
4123
|
+
if (probe(candidate))
|
|
4124
|
+
return candidate;
|
|
3909
4125
|
}
|
|
3910
|
-
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
|
|
3915
|
-
|
|
3916
|
-
|
|
3917
|
-
|
|
3918
|
-
|
|
4126
|
+
return null;
|
|
4127
|
+
}
|
|
4128
|
+
function resolveLocal(command, workingDirectory, suffixes, stopAt) {
|
|
4129
|
+
const boundary = stopAt === undefined ? undefined : resolve7(stopAt);
|
|
4130
|
+
let current = resolve7(workingDirectory);
|
|
4131
|
+
while (true) {
|
|
4132
|
+
for (const rule of LOCAL_BIN_RULES) {
|
|
4133
|
+
if (!rule.markers.some((marker) => probe(join4(current, marker))))
|
|
4134
|
+
continue;
|
|
4135
|
+
for (const binDir of rule.binDirs) {
|
|
4136
|
+
const found = probeWithSuffixes(join4(current, binDir), command, suffixes);
|
|
4137
|
+
if (found !== null)
|
|
4138
|
+
return found;
|
|
4139
|
+
}
|
|
3919
4140
|
}
|
|
4141
|
+
if (probe(join4(current, ".git")))
|
|
4142
|
+
return null;
|
|
4143
|
+
if (boundary !== undefined && current === boundary)
|
|
4144
|
+
return null;
|
|
4145
|
+
const parent = dirname7(current);
|
|
4146
|
+
if (parent === current)
|
|
4147
|
+
return null;
|
|
4148
|
+
current = parent;
|
|
3920
4149
|
}
|
|
3921
|
-
|
|
3922
|
-
|
|
4150
|
+
}
|
|
4151
|
+
function resolveFromPath(command, suffixes, platform, pathEnvOverride) {
|
|
4152
|
+
let pathEnv = pathEnvOverride ?? process.env["PATH"] ?? "";
|
|
4153
|
+
if (platform === "win32" && !pathEnv) {
|
|
3923
4154
|
pathEnv = process.env["Path"] ?? "";
|
|
3924
4155
|
}
|
|
3925
|
-
const
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
}
|
|
4156
|
+
for (const entry of pathEnv.split(delimiter3)) {
|
|
4157
|
+
if (entry.length === 0)
|
|
4158
|
+
continue;
|
|
4159
|
+
const found = probeWithSuffixes(entry, command, suffixes);
|
|
4160
|
+
if (found !== null)
|
|
4161
|
+
return found;
|
|
3932
4162
|
}
|
|
3933
|
-
|
|
3934
|
-
|
|
3935
|
-
|
|
4163
|
+
return null;
|
|
4164
|
+
}
|
|
4165
|
+
function resolveServerBinary(command, workingDirectory, options = {}) {
|
|
4166
|
+
if (command.length === 0)
|
|
4167
|
+
return null;
|
|
4168
|
+
const [cmd] = command;
|
|
4169
|
+
if (cmd === undefined || cmd.length === 0)
|
|
4170
|
+
return null;
|
|
4171
|
+
const platform = options.platform ?? process.platform;
|
|
4172
|
+
const suffixes = executableSuffixes(platform, options.pathExt);
|
|
4173
|
+
if (cmd.includes("/") || cmd.includes("\\")) {
|
|
4174
|
+
const explicit = isAbsolute3(cmd) ? cmd : resolve7(workingDirectory ?? process.cwd(), cmd);
|
|
4175
|
+
return probe(explicit) ? explicit : null;
|
|
4176
|
+
}
|
|
4177
|
+
const cacheKey = JSON.stringify([
|
|
4178
|
+
workingDirectory ?? "",
|
|
4179
|
+
cmd,
|
|
4180
|
+
platform,
|
|
4181
|
+
options.stopAt ?? "",
|
|
4182
|
+
options.pathExt ?? "",
|
|
4183
|
+
options.pathEnv ?? process.env["PATH"] ?? ""
|
|
4184
|
+
]);
|
|
4185
|
+
const cached = resolutionCache.get(cacheKey);
|
|
4186
|
+
if (cached !== undefined)
|
|
4187
|
+
return cached;
|
|
4188
|
+
let resolved = null;
|
|
4189
|
+
if (workingDirectory !== undefined && workingDirectory.length > 0) {
|
|
4190
|
+
resolved = resolveLocal(cmd, workingDirectory, suffixes, options.stopAt);
|
|
4191
|
+
}
|
|
4192
|
+
resolved ??= resolveFromPath(cmd, suffixes, platform, options.pathEnv);
|
|
4193
|
+
if (resolved === null && cmd === "node")
|
|
4194
|
+
resolved = cmd;
|
|
4195
|
+
resolutionCache.set(cacheKey, resolved);
|
|
4196
|
+
return resolved;
|
|
4197
|
+
}
|
|
4198
|
+
function isServerInstalled(command, workingDirectory, options = {}) {
|
|
4199
|
+
if (command.length === 0)
|
|
4200
|
+
return false;
|
|
4201
|
+
return resolveServerBinary(command, workingDirectory, options) !== null;
|
|
3936
4202
|
}
|
|
3937
4203
|
|
|
3938
4204
|
// ../lsp-core/src/lsp/server-resolution.ts
|
|
4205
|
+
function withResolvedCommand(command, binaryPath) {
|
|
4206
|
+
return [binaryPath, ...command.slice(1)];
|
|
4207
|
+
}
|
|
3939
4208
|
function findServerForExtension(ext) {
|
|
3940
4209
|
const servers = getMergedServers();
|
|
4210
|
+
const workingDirectory = contextCwd();
|
|
3941
4211
|
for (const server2 of servers) {
|
|
3942
|
-
if (server2.extensions.includes(ext)
|
|
4212
|
+
if (!server2.extensions.includes(ext))
|
|
4213
|
+
continue;
|
|
4214
|
+
const binaryPath = resolveServerBinary(server2.command, workingDirectory);
|
|
4215
|
+
if (binaryPath !== null) {
|
|
3943
4216
|
const resolvedServer = {
|
|
3944
4217
|
id: server2.id,
|
|
3945
|
-
command: server2.command,
|
|
4218
|
+
command: withResolvedCommand(server2.command, binaryPath),
|
|
3946
4219
|
extensions: server2.extensions,
|
|
3947
4220
|
priority: server2.priority
|
|
3948
4221
|
};
|
|
@@ -3989,6 +4262,7 @@ function findServerForExtension(ext) {
|
|
|
3989
4262
|
function getAllServers() {
|
|
3990
4263
|
const servers = getMergedServers();
|
|
3991
4264
|
const disabled = getDisabledServerIds();
|
|
4265
|
+
const workingDirectory = contextCwd();
|
|
3992
4266
|
const result = [];
|
|
3993
4267
|
const seen = new Set;
|
|
3994
4268
|
for (const server2 of servers) {
|
|
@@ -3996,7 +4270,7 @@ function getAllServers() {
|
|
|
3996
4270
|
continue;
|
|
3997
4271
|
result.push({
|
|
3998
4272
|
id: server2.id,
|
|
3999
|
-
installed: isServerInstalled(server2.command),
|
|
4273
|
+
installed: isServerInstalled(server2.command, workingDirectory),
|
|
4000
4274
|
extensions: server2.extensions,
|
|
4001
4275
|
disabled: false,
|
|
4002
4276
|
source: server2.source,
|
|
@@ -4010,7 +4284,7 @@ function getAllServers() {
|
|
|
4010
4284
|
const builtin = BUILTIN_SERVERS[id];
|
|
4011
4285
|
result.push({
|
|
4012
4286
|
id,
|
|
4013
|
-
installed: builtin ? isServerInstalled(builtin.command) : false,
|
|
4287
|
+
installed: builtin ? isServerInstalled(builtin.command, workingDirectory) : false,
|
|
4014
4288
|
extensions: builtin?.extensions ?? [],
|
|
4015
4289
|
disabled: true,
|
|
4016
4290
|
source: "disabled",
|
|
@@ -4021,7 +4295,6 @@ function getAllServers() {
|
|
|
4021
4295
|
}
|
|
4022
4296
|
|
|
4023
4297
|
// ../lsp-core/src/lsp/client-wrapper.ts
|
|
4024
|
-
var WORKSPACE_MARKERS = [".git", "package.json", "pyproject.toml", "Cargo.toml", "go.mod", "pom.xml", "build.gradle"];
|
|
4025
4298
|
function isDirectoryPath(filePath) {
|
|
4026
4299
|
try {
|
|
4027
4300
|
return statSync3(filePath).isDirectory();
|
|
@@ -4030,32 +4303,90 @@ function isDirectoryPath(filePath) {
|
|
|
4030
4303
|
}
|
|
4031
4304
|
}
|
|
4032
4305
|
function findWorkspaceRoot(filePath) {
|
|
4033
|
-
const
|
|
4306
|
+
const cwd = contextCwd();
|
|
4307
|
+
const abs = resolveReadablePathInsideContext(filePath);
|
|
4034
4308
|
let dir = abs;
|
|
4035
4309
|
if (!isDirectoryPath(dir)) {
|
|
4036
|
-
dir =
|
|
4037
|
-
}
|
|
4038
|
-
|
|
4039
|
-
|
|
4040
|
-
|
|
4041
|
-
|
|
4042
|
-
|
|
4310
|
+
dir = dirname8(dir);
|
|
4311
|
+
}
|
|
4312
|
+
if (!isPathInside(cwd, abs))
|
|
4313
|
+
return findWorkspaceRootOutsideContext(dir);
|
|
4314
|
+
const fallbackRoot = nearestExistingDirectoryInsideContext(dir, cwd) ?? cwd;
|
|
4315
|
+
let nearestPackageRoot;
|
|
4316
|
+
while (isPathInside(cwd, dir)) {
|
|
4317
|
+
const canonicalDir = existingDirectoryInsideContext(dir, cwd);
|
|
4318
|
+
if (canonicalDir !== undefined) {
|
|
4319
|
+
if (existsSync10(join5(dir, GIT_WORKSPACE_MARKER))) {
|
|
4320
|
+
return canonicalDir;
|
|
4321
|
+
}
|
|
4322
|
+
if (nearestPackageRoot === undefined && hasProjectWorkspaceMarker(dir)) {
|
|
4323
|
+
nearestPackageRoot = canonicalDir;
|
|
4043
4324
|
}
|
|
4044
4325
|
}
|
|
4045
|
-
|
|
4046
|
-
|
|
4326
|
+
if (dir === cwd)
|
|
4327
|
+
break;
|
|
4328
|
+
dir = dirname8(dir);
|
|
4047
4329
|
}
|
|
4048
|
-
return
|
|
4330
|
+
return nearestPackageRoot ?? fallbackRoot;
|
|
4331
|
+
}
|
|
4332
|
+
function hasProjectWorkspaceMarker(directory) {
|
|
4333
|
+
return PROJECT_WORKSPACE_MARKERS.some((marker) => existsSync10(join5(directory, marker)));
|
|
4334
|
+
}
|
|
4335
|
+
function resolveReadablePathInsideContext(filePath) {
|
|
4336
|
+
const cwd = contextCwd();
|
|
4337
|
+
const abs = resolve8(cwd, filePath);
|
|
4338
|
+
if (isPathInside(cwd, abs))
|
|
4339
|
+
return abs;
|
|
4340
|
+
const rebased = rebaseThroughCanonicalAncestor(abs, cwd);
|
|
4341
|
+
if (rebased !== undefined)
|
|
4342
|
+
return rebased;
|
|
4343
|
+
return canonicalizeExistingOrNearestAncestor(abs);
|
|
4049
4344
|
}
|
|
4050
4345
|
function resolvePathInsideContext(filePath) {
|
|
4051
4346
|
const cwd = contextCwd();
|
|
4052
|
-
const abs =
|
|
4347
|
+
const abs = resolveReadablePathInsideContext(filePath);
|
|
4053
4348
|
const canonical = canonicalizeExistingOrNearestAncestor(abs);
|
|
4054
4349
|
if (!isPathInside(cwd, canonical)) {
|
|
4055
4350
|
throw new LspInvalidPathError(`LSP file path must be inside request cwd: ${filePath}`);
|
|
4056
4351
|
}
|
|
4057
4352
|
return canonical;
|
|
4058
4353
|
}
|
|
4354
|
+
function rebaseThroughCanonicalAncestor(path, cwd) {
|
|
4355
|
+
let current = path;
|
|
4356
|
+
const suffix = [];
|
|
4357
|
+
while (true) {
|
|
4358
|
+
if (existsSync10(current)) {
|
|
4359
|
+
const canonical = realpathSync5(current);
|
|
4360
|
+
if (isPathInside(cwd, canonical))
|
|
4361
|
+
return suffix.length === 0 ? canonical : join5(canonical, ...suffix);
|
|
4362
|
+
}
|
|
4363
|
+
const parent = dirname8(current);
|
|
4364
|
+
if (parent === current)
|
|
4365
|
+
return;
|
|
4366
|
+
suffix.unshift(basename3(current));
|
|
4367
|
+
current = parent;
|
|
4368
|
+
}
|
|
4369
|
+
}
|
|
4370
|
+
function existingDirectoryInsideContext(directory, cwd) {
|
|
4371
|
+
if (!existsSync10(directory))
|
|
4372
|
+
return;
|
|
4373
|
+
const canonical = realpathSync5(directory);
|
|
4374
|
+
if (!statSync3(canonical).isDirectory())
|
|
4375
|
+
return;
|
|
4376
|
+
return isPathInside(cwd, canonical) ? canonical : undefined;
|
|
4377
|
+
}
|
|
4378
|
+
function nearestExistingDirectoryInsideContext(directory, cwd) {
|
|
4379
|
+
let current = directory;
|
|
4380
|
+
while (isPathInside(cwd, current)) {
|
|
4381
|
+
const canonical = existingDirectoryInsideContext(current, cwd);
|
|
4382
|
+
if (canonical !== undefined)
|
|
4383
|
+
return canonical;
|
|
4384
|
+
if (current === cwd)
|
|
4385
|
+
return;
|
|
4386
|
+
current = dirname8(current);
|
|
4387
|
+
}
|
|
4388
|
+
return;
|
|
4389
|
+
}
|
|
4059
4390
|
function formatServerLookupError(result) {
|
|
4060
4391
|
if (result.status === "not_installed") {
|
|
4061
4392
|
return formatNotInstalled(result);
|
|
@@ -4079,6 +4410,19 @@ function formatServerLookupError(result) {
|
|
|
4079
4410
|
].join(`
|
|
4080
4411
|
`);
|
|
4081
4412
|
}
|
|
4413
|
+
function formatInstallOptions(serverId, installHint) {
|
|
4414
|
+
const localHint = LSP_LOCAL_INSTALL_HINTS[serverId];
|
|
4415
|
+
if (localHint === undefined) {
|
|
4416
|
+
return ["To install, run:", ` ${installHint}`];
|
|
4417
|
+
}
|
|
4418
|
+
return [
|
|
4419
|
+
"To install in THIS repository (preferred — no global install needed):",
|
|
4420
|
+
` ${localHint}`,
|
|
4421
|
+
"",
|
|
4422
|
+
"Or install it globally:",
|
|
4423
|
+
` ${installHint}`
|
|
4424
|
+
];
|
|
4425
|
+
}
|
|
4082
4426
|
function formatNotInstalled(result) {
|
|
4083
4427
|
const { server: server2, installHint } = result;
|
|
4084
4428
|
const extensions = server2.extensions.join(", ");
|
|
@@ -4093,19 +4437,19 @@ function formatNotInstalled(result) {
|
|
|
4093
4437
|
`Command not found: ${server2.command[0]}`,
|
|
4094
4438
|
""
|
|
4095
4439
|
];
|
|
4440
|
+
const installOptions = formatInstallOptions(server2.id, installHint);
|
|
4096
4441
|
if (decision === "allowed") {
|
|
4097
4442
|
return [
|
|
4098
4443
|
...header,
|
|
4099
4444
|
"The user has pre-authorized LSP installation. Run the install command, then retry this tool:",
|
|
4100
|
-
|
|
4445
|
+
...installOptions.slice(1)
|
|
4101
4446
|
].join(`
|
|
4102
4447
|
`);
|
|
4103
4448
|
}
|
|
4104
4449
|
if (!context.capabilities.installDecisionTool) {
|
|
4105
4450
|
return [
|
|
4106
4451
|
...header,
|
|
4107
|
-
|
|
4108
|
-
` ${installHint}`,
|
|
4452
|
+
...installOptions,
|
|
4109
4453
|
"",
|
|
4110
4454
|
"ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
|
|
4111
4455
|
"Install-decision recording is unavailable in this harness; proceed without LSP if the user declines."
|
|
@@ -4114,8 +4458,7 @@ function formatNotInstalled(result) {
|
|
|
4114
4458
|
}
|
|
4115
4459
|
return [
|
|
4116
4460
|
...header,
|
|
4117
|
-
|
|
4118
|
-
` ${installHint}`,
|
|
4461
|
+
...installOptions,
|
|
4119
4462
|
"",
|
|
4120
4463
|
"ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
|
|
4121
4464
|
"- If the user agrees: run the install command above, then retry this tool.",
|
|
@@ -4126,7 +4469,7 @@ function formatNotInstalled(result) {
|
|
|
4126
4469
|
].join(`
|
|
4127
4470
|
`);
|
|
4128
4471
|
}
|
|
4129
|
-
var
|
|
4472
|
+
var READ_ONLY_TOOLS = new Set([
|
|
4130
4473
|
"diagnostics",
|
|
4131
4474
|
"definition",
|
|
4132
4475
|
"references",
|
|
@@ -4135,7 +4478,7 @@ var READ_ONLY_RETRY_TOOLS = new Set([
|
|
|
4135
4478
|
"prepareRename"
|
|
4136
4479
|
]);
|
|
4137
4480
|
async function withLspClient(filePath, fn, toolName, options = {}) {
|
|
4138
|
-
const absPath = resolvePathInsideContext(filePath);
|
|
4481
|
+
const absPath = READ_ONLY_TOOLS.has(toolName) ? resolveReadablePathInsideContext(filePath) : resolvePathInsideContext(filePath);
|
|
4139
4482
|
if (isDirectoryPath(absPath)) {
|
|
4140
4483
|
throw new LspInvalidPathError("Directory paths are not supported by this LSP tool. " + "Use lsp.diagnostics with a directory path for directory diagnostics.");
|
|
4141
4484
|
}
|
|
@@ -4150,9 +4493,9 @@ async function withLspClient(filePath, fn, toolName, options = {}) {
|
|
|
4150
4493
|
const acquireAndCall = async (allowRetry) => {
|
|
4151
4494
|
const client = await manager.getClient(root, server2, options.signal);
|
|
4152
4495
|
try {
|
|
4153
|
-
return await fn(client, root);
|
|
4496
|
+
return await fn(client, root, absPath);
|
|
4154
4497
|
} catch (err) {
|
|
4155
|
-
if (allowRetry &&
|
|
4498
|
+
if (allowRetry && READ_ONLY_TOOLS.has(toolName) && isLspDeadConnectionError(err)) {
|
|
4156
4499
|
manager.invalidateClient(root, server2.id, client);
|
|
4157
4500
|
return acquireAndCall(false);
|
|
4158
4501
|
}
|
|
@@ -4170,8 +4513,8 @@ async function withLspClient(filePath, fn, toolName, options = {}) {
|
|
|
4170
4513
|
}
|
|
4171
4514
|
|
|
4172
4515
|
// ../lsp-core/src/lsp/directory-diagnostics.ts
|
|
4173
|
-
import { existsSync as
|
|
4174
|
-
import { join as
|
|
4516
|
+
import { existsSync as existsSync11, lstatSync as lstatSync4, readdirSync as readdirSync3 } from "node:fs";
|
|
4517
|
+
import { join as join6, resolve as resolve9 } from "node:path";
|
|
4175
4518
|
|
|
4176
4519
|
// ../lsp-core/src/lsp/formatters.ts
|
|
4177
4520
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
@@ -4301,7 +4644,7 @@ function collectFilesWithExtension(dir, extension, maxFiles) {
|
|
|
4301
4644
|
for (const entry of entries) {
|
|
4302
4645
|
if (files.length >= maxFiles)
|
|
4303
4646
|
return;
|
|
4304
|
-
const fullPath =
|
|
4647
|
+
const fullPath = join6(currentDir, entry);
|
|
4305
4648
|
let stat;
|
|
4306
4649
|
try {
|
|
4307
4650
|
stat = lstatSync4(fullPath);
|
|
@@ -4326,8 +4669,8 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
|
|
|
4326
4669
|
if (!extension.startsWith(".")) {
|
|
4327
4670
|
throw new LspInvalidPathError(`Extension must start with a dot (e.g., ".ts", not "${extension}"). Use ".${extension}" instead.`);
|
|
4328
4671
|
}
|
|
4329
|
-
const absDir =
|
|
4330
|
-
if (!
|
|
4672
|
+
const absDir = resolve9(options.workspaceRoot ?? contextCwd(), directory);
|
|
4673
|
+
if (!existsSync11(absDir)) {
|
|
4331
4674
|
throw new LspInvalidPathError(`Directory does not exist: ${absDir}`);
|
|
4332
4675
|
}
|
|
4333
4676
|
const serverResult = options.server === undefined ? findServerForExtension(extension) : { status: "found", server: options.server };
|
|
@@ -4414,7 +4757,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
|
|
|
4414
4757
|
|
|
4415
4758
|
// ../lsp-core/src/lsp/infer-extension.ts
|
|
4416
4759
|
import { lstatSync as lstatSync5, readdirSync as readdirSync4 } from "node:fs";
|
|
4417
|
-
import { join as
|
|
4760
|
+
import { join as join7 } from "node:path";
|
|
4418
4761
|
var SKIP_DIRECTORIES2 = new Set(["node_modules", ".git", "dist", "build", ".next", "out"]);
|
|
4419
4762
|
var MAX_SCAN_ENTRIES = 500;
|
|
4420
4763
|
function inferExtensionFromDirectory(directory) {
|
|
@@ -4432,7 +4775,7 @@ function inferExtensionFromDirectory(directory) {
|
|
|
4432
4775
|
for (const entry of entries) {
|
|
4433
4776
|
if (scanned >= MAX_SCAN_ENTRIES)
|
|
4434
4777
|
return;
|
|
4435
|
-
const fullPath =
|
|
4778
|
+
const fullPath = join7(dir, entry);
|
|
4436
4779
|
let stat;
|
|
4437
4780
|
try {
|
|
4438
4781
|
stat = lstatSync5(fullPath);
|
|
@@ -4607,7 +4950,7 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
4607
4950
|
const filePath = requireString(params, "filePath");
|
|
4608
4951
|
const severity = severityFilter(params);
|
|
4609
4952
|
try {
|
|
4610
|
-
const absPath =
|
|
4953
|
+
const absPath = resolveReadablePathInsideContext(filePath);
|
|
4611
4954
|
if (isDirectoryPath(absPath)) {
|
|
4612
4955
|
const extension = inferExtensionFromDirectory(absPath);
|
|
4613
4956
|
if (!extension) {
|
|
@@ -4636,7 +4979,7 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
4636
4979
|
};
|
|
4637
4980
|
return text(output2.output, details2);
|
|
4638
4981
|
}
|
|
4639
|
-
const result = await withLspClient(filePath, async (client) => client.diagnostics(
|
|
4982
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.diagnostics(resolvedFilePath, signal), "diagnostics", clientOptions(signal));
|
|
4640
4983
|
if (result.transientError) {
|
|
4641
4984
|
const message = result.transientError.message;
|
|
4642
4985
|
const details2 = {
|
|
@@ -4683,6 +5026,96 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
4683
5026
|
throw error;
|
|
4684
5027
|
}
|
|
4685
5028
|
}
|
|
5029
|
+
// ../lsp-core/src/lsp/format-document.ts
|
|
5030
|
+
import { readFileSync as readFileSync5, renameSync as renameSync3, unlinkSync, writeFileSync as writeFileSync3 } from "node:fs";
|
|
5031
|
+
var DEFAULT_FORMATTING_OPTIONS = {
|
|
5032
|
+
tabSize: 4,
|
|
5033
|
+
insertSpaces: false,
|
|
5034
|
+
trimTrailingWhitespace: true,
|
|
5035
|
+
insertFinalNewline: true,
|
|
5036
|
+
trimFinalNewlines: true
|
|
5037
|
+
};
|
|
5038
|
+
var UNCHANGED = { status: "unchanged", linesAdded: 0, linesRemoved: 0 };
|
|
5039
|
+
async function formatDocumentWithClient(client, filePath, options = {}) {
|
|
5040
|
+
const edits = await client.formatDocument(filePath, options.formattingOptions ?? DEFAULT_FORMATTING_OPTIONS, options.signal);
|
|
5041
|
+
if (edits === null)
|
|
5042
|
+
return { status: "unavailable", reason: "capability_not_advertised" };
|
|
5043
|
+
if (edits.length === 0)
|
|
5044
|
+
return UNCHANGED;
|
|
5045
|
+
const before = readFileSync5(filePath, "utf-8");
|
|
5046
|
+
const normalized = normalizeTextEdits(before, edits, 0);
|
|
5047
|
+
if (normalized.text === before)
|
|
5048
|
+
return UNCHANGED;
|
|
5049
|
+
writeAtomically(filePath, normalized.text);
|
|
5050
|
+
await client.openFile(filePath);
|
|
5051
|
+
return {
|
|
5052
|
+
status: "formatted",
|
|
5053
|
+
...lineDelta(normalized.edits)
|
|
5054
|
+
};
|
|
5055
|
+
}
|
|
5056
|
+
function lineDelta(edits) {
|
|
5057
|
+
let linesAdded = 0;
|
|
5058
|
+
let linesRemoved = 0;
|
|
5059
|
+
for (const edit of edits) {
|
|
5060
|
+
linesRemoved += edit.range.end.line - edit.range.start.line + 1;
|
|
5061
|
+
linesAdded += edit.newText.split(`
|
|
5062
|
+
`).length;
|
|
5063
|
+
}
|
|
5064
|
+
return { linesAdded, linesRemoved };
|
|
5065
|
+
}
|
|
5066
|
+
function writeAtomically(filePath, content) {
|
|
5067
|
+
const tempPath = `${filePath}.omo-format.tmp`;
|
|
5068
|
+
writeFileSync3(tempPath, content, "utf-8");
|
|
5069
|
+
try {
|
|
5070
|
+
renameSync3(tempPath, filePath);
|
|
5071
|
+
} catch (error) {
|
|
5072
|
+
try {
|
|
5073
|
+
unlinkSync(tempPath);
|
|
5074
|
+
} catch {}
|
|
5075
|
+
throw error;
|
|
5076
|
+
}
|
|
5077
|
+
}
|
|
5078
|
+
|
|
5079
|
+
// ../lsp-core/src/tools/format.ts
|
|
5080
|
+
async function executeLspFormat(params, signal) {
|
|
5081
|
+
const filePath = requireString(params, "filePath");
|
|
5082
|
+
try {
|
|
5083
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => formatDocumentWithClient(client, resolvedFilePath, signal === undefined ? {} : { signal }), "format", clientOptions(signal));
|
|
5084
|
+
return text(describeResult(filePath, result), formatDetails(filePath, result));
|
|
5085
|
+
} catch (error) {
|
|
5086
|
+
const missingDependency = missingDependencyResult(error, {
|
|
5087
|
+
filePath,
|
|
5088
|
+
status: "unavailable",
|
|
5089
|
+
reason: "server_unavailable",
|
|
5090
|
+
linesAdded: 0,
|
|
5091
|
+
linesRemoved: 0
|
|
5092
|
+
});
|
|
5093
|
+
if (missingDependency)
|
|
5094
|
+
return missingDependency;
|
|
5095
|
+
throw error;
|
|
5096
|
+
}
|
|
5097
|
+
}
|
|
5098
|
+
function formatDetails(filePath, result) {
|
|
5099
|
+
if (result.status === "unavailable") {
|
|
5100
|
+
return { filePath, status: "unavailable", reason: result.reason, linesAdded: 0, linesRemoved: 0 };
|
|
5101
|
+
}
|
|
5102
|
+
return {
|
|
5103
|
+
filePath,
|
|
5104
|
+
status: result.status,
|
|
5105
|
+
linesAdded: result.linesAdded,
|
|
5106
|
+
linesRemoved: result.linesRemoved
|
|
5107
|
+
};
|
|
5108
|
+
}
|
|
5109
|
+
function describeResult(filePath, result) {
|
|
5110
|
+
if (result.status === "unavailable") {
|
|
5111
|
+
return `Formatting unavailable for ${filePath}: the language server does not advertise documentFormattingProvider.`;
|
|
5112
|
+
}
|
|
5113
|
+
if (result.status === "unchanged") {
|
|
5114
|
+
return `Already formatted: ${filePath}`;
|
|
5115
|
+
}
|
|
5116
|
+
return `Formatted ${filePath} (+${result.linesAdded}/-${result.linesRemoved} lines)`;
|
|
5117
|
+
}
|
|
5118
|
+
|
|
4686
5119
|
// ../lsp-core/src/tools/install-decision.ts
|
|
4687
5120
|
async function executeLspInstallDecision(params) {
|
|
4688
5121
|
const serverId = requireString(params, "server_id");
|
|
@@ -4711,7 +5144,7 @@ async function executeLspGotoDefinition(params, signal) {
|
|
|
4711
5144
|
const line = requireNumber(params, "line");
|
|
4712
5145
|
const character = requireNumber(params, "character");
|
|
4713
5146
|
try {
|
|
4714
|
-
const result = await withLspClient(filePath, async (client) => client.definition(
|
|
5147
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.definition(resolvedFilePath, line, character, signal), "definition", clientOptions(signal));
|
|
4715
5148
|
const locations = !result ? [] : Array.isArray(result) ? result : [result];
|
|
4716
5149
|
const details = { filePath, line, character, locations };
|
|
4717
5150
|
if (locations.length === 0)
|
|
@@ -4736,7 +5169,7 @@ async function executeLspFindReferences(params, signal) {
|
|
|
4736
5169
|
const character = requireNumber(params, "character");
|
|
4737
5170
|
const includeDeclaration = optionalBoolean(params, "includeDeclaration") ?? true;
|
|
4738
5171
|
try {
|
|
4739
|
-
const result = await withLspClient(filePath, async (client) => client.references(
|
|
5172
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.references(resolvedFilePath, line, character, includeDeclaration, signal), "references", clientOptions(signal));
|
|
4740
5173
|
const references = Array.isArray(result) ? result : [];
|
|
4741
5174
|
const total = references.length;
|
|
4742
5175
|
const truncated = total > DEFAULT_MAX_REFERENCES;
|
|
@@ -4778,7 +5211,7 @@ async function executeLspPrepareRename(params, signal) {
|
|
|
4778
5211
|
const line = requireNumber(params, "line");
|
|
4779
5212
|
const character = requireNumber(params, "character");
|
|
4780
5213
|
try {
|
|
4781
|
-
const result = await withLspClient(filePath, async (client) => client.prepareRename(
|
|
5214
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.prepareRename(resolvedFilePath, line, character, signal), "prepareRename", clientOptions(signal));
|
|
4782
5215
|
const details = { filePath, line, character, result };
|
|
4783
5216
|
return text(formatPrepareRenameResult(result), details);
|
|
4784
5217
|
} catch (error) {
|
|
@@ -4799,7 +5232,7 @@ async function executeLspRename(params, signal) {
|
|
|
4799
5232
|
const character = requireNumber(params, "character");
|
|
4800
5233
|
const newName = requireString(params, "newName");
|
|
4801
5234
|
try {
|
|
4802
|
-
const result = await withLspClient(filePath, async (client) => client.rename(
|
|
5235
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.rename(resolvedFilePath, line, character, newName, signal), "rename", clientOptions(signal));
|
|
4803
5236
|
const details = { filePath, line, character, newName, apply: result.apply, edit: result.edit };
|
|
4804
5237
|
return text(formatApplyResult(result.apply), details, !result.apply.success);
|
|
4805
5238
|
} catch (error) {
|
|
@@ -4879,7 +5312,7 @@ async function executeLspSymbols(params, signal) {
|
|
|
4879
5312
|
const symbols2 = await withLspClient(filePath, async (client) => client.workspaceSymbols(query, signal), "workspaceSymbols", clientOptions(signal));
|
|
4880
5313
|
return formatSymbolsResult(filePath, scope, symbols2, limit, query);
|
|
4881
5314
|
}
|
|
4882
|
-
const symbols = await withLspClient(filePath, async (client) => client.documentSymbols(
|
|
5315
|
+
const symbols = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.documentSymbols(resolvedFilePath, signal), "documentSymbols", clientOptions(signal));
|
|
4883
5316
|
return formatSymbolsResult(filePath, scope, symbols, limit);
|
|
4884
5317
|
} catch (error) {
|
|
4885
5318
|
const query = optionalString(params, "query");
|
|
@@ -5015,6 +5448,16 @@ var LSP_MCP_TOOLS = [
|
|
|
5015
5448
|
}, ["filePath", "line", "character", "newName"]),
|
|
5016
5449
|
execute: executeLspRename
|
|
5017
5450
|
},
|
|
5451
|
+
{
|
|
5452
|
+
name: "format",
|
|
5453
|
+
aliases: ["lsp_format"],
|
|
5454
|
+
title: "LSP Format",
|
|
5455
|
+
description: "Format a source file with its language server and write the returned edits to disk.",
|
|
5456
|
+
inputSchema: objectSchema({
|
|
5457
|
+
filePath: { type: "string", description: "Source file path to format." }
|
|
5458
|
+
}, ["filePath"]),
|
|
5459
|
+
execute: executeLspFormat
|
|
5460
|
+
},
|
|
5018
5461
|
{
|
|
5019
5462
|
name: "install_decision",
|
|
5020
5463
|
aliases: ["lsp_install_decision"],
|
|
@@ -5122,6 +5565,6 @@ function requestedProtocolVersion(params) {
|
|
|
5122
5565
|
return params["protocolVersion"];
|
|
5123
5566
|
}
|
|
5124
5567
|
export {
|
|
5125
|
-
|
|
5126
|
-
|
|
5568
|
+
handleLspMcpRequest,
|
|
5569
|
+
runMcpStdioServer
|
|
5127
5570
|
};
|