oh-my-opencode 5.0.0-beta.3 → 5.0.0-beta.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/command/publish.md +44 -16
- package/.agents/skills/publish/SKILL.md +44 -16
- package/.agents/skills/senpi-qa/SKILL.md +80 -0
- package/.agents/skills/senpi-qa/scripts/resolve-evidence-dir.mjs +65 -0
- package/.agents/skills/senpi-qa/scripts/resolve-evidence-dir.test.mjs +171 -0
- package/.agents/skills/work-with-pr/SKILL.md +37 -23
- package/.opencode/command/publish.md +44 -16
- package/.opencode/skills/work-with-pr/SKILL.md +37 -23
- package/README.ja.md +25 -21
- package/README.ko.md +25 -21
- package/README.md +38 -23
- package/README.ru.md +24 -20
- package/README.zh-cn.md +25 -21
- package/dist/agents/atlas/agent.d.ts +0 -1
- package/dist/agents/sisyphus/grok-4.d.ts +20 -0
- package/dist/agents/sisyphus/index.d.ts +2 -0
- package/dist/agents/sisyphus-agent-config.d.ts +6 -0
- package/dist/agents/sisyphus-agent-factory.d.ts +1 -1
- package/dist/agents/sisyphus-runtime-prompt-reconciler.d.ts +15 -4
- package/dist/agents/types.d.ts +2 -2
- package/dist/cli/config-manager/parse-opencode-config-file.d.ts +2 -1
- package/dist/cli/doctor/checks/system-plugin.d.ts +4 -3
- package/dist/cli/fallback-lane-policy.d.ts +1 -0
- package/dist/cli/index.js +22601 -20302
- package/dist/cli/install-codex/install-codex-test-fixtures.d.ts +1 -1
- package/dist/cli/run/on-complete-hook.d.ts +2 -0
- package/dist/cli/runtime-commands.d.ts +1 -1
- package/dist/cli/worktree-sweep/classify.d.ts +16 -0
- package/dist/cli/worktree-sweep/format.d.ts +8 -0
- package/dist/cli/worktree-sweep/git.d.ts +19 -0
- package/dist/cli/worktree-sweep/index.d.ts +7 -0
- package/dist/cli/worktree-sweep/options.d.ts +2 -0
- package/dist/cli/worktree-sweep/parse-worktree-list.d.ts +8 -0
- package/dist/cli/worktree-sweep/sweep.d.ts +2 -0
- package/dist/cli/worktree-sweep/types.d.ts +65 -0
- package/dist/cli/worktree-sweep/worktree-sweep.d.ts +2 -0
- package/dist/cli-node/index.js +22219 -19897
- package/dist/config/schema/background-task.d.ts +1 -0
- package/dist/config/schema/commands.d.ts +1 -1
- package/dist/config/schema/hooks.d.ts +1 -1
- package/dist/config/schema/oh-my-opencode-config.d.ts +5 -1
- package/dist/config/schema/ulw-execute.d.ts +5 -0
- package/dist/config/validate.d.ts +2 -0
- package/dist/create-hooks.d.ts +3 -1
- package/dist/features/background-agent/constants.d.ts +0 -7
- package/dist/features/background-agent/manager.d.ts +2 -1
- package/dist/features/background-agent/parent-wake-dispatched-tracker.d.ts +0 -1
- package/dist/features/background-agent/subagent-spawn-limits.d.ts +8 -0
- package/dist/features/btw-side/btw-command-draft.d.ts +7 -0
- package/dist/features/btw-side/context-injector.d.ts +15 -0
- package/dist/features/btw-side/index.d.ts +8 -0
- package/dist/features/btw-side/metadata.d.ts +15 -0
- package/dist/features/btw-side/parent-context-budget.d.ts +9 -0
- package/dist/features/btw-side/server-session-registry.d.ts +8 -0
- package/dist/features/btw-side/tui-adoption-cache.d.ts +13 -0
- package/dist/features/btw-side/tui-adoption-guard.d.ts +5 -0
- package/dist/features/btw-side/tui-controller-types.d.ts +68 -0
- package/dist/features/btw-side/tui-controller.d.ts +19 -0
- package/dist/features/btw-side/tui-escape-return.d.ts +12 -0
- package/dist/features/btw-side/tui-keymap.d.ts +17 -0
- package/dist/features/btw-side/tui-parent-validator.d.ts +6 -0
- package/dist/features/btw-side/tui-picker-options.d.ts +20 -0
- package/dist/features/btw-side/tui-picker.d.ts +9 -0
- package/dist/features/btw-side/tui-prompt-queue.d.ts +8 -0
- package/dist/features/btw-side/tui-session-bridge.d.ts +11 -0
- package/dist/features/btw-side/tui-session-catalog.d.ts +35 -0
- package/dist/features/btw-side/tui-side-removal.d.ts +11 -0
- package/dist/features/btw-side/tui-side-start.d.ts +9 -0
- package/dist/features/btw-side/tui-wiring.d.ts +8 -0
- package/dist/features/builtin-commands/templates/ulw-execute.d.ts +1 -0
- package/dist/features/builtin-commands/types.d.ts +1 -1
- package/dist/features/opengateway-provider/index.d.ts +13 -0
- package/dist/features/task-toast-manager/manager.d.ts +0 -24
- package/dist/features/team-mode/tools/messaging-fallback-wake.d.ts +15 -0
- package/dist/hooks/anthropic-context-window-limit-recovery/message-storage-directory.d.ts +0 -3
- package/dist/hooks/anthropic-context-window-limit-recovery/state.d.ts +1 -0
- package/dist/hooks/anthropic-context-window-limit-recovery/storage/empty-messages.d.ts +0 -1
- package/dist/hooks/atlas/atlas-hook.d.ts +1 -0
- package/dist/hooks/atlas/atlas-lifecycle-store.d.ts +50 -0
- package/dist/hooks/atlas/event-handler.d.ts +1 -0
- package/dist/hooks/atlas/final-wave-approval-gate.test-support.d.ts +50 -0
- package/dist/hooks/atlas/system-reminder-templates.d.ts +0 -1
- package/dist/hooks/atlas/tool-execute-before.d.ts +3 -0
- package/dist/hooks/atlas/types.d.ts +1 -0
- package/dist/hooks/claude-code-hooks/session-hook-state.d.ts +1 -0
- package/dist/hooks/claude-code-hooks/stop.d.ts +2 -0
- package/dist/hooks/claude-code-hooks/todo.d.ts +0 -1
- package/dist/hooks/claude-code-hooks/transcript.d.ts +2 -0
- package/dist/hooks/fsync-skip-warning/index.d.ts +4 -0
- package/dist/hooks/hashline-edit-diff-enhancer/hook.d.ts +1 -0
- package/dist/hooks/hashline-edit-diff-enhancer/pending-captures.d.ts +13 -0
- package/dist/hooks/index.d.ts +1 -1
- package/dist/hooks/keyword-detector/hook.d.ts +7 -0
- package/dist/hooks/keyword-detector/ultrawork/source-detector.d.ts +0 -1
- package/dist/hooks/model-fallback/hook.d.ts +1 -1
- package/dist/hooks/prometheus-md-only/agent-resolution.d.ts +2 -2
- package/dist/hooks/runtime-fallback/chat-message-handler.d.ts +2 -0
- package/dist/hooks/runtime-fallback/retry-model-payload.d.ts +1 -0
- package/dist/hooks/runtime-fallback/runtime-model-settings.d.ts +6 -0
- package/dist/hooks/runtime-fallback/session-status-handler.d.ts +1 -1
- package/dist/hooks/runtime-fallback/types.d.ts +3 -1
- package/dist/hooks/sisyphus-junior-notepad/constants.d.ts +1 -1
- package/dist/hooks/todo-continuation-enforcer/types.d.ts +1 -0
- package/dist/hooks/{start-work → ulw-execute}/context-info-builder.d.ts +1 -1
- package/dist/hooks/{start-work → ulw-execute}/index.d.ts +1 -1
- package/dist/hooks/ulw-execute/ulw-execute-hook.d.ts +23 -0
- package/dist/index.js +12989 -7152
- package/dist/oh-my-opencode.schema.json +20 -2
- package/dist/plugin/chat-message/types.d.ts +3 -3
- package/dist/plugin/chat-message/ulw-execute-message.d.ts +5 -0
- package/dist/plugin/event-session-lifecycle.d.ts +1 -0
- package/dist/plugin/hooks/create-core-hooks.d.ts +2 -1
- package/dist/plugin/hooks/create-session-hooks.d.ts +2 -2
- package/dist/plugin/hooks/create-transform-hooks.d.ts +2 -0
- package/dist/plugin/messages-transform.d.ts +1 -0
- package/dist/plugin-dispose.d.ts +3 -0
- package/dist/shared/agent-tool-restrictions.d.ts +0 -1
- package/dist/shared/index.d.ts +2 -0
- package/dist/shared/legacy-plugin-warning.d.ts +2 -1
- package/dist/shared/normalize-sdk-response.d.ts +1 -0
- package/dist/shared/plugin-entry-migrator.d.ts +4 -3
- package/dist/shared/plugin-entry-shape.d.ts +6 -0
- package/dist/shared/runtime-fallback-retry-marker.d.ts +16 -0
- package/dist/shared/shell-env.d.ts +1 -1
- package/dist/skills/ast-grep/AGENTS.md +51 -0
- package/dist/skills/coding-agent-sessions/AGENTS.md +62 -0
- package/dist/skills/coding-agent-sessions/SKILL.md +3 -2
- package/dist/skills/coding-agent-sessions/references/all-platforms.md +1 -1
- package/dist/skills/coding-agent-sessions/references/senpi.md +4 -4
- package/dist/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +1 -1
- package/dist/skills/data-scientist/SKILL.md +99 -239
- package/dist/skills/data-scientist/references/execution-surfaces.md +91 -0
- package/dist/skills/data-scientist/references/placement.md +74 -0
- package/dist/skills/data-scientist/references/polars-lane.md +95 -0
- package/dist/skills/data-scientist/references/uv-setup.md +1 -1
- package/dist/skills/data-scientist/references/visualization.md +64 -0
- package/dist/skills/data-scientist/scripts/ensure-js-deps.sh +28 -0
- package/dist/skills/data-scientist/scripts/ensure-py-deps.sh +37 -0
- package/dist/skills/debugging/SKILL.md +2 -0
- package/dist/skills/debugging/references/methodology/00-setup.md +12 -0
- package/dist/skills/debugging/references/methodology/02-investigate.md +21 -0
- package/dist/skills/debugging/references/runtimes/go.md +15 -1
- package/dist/skills/debugging/references/runtimes/native-binary.md +38 -0
- package/dist/skills/debugging/references/runtimes/node.md +25 -0
- package/dist/skills/debugging/references/runtimes/python.md +13 -0
- package/dist/skills/debugging/references/runtimes/rust.md +41 -0
- package/dist/skills/debugging/references/scripts/dap.mjs +267 -0
- package/dist/skills/debugging/references/scripts/dap.test.ts +86 -0
- package/dist/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
- package/dist/skills/debugging/references/tools/dap.md +103 -0
- package/dist/skills/debugging/references/tools/frida.md +193 -0
- package/dist/skills/frontend/SKILL.md +11 -7
- package/dist/skills/frontend/references/design/_INDEX.md +1 -0
- package/dist/skills/frontend/references/design/print-paged-media.md +76 -0
- package/dist/skills/frontend/references/design/stylegallery.md +80 -0
- package/dist/skills/frontend/references/designpowers/README.md +1 -1
- package/dist/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
- package/dist/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
- package/dist/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
- package/dist/skills/frontend/references/designpowers/orchestration.md +1 -1
- package/dist/skills/frontend/references/designpowers/routing.md +5 -5
- package/dist/skills/review-work/SKILL.md +3 -3
- package/dist/skills/ultimate-browsing/ATTRIBUTION.md +37 -10
- package/dist/skills/ultimate-browsing/SKILL.md +2 -0
- package/dist/skills/ultimate-browsing/engine/AGENTS.md +179 -0
- package/dist/skills/ultimate-browsing/engine/templates/package.json +1 -1
- package/dist/skills/ultimate-browsing/references/chrome-stealth.md +13 -11
- package/dist/skills/{start-work → ulw-execute}/SKILL.md +9 -8
- package/dist/skills/ulw-plan/SKILL.md +6 -6
- package/dist/skills/ulw-plan/references/full-workflow.md +31 -7
- package/dist/skills/ulw-plan/references/intent-clear.md +2 -1
- package/dist/skills/ulw-plan/references/intent-unclear.md +5 -5
- package/dist/skills/ulw-research/SKILL.md +4 -2
- package/dist/skills/visual-qa/AGENTS.md +58 -0
- package/dist/skills/visual-qa/SKILL.md +3 -2
- package/dist/tools/delegate-task/builtin-categories.d.ts +1 -0
- package/dist/tools/delegate-task/builtin-category-definition.d.ts +1 -0
- package/dist/tools/delegate-task/sync-session-cleanup.d.ts +3 -0
- package/dist/tools/delegate-task/sync-session-poller.d.ts +1 -0
- package/dist/tools/delegate-task/tool-description.d.ts +3 -1
- package/dist/tools/delegate-task/types.d.ts +4 -0
- package/dist/tui.d.ts +12 -0
- package/dist/tui.js +11522 -11501
- package/package.json +42 -36
- package/packages/git-bash-mcp/dist/cli.js +6 -1
- package/packages/git-bash-mcp/package.json +1 -1
- package/packages/lsp-core/src/index.ts +1 -0
- package/packages/lsp-core/src/lsp/client-diagnostics-concurrency.integration.test.ts +44 -0
- package/packages/lsp-core/src/lsp/client-diagnostics-freshness.integration.test.ts +0 -28
- package/packages/lsp-core/src/lsp/client-wrapper-outside-cwd.test.ts +78 -0
- package/packages/lsp-core/src/lsp/client-wrapper.test.ts +163 -13
- package/packages/lsp-core/src/lsp/client-wrapper.ts +110 -23
- package/packages/lsp-core/src/lsp/client.ts +26 -0
- package/packages/lsp-core/src/lsp/connection.ts +16 -0
- package/packages/lsp-core/src/lsp/constants.ts +6 -0
- package/packages/lsp-core/src/lsp/errors.ts +15 -0
- package/packages/lsp-core/src/lsp/format-document.test.ts +143 -0
- package/packages/lsp-core/src/lsp/format-document.ts +90 -0
- package/packages/lsp-core/src/lsp/manager-lifecycle.test.ts +262 -0
- package/packages/lsp-core/src/lsp/manager-max-clients.test.ts +151 -0
- package/packages/lsp-core/src/lsp/manager.ts +138 -12
- package/packages/lsp-core/src/lsp/outside-context-workspace.ts +33 -0
- package/packages/lsp-core/src/lsp/server-definitions.ts +29 -0
- package/packages/lsp-core/src/lsp/server-installation.test.ts +376 -0
- package/packages/lsp-core/src/lsp/server-installation.ts +200 -27
- package/packages/lsp-core/src/lsp/server-resolution-local-binary.test.ts +170 -0
- package/packages/lsp-core/src/lsp/server-resolution.ts +18 -5
- package/packages/lsp-core/src/lsp/transport.ts +9 -0
- package/packages/lsp-core/src/lsp/types.ts +8 -0
- package/packages/lsp-core/src/lsp/workspace-edit-adversarial.test.ts +20 -1
- package/packages/lsp-core/src/lsp/workspace-markers.ts +18 -0
- package/packages/lsp-core/src/mcp.ts +3 -0
- package/packages/lsp-core/src/request-context.test.ts +29 -0
- package/packages/lsp-core/src/request-context.ts +1 -1
- package/packages/lsp-core/src/tool-surface.test.ts +13 -1
- package/packages/lsp-core/src/tools/definitions.ts +14 -0
- package/packages/lsp-core/src/tools/diagnostics.ts +3 -3
- package/packages/lsp-core/src/tools/format.test.ts +56 -0
- package/packages/lsp-core/src/tools/format.ts +56 -0
- package/packages/lsp-core/src/tools/index.ts +1 -0
- package/packages/lsp-core/src/tools/navigation.ts +4 -2
- package/packages/lsp-core/src/tools/rename.ts +4 -2
- package/packages/lsp-core/src/tools/symbols.ts +1 -1
- package/packages/lsp-core/src/tools/types.ts +10 -0
- package/packages/lsp-daemon/dist/cli.js +752 -307
- package/packages/lsp-daemon/dist/client.d.ts +10 -0
- package/packages/lsp-daemon/dist/client.js +712 -264
- package/packages/lsp-daemon/dist/daemon-client.d.ts +1 -0
- package/packages/lsp-daemon/dist/daemon-client.js +3 -0
- package/packages/lsp-daemon/dist/ensure-daemon.js +1 -0
- package/packages/lsp-daemon/dist/index.js +716 -273
- package/packages/lsp-daemon/dist/proxy.js +3 -0
- package/packages/lsp-daemon/dist/version-reap.js +1 -1
- package/packages/lsp-daemon/package.json +1 -1
- package/packages/lsp-tools-mcp/dist/cli.js +671 -228
- package/packages/lsp-tools-mcp/dist/lsp/manager.js +207 -103
- package/packages/lsp-tools-mcp/dist/mcp.js +673 -230
- package/packages/lsp-tools-mcp/dist/request-context.js +12 -13
- package/packages/lsp-tools-mcp/dist/tools.js +677 -238
- package/packages/omo-codex/THIRD-PARTY-NOTICES.md +4 -4
- package/packages/omo-codex/plugin/.codex-plugin/plugin.json +4 -4
- package/packages/omo-codex/plugin/AGENTS.md +47 -0
- package/packages/omo-codex/plugin/README.md +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +34 -33
- package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/src/hook.ts +1 -0
- package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +323 -117
- package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +275 -85
- package/packages/omo-codex/plugin/components/codegraph/package.json +4 -4
- package/packages/omo-codex/plugin/components/codegraph/src/mcp-bridge.ts +1 -0
- package/packages/omo-codex/plugin/components/codegraph/src/mcp-unavailable.ts +12 -0
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-hook-runtime.ts +1 -0
- package/packages/omo-codex/plugin/components/codegraph/test/serve-unavailable-idle.test.ts +47 -0
- package/packages/omo-codex/plugin/components/comment-checker/AGENTS.md +9 -0
- package/packages/omo-codex/plugin/components/comment-checker/biome.json +2 -2
- package/packages/omo-codex/plugin/components/comment-checker/dist/cli.js +2 -1
- package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/package.json +5 -5
- package/packages/omo-codex/plugin/components/comment-checker/src/apply-patch.ts +2 -8
- package/packages/omo-codex/plugin/components/comment-checker/src/core.ts +1 -2
- package/packages/omo-codex/plugin/components/comment-checker/src/request-extractor.ts +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/src/runner.ts +1 -0
- package/packages/omo-codex/plugin/components/git-bash/AGENTS.md +1 -1
- package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/git-bash/package.json +3 -4
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/biome.json +2 -2
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/cli.js +1 -5
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/codex-hook.js +1 -5
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +5 -5
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/src/codex-hook.ts +1 -5
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/test/codex-hook.test.ts +4 -21
- package/packages/omo-codex/plugin/components/lsp/AGENTS.md +30 -15
- package/packages/omo-codex/plugin/components/lsp/biome.json +2 -2
- package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +4 -4
- package/packages/omo-codex/plugin/components/lsp/dist/cli.js +702 -278
- package/packages/omo-codex/plugin/components/lsp/dist/daemon-cli-path.js +1 -1
- package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/lsp/package.json +5 -5
- package/packages/omo-codex/plugin/components/lsp/src/cli.ts +1 -1
- package/packages/omo-codex/plugin/components/lsp/src/codex-hook.ts +1 -1
- package/packages/omo-codex/plugin/components/lsp/src/daemon-cli-path.ts +1 -5
- package/packages/omo-codex/plugin/components/lsp/test/codex-hook-unavailable.test.ts +6 -7
- package/packages/omo-codex/plugin/components/lsp/test/codex-hook.test.ts +1 -2
- package/packages/omo-codex/plugin/components/lsp/test/package-smoke.test.ts +11 -1
- package/packages/omo-codex/plugin/components/rules/AGENTS.md +12 -0
- package/packages/omo-codex/plugin/components/rules/biome.json +2 -2
- package/packages/omo-codex/plugin/components/rules/dist/cli.js +60 -45
- package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
- package/packages/omo-codex/plugin/components/rules/package.json +7 -7
- package/packages/omo-codex/plugin/components/rules/src/config.ts +1 -2
- package/packages/omo-codex/plugin/components/rules/src/persistent-cache.ts +1 -2
- package/packages/omo-codex/plugin/components/rules/src/post-compact-budget.ts +9 -5
- package/packages/omo-codex/plugin/components/rules/src/rules-engine-factory.ts +1 -4
- package/packages/omo-codex/plugin/components/rules/src/static-injection.ts +4 -9
- package/packages/omo-codex/plugin/components/rules/test/bundled-rules-priority.test.ts +11 -16
- package/packages/omo-codex/plugin/components/rules/test/bundled-rules.test.ts +17 -25
- package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-budget.test.ts +9 -7
- package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-context.test.ts +0 -6
- package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-dedup.test.ts +6 -4
- package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-directive.test.ts +12 -9
- package/packages/omo-codex/plugin/components/rules/test/codex-hook.test.ts +28 -37
- package/packages/omo-codex/plugin/components/rules/test/dynamic-target-fingerprints.test.ts +1 -2
- package/packages/omo-codex/plugin/components/rules/test/engine.test.ts +7 -4
- package/packages/omo-codex/plugin/components/rules/test/finder.test.ts +2 -3
- package/packages/omo-codex/plugin/components/rules/test/formatter.test.ts +39 -72
- package/packages/omo-codex/plugin/components/rules/test/hephaestus-model-variant.test.ts +1 -2
- package/packages/omo-codex/plugin/components/rules/test/hook-output.test.ts +2 -3
- package/packages/omo-codex/plugin/components/rules/test/matcher.test.ts +2 -3
- package/packages/omo-codex/plugin/components/rules/test/package-smoke.test.ts +1 -1
- package/packages/omo-codex/plugin/components/rules/test/parser.test.ts +1 -2
- package/packages/omo-codex/plugin/components/rules/test/post-compact-budget.test.ts +5 -6
- package/packages/omo-codex/plugin/components/rules/test/rules-engine-consumption.test.ts +3 -6
- package/packages/omo-codex/plugin/components/rules/test/scanner.test.ts +1 -2
- package/packages/omo-codex/plugin/components/rules/test/sources.test.ts +2 -5
- package/packages/omo-codex/plugin/components/rules/test/windows-git-bash-bundled-rule.test.ts +2 -17
- package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/package.json +5 -5
- package/packages/omo-codex/plugin/components/teammode/test/thread-title-hook.test.ts +3 -9
- package/packages/omo-codex/plugin/components/telemetry/AGENTS.md +8 -0
- package/packages/omo-codex/plugin/components/telemetry/biome.json +2 -2
- package/packages/omo-codex/plugin/components/telemetry/dist/cli.js +2463 -437
- package/packages/omo-codex/plugin/components/telemetry/dist/posthog.js +2467 -441
- package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/package.json +5 -5
- package/packages/omo-codex/plugin/components/telemetry/src/codex-hook.ts +1 -4
- package/packages/omo-codex/plugin/components/telemetry/src/posthog.ts +4 -14
- package/packages/omo-codex/plugin/components/telemetry/src/product-identity.ts +1 -1
- package/packages/omo-codex/plugin/components/telemetry/test/diagnostics.test.ts +2 -5
- package/packages/omo-codex/plugin/components/ultrawork/AGENTS.md +5 -0
- package/packages/omo-codex/plugin/components/ultrawork/biome.json +2 -2
- package/packages/omo-codex/plugin/components/ultrawork/directive.md +13 -1
- package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/package.json +5 -5
- package/packages/omo-codex/plugin/components/ultrawork/skills/ultrawork/SKILL.md +13 -1
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +6 -6
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +31 -7
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-clear.md +2 -1
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-unclear.md +5 -5
- package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook-trigger-policy.test.ts +9 -1
- package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook.test.ts +0 -136
- package/packages/omo-codex/plugin/components/ultrawork/test/skill-pointer.test.ts +0 -2
- package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/AGENTS.md +5 -4
- package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/NOTICE +1 -1
- package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/README.md +5 -5
- package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/biome.json +2 -2
- package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/directive.md +6 -6
- package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/dist/cli.js +12 -12
- package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +28 -0
- package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/package.json +12 -12
- package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/boulder-reader.ts +1 -1
- package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/cli.ts +1 -1
- package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/codex-hook.ts +3 -3
- package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/directive.ts +1 -1
- package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/index.ts +1 -1
- package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/boulder-reader.test.ts +3 -3
- package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/cli.test.ts +1 -4
- package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/codex-hook.test.ts +8 -22
- package/packages/omo-codex/plugin/components/ulw-loop/AGENTS.md +17 -0
- package/packages/omo-codex/plugin/components/ulw-loop/CHANGELOG.md +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/biome.json +2 -2
- package/packages/omo-codex/plugin/components/ulw-loop/directive.md +13 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.js +2 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-commands.js +5 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.d.ts +2 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.js +11 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +124 -68
- package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.d.ts +2 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.js +9 -6
- package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-snapshot.js +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/paths.js +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.d.ts +4 -2
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.js +7 -10
- package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-guard.js +3 -2
- package/packages/omo-codex/plugin/components/ulw-loop/dist/stop-resume-hook.js +3 -3
- package/packages/omo-codex/plugin/components/ulw-loop/dist/surface.d.ts +15 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/surface.js +50 -0
- package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +4 -4
- package/packages/omo-codex/plugin/components/ulw-loop/package.json +5 -5
- package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md +3 -2
- package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/define-goal.md +108 -0
- package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +1 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint.ts +2 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/cli-commands.ts +5 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/cli-output.ts +13 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/cli.ts +3 -5
- package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-instruction.ts +16 -5
- package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-snapshot.ts +3 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/codex-hook.ts +3 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/paths.ts +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate.ts +11 -14
- package/packages/omo-codex/plugin/components/ulw-loop/src/spawn-guard.ts +3 -2
- package/packages/omo-codex/plugin/components/ulw-loop/src/stop-resume-hook.ts +3 -3
- package/packages/omo-codex/plugin/components/ulw-loop/src/surface.ts +73 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-continuation.test.ts +0 -1
- package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-final.test.ts +44 -1
- package/packages/omo-codex/plugin/components/ulw-loop/test/cli-create-goals.test.ts +25 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/cli-entrypoint.test.ts +26 -2
- package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-instruction.test.ts +27 -2
- package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-snapshot.test.ts +18 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/codex-hook.test.ts +0 -3
- package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/quality-gate-builder.ts +7 -3
- package/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts +5 -37
- package/packages/omo-codex/plugin/components/ulw-loop/test/paths.test.ts +9 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-roles.test.ts +45 -2
- package/packages/omo-codex/plugin/components/ulw-loop/test/spawn-guard.test.ts +20 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/steering.test.ts +8 -5
- package/packages/omo-codex/plugin/components/ulw-loop/test/stop-resume-hook.test.ts +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/test/surface.test.ts +74 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/ultrawork-directive.test.ts +4 -5
- package/packages/omo-codex/plugin/components/ulw-loop/vitest.config.ts +1 -0
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
- package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +17 -0
- package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
- package/packages/omo-codex/plugin/hooks/subagent-stop-checking-ulw-execute-continuation.json +17 -0
- package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
- package/packages/omo-codex/plugin/model-catalog.json +3 -3
- package/packages/omo-codex/plugin/package-lock.json +681 -395
- package/packages/omo-codex/plugin/package.json +2 -2
- package/packages/omo-codex/plugin/scripts/AGENTS.md +40 -0
- package/packages/omo-codex/plugin/scripts/auto-update-plan.mjs +1 -1
- package/packages/omo-codex/plugin/scripts/migrate-codex-config/catalog.mjs +3 -3
- package/packages/omo-codex/plugin/scripts/sync-skills.mjs +11 -11
- package/packages/omo-codex/plugin/shared/package.json +3 -4
- package/packages/omo-codex/plugin/skills/ast-grep/AGENTS.md +51 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/AGENTS.md +62 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/SKILL.md +3 -2
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/all-platforms.md +1 -1
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/senpi.md +4 -4
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +1 -1
- package/packages/omo-codex/plugin/skills/data-scientist/SKILL.md +99 -239
- package/packages/omo-codex/plugin/skills/data-scientist/references/execution-surfaces.md +91 -0
- package/packages/omo-codex/plugin/skills/data-scientist/references/placement.md +74 -0
- package/packages/omo-codex/plugin/skills/data-scientist/references/polars-lane.md +95 -0
- package/packages/omo-codex/plugin/skills/data-scientist/references/uv-setup.md +1 -1
- package/packages/omo-codex/plugin/skills/data-scientist/references/visualization.md +64 -0
- package/packages/omo-codex/plugin/skills/data-scientist/scripts/ensure-js-deps.sh +28 -0
- package/packages/omo-codex/plugin/skills/data-scientist/scripts/ensure-py-deps.sh +37 -0
- package/packages/omo-codex/plugin/skills/debugging/SKILL.md +2 -0
- package/packages/omo-codex/plugin/skills/debugging/references/methodology/00-setup.md +12 -0
- package/packages/omo-codex/plugin/skills/debugging/references/methodology/02-investigate.md +21 -0
- package/packages/omo-codex/plugin/skills/debugging/references/runtimes/go.md +15 -1
- package/packages/omo-codex/plugin/skills/debugging/references/runtimes/native-binary.md +38 -0
- package/packages/omo-codex/plugin/skills/debugging/references/runtimes/node.md +25 -0
- package/packages/omo-codex/plugin/skills/debugging/references/runtimes/python.md +13 -0
- package/packages/omo-codex/plugin/skills/debugging/references/runtimes/rust.md +41 -0
- package/packages/omo-codex/plugin/skills/debugging/references/scripts/dap.mjs +267 -0
- package/packages/omo-codex/plugin/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
- package/packages/omo-codex/plugin/skills/debugging/references/tools/dap.md +103 -0
- package/packages/omo-codex/plugin/skills/debugging/references/tools/frida.md +193 -0
- package/packages/omo-codex/plugin/skills/frontend/SKILL.md +11 -7
- package/packages/omo-codex/plugin/skills/frontend/references/design/_INDEX.md +1 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/print-paged-media.md +76 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/stylegallery.md +80 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/README.md +1 -1
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/orchestration.md +1 -1
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/routing.md +5 -5
- package/packages/omo-codex/plugin/skills/review-work/SKILL.md +4 -4
- package/packages/omo-codex/plugin/skills/ultimate-browsing/ATTRIBUTION.md +37 -10
- package/packages/omo-codex/plugin/skills/ultimate-browsing/SKILL.md +2 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/AGENTS.md +179 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/templates/package.json +1 -1
- package/packages/omo-codex/plugin/skills/ultimate-browsing/references/chrome-stealth.md +13 -11
- package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +13 -1
- package/packages/omo-codex/plugin/skills/{start-work → ulw-execute}/SKILL.md +12 -11
- package/packages/omo-codex/plugin/skills/ulw-execute/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +3 -2
- package/packages/omo-codex/plugin/skills/ulw-loop/references/define-goal.md +108 -0
- package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +1 -0
- package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +6 -6
- package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +31 -7
- package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-clear.md +2 -1
- package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-unclear.md +5 -5
- package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +4 -2
- package/packages/omo-codex/plugin/skills/visual-qa/AGENTS.md +58 -0
- package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +3 -2
- package/packages/omo-codex/plugin/test/AGENTS.md +47 -0
- package/packages/omo-codex/plugin/test/aggregate-agents.test.mjs +19 -173
- package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +8 -28
- package/packages/omo-codex/plugin/test/aggregate-manifest.test.mjs +1 -1
- package/packages/omo-codex/plugin/test/aggregate-model-catalog.test.mjs +1 -1
- package/packages/omo-codex/plugin/test/aggregate-plugin-fixture.mjs +175 -13
- package/packages/omo-codex/plugin/test/aggregate.test.mjs +78 -2
- package/packages/omo-codex/plugin/test/auto-update-release-notes.test.mjs +19 -33
- package/packages/omo-codex/plugin/test/auto-update.test.mjs +2 -2
- package/packages/omo-codex/plugin/test/component-bin-names.test.mjs +2 -2
- package/packages/omo-codex/plugin/test/component-bundled-cli.test.mjs +1 -1
- package/packages/omo-codex/plugin/test/component-hook-contract-cases.mjs +2 -2
- package/packages/omo-codex/plugin/test/hook-status-message.test.mjs +4 -4
- package/packages/omo-codex/plugin/test/lcx-contribute-bug-fix-template.test.mjs +21 -27
- package/packages/omo-codex/plugin/test/migrate-codex-config.test.mjs +8 -8
- package/packages/omo-codex/plugin/test/scaffold-plan.test.mjs +0 -36
- package/packages/omo-codex/plugin/test/sync-skills-codex-compatibility.test.mjs +101 -0
- package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +12 -12
- package/packages/omo-codex/plugin/test/sync-skills.test.mjs +1 -119
- package/packages/omo-codex/plugin/test/teammode-archive-ambiguity.test.mjs +0 -40
- package/packages/omo-codex/plugin/test/teammode-communication.test.mjs +6 -62
- package/packages/omo-codex/plugin/test/teammode-thread-links.test.mjs +3 -36
- package/packages/omo-codex/plugin/test/teammode-transport.test.mjs +0 -44
- package/packages/omo-codex/plugin/test/teammode-worktree.test.mjs +2 -6
- package/packages/omo-codex/plugin/test/ultrawork-skill-pointer.test.mjs +0 -3
- package/packages/omo-codex/plugin/test/ulw-plan-review-state-contract.test.mjs +0 -3
- package/packages/omo-codex/scripts/AGENTS.md +36 -0
- package/packages/omo-codex/scripts/install-config-reasoning.test.mjs +2 -2
- package/packages/omo-codex/scripts/install-dist/install-local.mjs +2637 -549
- package/packages/omo-codex/scripts/install-lazycodex-version-stamp.test.mjs +7 -2
- package/packages/shared-skills/skills/ast-grep/AGENTS.md +51 -0
- package/packages/shared-skills/skills/coding-agent-sessions/AGENTS.md +62 -0
- package/packages/shared-skills/skills/coding-agent-sessions/SKILL.md +3 -2
- package/packages/shared-skills/skills/coding-agent-sessions/references/all-platforms.md +1 -1
- package/packages/shared-skills/skills/coding-agent-sessions/references/senpi.md +4 -4
- package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +1 -1
- package/packages/shared-skills/skills/data-scientist/SKILL.md +99 -239
- package/packages/shared-skills/skills/data-scientist/references/execution-surfaces.md +91 -0
- package/packages/shared-skills/skills/data-scientist/references/placement.md +74 -0
- package/packages/shared-skills/skills/data-scientist/references/polars-lane.md +95 -0
- package/packages/shared-skills/skills/data-scientist/references/uv-setup.md +1 -1
- package/packages/shared-skills/skills/data-scientist/references/visualization.md +64 -0
- package/packages/shared-skills/skills/data-scientist/scripts/ensure-js-deps.sh +28 -0
- package/packages/shared-skills/skills/data-scientist/scripts/ensure-py-deps.sh +37 -0
- package/packages/shared-skills/skills/debugging/SKILL.md +2 -0
- package/packages/shared-skills/skills/debugging/references/methodology/00-setup.md +12 -0
- package/packages/shared-skills/skills/debugging/references/methodology/02-investigate.md +21 -0
- package/packages/shared-skills/skills/debugging/references/runtimes/go.md +15 -1
- package/packages/shared-skills/skills/debugging/references/runtimes/native-binary.md +38 -0
- package/packages/shared-skills/skills/debugging/references/runtimes/node.md +25 -0
- package/packages/shared-skills/skills/debugging/references/runtimes/python.md +13 -0
- package/packages/shared-skills/skills/debugging/references/runtimes/rust.md +41 -0
- package/packages/shared-skills/skills/debugging/references/scripts/dap.mjs +267 -0
- package/packages/shared-skills/skills/debugging/references/scripts/dap.test.ts +86 -0
- package/packages/shared-skills/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
- package/packages/shared-skills/skills/debugging/references/tools/dap.md +103 -0
- package/packages/shared-skills/skills/debugging/references/tools/frida.md +193 -0
- package/packages/shared-skills/skills/frontend/SKILL.md +11 -7
- package/packages/shared-skills/skills/frontend/references/design/_INDEX.md +1 -0
- package/packages/shared-skills/skills/frontend/references/design/print-paged-media.md +76 -0
- package/packages/shared-skills/skills/frontend/references/design/stylegallery.md +80 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/README.md +1 -1
- package/packages/shared-skills/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
- package/packages/shared-skills/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
- package/packages/shared-skills/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
- package/packages/shared-skills/skills/frontend/references/designpowers/orchestration.md +1 -1
- package/packages/shared-skills/skills/frontend/references/designpowers/routing.md +5 -5
- package/packages/shared-skills/skills/review-work/SKILL.md +3 -3
- package/packages/shared-skills/skills/ultimate-browsing/ATTRIBUTION.md +37 -10
- package/packages/shared-skills/skills/ultimate-browsing/SKILL.md +2 -0
- package/packages/shared-skills/skills/ultimate-browsing/engine/AGENTS.md +179 -0
- package/packages/shared-skills/skills/ultimate-browsing/engine/templates/package.json +1 -1
- package/packages/shared-skills/skills/ultimate-browsing/references/chrome-stealth.md +13 -11
- package/packages/shared-skills/skills/{start-work → ulw-execute}/SKILL.md +9 -8
- package/packages/shared-skills/skills/ulw-plan/SKILL.md +6 -6
- package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +31 -7
- package/packages/shared-skills/skills/ulw-plan/references/intent-clear.md +2 -1
- package/packages/shared-skills/skills/ulw-plan/references/intent-unclear.md +5 -5
- package/packages/shared-skills/skills/ulw-research/SKILL.md +4 -2
- package/packages/shared-skills/skills/visual-qa/AGENTS.md +58 -0
- package/packages/shared-skills/skills/visual-qa/SKILL.md +3 -2
- package/script/qa/web-terminal-visual-qa.mjs +2 -0
- package/script/qa/xterm-live-terminal.mjs +18 -2
- package/dist/config/schema/start-work.d.ts +0 -5
- package/dist/features/builtin-commands/templates/start-work.d.ts +0 -1
- package/dist/hooks/ralph-loop/completion-promise-detector-test-input.d.ts +0 -11
- package/dist/hooks/ralph-loop/loop-session-recovery.d.ts +0 -7
- package/dist/hooks/start-work/start-work-hook.d.ts +0 -23
- package/dist/plugin/chat-message/start-work-message.d.ts +0 -5
- package/dist/skills/data-scientist/references/common-scenarios.md +0 -176
- package/dist/skills/data-scientist/references/execution-templates.md +0 -197
- package/dist/skills/data-scientist/references/integration-patterns.md +0 -153
- package/dist/skills/data-scientist/references/performance-benchmarks.md +0 -37
- package/dist/tools/call-omo-agent/background-agent-executor.d.ts +0 -5
- package/dist/tools/call-omo-agent/message-storage-directory.d.ts +0 -1
- package/dist/tools/delegate-task/model-string-parser.d.ts +0 -1
- package/packages/lsp-tools-mcp/dist/lsp/cleanup-errors.d.ts +0 -1
- package/packages/lsp-tools-mcp/dist/lsp/constants.d.ts +0 -1
- package/packages/lsp-tools-mcp/dist/lsp/language-mappings.d.ts +0 -1
- package/packages/lsp-tools-mcp/dist/lsp/process-signal-cleanup.d.ts +0 -1
- package/packages/lsp-tools-mcp/dist/missing-dependency-result.d.ts +0 -1
- package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +0 -28
- package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +0 -17
- package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +0 -17
- package/packages/omo-codex/plugin/skills/data-scientist/references/common-scenarios.md +0 -176
- package/packages/omo-codex/plugin/skills/data-scientist/references/execution-templates.md +0 -197
- package/packages/omo-codex/plugin/skills/data-scientist/references/integration-patterns.md +0 -153
- package/packages/omo-codex/plugin/skills/data-scientist/references/performance-benchmarks.md +0 -37
- package/packages/omo-codex/plugin/skills/start-work/agents/openai.yaml +0 -2
- package/packages/omo-codex/plugin/test/aggregate-skills.test.mjs +0 -92
- package/packages/omo-codex/plugin/test/sync-skills-orchestration.test.mjs +0 -314
- package/packages/omo-codex/plugin/test/ulw-plan-scope-contract.test.mjs +0 -24
- package/packages/shared-skills/skills/data-scientist/references/common-scenarios.md +0 -176
- package/packages/shared-skills/skills/data-scientist/references/execution-templates.md +0 -197
- package/packages/shared-skills/skills/data-scientist/references/integration-patterns.md +0 -153
- package/packages/shared-skills/skills/data-scientist/references/performance-benchmarks.md +0 -37
- /package/dist/hooks/{start-work → ulw-execute}/context-info-formatters.d.ts +0 -0
- /package/dist/hooks/{start-work → ulw-execute}/explicit-plan-context.d.ts +0 -0
- /package/dist/hooks/{start-work → ulw-execute}/notepad-scaffold.d.ts +0 -0
- /package/dist/hooks/{start-work → ulw-execute}/parse-user-request.d.ts +0 -0
- /package/dist/hooks/{start-work → ulw-execute}/plan-discovery-context.d.ts +0 -0
- /package/dist/hooks/{start-work → ulw-execute}/plan-selection.d.ts +0 -0
- /package/dist/hooks/{start-work → ulw-execute}/session-plan-affinity.d.ts +0 -0
- /package/dist/hooks/{start-work → ulw-execute}/work-initializer.d.ts +0 -0
- /package/dist/hooks/{start-work → ulw-execute}/worktree-block.d.ts +0 -0
- /package/dist/hooks/{start-work → ulw-execute}/worktree-detector.d.ts +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/.gitattributes +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/CHANGELOG.md +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/LICENSE +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/plan-checklist.ts +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/types.ts +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-completed.json +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-mixed-platforms.json +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-single-codex-work.json +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-all-done.md +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-scaffold.md +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-with-nested-checkboxes.md +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-with-unchecked.md +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/tsconfig.build.json +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/tsconfig.json +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/vitest.config.ts +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// ../lsp-core/src/lsp/client-wrapper.ts
|
|
2
|
-
import { existsSync as
|
|
3
|
-
import { dirname as
|
|
2
|
+
import { existsSync as existsSync10, realpathSync as realpathSync5, statSync as statSync3 } from "node:fs";
|
|
3
|
+
import { basename as basename3, dirname as dirname8, join as join5, resolve as resolve8 } from "node:path";
|
|
4
4
|
|
|
5
5
|
// ../lsp-core/src/request-context.ts
|
|
6
6
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
@@ -9,18 +9,17 @@ import { homedir } from "node:os";
|
|
|
9
9
|
import { basename, delimiter, dirname, isAbsolute, join, relative, resolve } from "node:path";
|
|
10
10
|
|
|
11
11
|
class LspRequestContextParseError extends Error {
|
|
12
|
-
code;
|
|
13
|
-
name = "LspRequestContextParseError";
|
|
14
12
|
constructor(code, message) {
|
|
15
13
|
super(message);
|
|
16
14
|
this.code = code;
|
|
15
|
+
this.name = "LspRequestContextParseError";
|
|
17
16
|
}
|
|
18
17
|
}
|
|
19
18
|
|
|
20
19
|
class LspRequestContextUnavailableError extends Error {
|
|
21
|
-
name = "LspRequestContextUnavailableError";
|
|
22
20
|
constructor() {
|
|
23
21
|
super("LSP request context is required. Standalone MCP startup must install one with runWithRequestContext(createStandaloneMcpRequestContext()).");
|
|
22
|
+
this.name = "LspRequestContextUnavailableError";
|
|
24
23
|
}
|
|
25
24
|
}
|
|
26
25
|
var storage = new AsyncLocalStorage;
|
|
@@ -50,7 +49,7 @@ function contextEnv(key) {
|
|
|
50
49
|
}
|
|
51
50
|
function createStandaloneMcpRequestContext(input = {}) {
|
|
52
51
|
const env = input.env ?? process.env;
|
|
53
|
-
const cwd = canonicalCwd(input.cwd ?? process.cwd());
|
|
52
|
+
const cwd = canonicalCwd(input.cwd ?? env["LSP_TOOLS_MCP_CWD"] ?? process.cwd());
|
|
54
53
|
const home = input.homeDir ?? homedir();
|
|
55
54
|
const projectConfigPaths = translateProjectConfigEnv(env["LSP_TOOLS_MCP_PROJECT_CONFIG"], cwd);
|
|
56
55
|
const userConfigPath = translateHomeConfigEnv(env["LSP_TOOLS_MCP_USER_CONFIG"], home, ".codex/lsp-client.json");
|
|
@@ -193,22 +192,15 @@ function effectiveExtension(filePath) {
|
|
|
193
192
|
|
|
194
193
|
// ../lsp-core/src/lsp/errors.ts
|
|
195
194
|
class LspConnectionClosedError extends Error {
|
|
196
|
-
serverId;
|
|
197
|
-
root;
|
|
198
|
-
name = "LspConnectionClosedError";
|
|
199
195
|
constructor(serverId, root, message) {
|
|
200
196
|
super(message ?? `LSP connection closed for ${serverId} at ${root}`);
|
|
201
197
|
this.serverId = serverId;
|
|
202
198
|
this.root = root;
|
|
199
|
+
this.name = "LspConnectionClosedError";
|
|
203
200
|
}
|
|
204
201
|
}
|
|
205
202
|
|
|
206
203
|
class LspProcessExitedError extends Error {
|
|
207
|
-
serverId;
|
|
208
|
-
root;
|
|
209
|
-
exitCode;
|
|
210
|
-
stderrTail;
|
|
211
|
-
name = "LspProcessExitedError";
|
|
212
204
|
constructor(serverId, root, exitCode, stderrTail) {
|
|
213
205
|
const stderrSuffix = stderrTail ? `
|
|
214
206
|
stderr tail: ${stderrTail}` : "";
|
|
@@ -217,46 +209,59 @@ stderr tail: ${stderrTail}` : "";
|
|
|
217
209
|
this.root = root;
|
|
218
210
|
this.exitCode = exitCode;
|
|
219
211
|
this.stderrTail = stderrTail;
|
|
212
|
+
this.name = "LspProcessExitedError";
|
|
220
213
|
}
|
|
221
214
|
}
|
|
222
215
|
|
|
223
216
|
class LspRequestTimeoutError extends Error {
|
|
224
|
-
method;
|
|
225
|
-
stderrTail;
|
|
226
|
-
name = "LspRequestTimeoutError";
|
|
227
217
|
constructor(method, stderrTail) {
|
|
228
218
|
const stderrSuffix = stderrTail ? `
|
|
229
219
|
recent stderr: ${stderrTail}` : "";
|
|
230
220
|
super(`LSP request timeout (method: ${method})${stderrSuffix}`);
|
|
231
221
|
this.method = method;
|
|
232
222
|
this.stderrTail = stderrTail;
|
|
223
|
+
this.name = "LspRequestTimeoutError";
|
|
233
224
|
}
|
|
234
225
|
}
|
|
235
226
|
|
|
236
227
|
class LspInvalidPathError extends Error {
|
|
237
|
-
|
|
228
|
+
constructor() {
|
|
229
|
+
super(...arguments);
|
|
230
|
+
this.name = "LspInvalidPathError";
|
|
231
|
+
}
|
|
238
232
|
}
|
|
239
233
|
|
|
240
234
|
class LspServerLookupError extends Error {
|
|
241
|
-
lookup;
|
|
242
|
-
name = "LspServerLookupError";
|
|
243
235
|
constructor(message, lookup) {
|
|
244
236
|
super(message);
|
|
245
237
|
this.lookup = lookup;
|
|
238
|
+
this.name = "LspServerLookupError";
|
|
246
239
|
}
|
|
247
240
|
}
|
|
248
241
|
|
|
249
242
|
class LspServerInitializingError extends Error {
|
|
250
|
-
originalError;
|
|
251
|
-
name = "LspServerInitializingError";
|
|
252
243
|
constructor(originalError) {
|
|
253
244
|
super(`LSP server is still initializing. Please retry in a few seconds. Original error: ${originalError.message}`);
|
|
254
245
|
this.originalError = originalError;
|
|
246
|
+
this.name = "LspServerInitializingError";
|
|
255
247
|
}
|
|
256
248
|
}
|
|
257
249
|
|
|
258
250
|
class LspProcessSpawnError extends Error {
|
|
259
|
-
|
|
251
|
+
constructor() {
|
|
252
|
+
super(...arguments);
|
|
253
|
+
this.name = "LspProcessSpawnError";
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
class LspClientRespawnBudgetExceededError extends Error {
|
|
258
|
+
constructor(serverId, root, retryLimit) {
|
|
259
|
+
super(`LSP server ${serverId} at ${root} failed to stay alive; respawn budget exhausted ` + `(${retryLimit} consecutive dead generations). Retrying after the cooldown may succeed.`);
|
|
260
|
+
this.serverId = serverId;
|
|
261
|
+
this.root = root;
|
|
262
|
+
this.retryLimit = retryLimit;
|
|
263
|
+
this.name = "LspClientRespawnBudgetExceededError";
|
|
264
|
+
}
|
|
260
265
|
}
|
|
261
266
|
function isLspDeadConnectionError(err) {
|
|
262
267
|
return err instanceof LspConnectionClosedError || err instanceof LspProcessExitedError;
|
|
@@ -287,9 +292,12 @@ var DEFAULT_MAX_DIRECTORY_FILES = 50;
|
|
|
287
292
|
var REQUEST_TIMEOUT_MS = 15000;
|
|
288
293
|
var INIT_TIMEOUT_MS = 60000;
|
|
289
294
|
var IDLE_TIMEOUT_MS = 5 * 60000;
|
|
295
|
+
var MAX_RESIDENT_CLIENTS = 6;
|
|
290
296
|
var REAPER_INTERVAL_MS = 60000;
|
|
291
297
|
var STOP_HARD_KILL_TIMEOUT_MS = 5000;
|
|
292
298
|
var STOP_SIGKILL_GRACE_MS = 1000;
|
|
299
|
+
var CLIENT_RESPAWN_RETRY_LIMIT = 2;
|
|
300
|
+
var CLIENT_RESPAWN_COOLDOWN_MS = 60000;
|
|
293
301
|
|
|
294
302
|
// ../lsp-core/src/lsp/json-rpc-connection.ts
|
|
295
303
|
var HEADER_SEPARATOR = `\r
|
|
@@ -301,20 +309,31 @@ var METHOD_NOT_FOUND = -32601;
|
|
|
301
309
|
var INTERNAL_ERROR = -32603;
|
|
302
310
|
|
|
303
311
|
class JsonRpcConnection {
|
|
304
|
-
reader;
|
|
305
|
-
writer;
|
|
306
|
-
pendingRequests = new Map;
|
|
307
|
-
notificationHandlers = new Map;
|
|
308
|
-
requestHandlers = new Map;
|
|
309
|
-
closeHandlers = [];
|
|
310
|
-
errorHandlers = [];
|
|
311
|
-
inputBuffer = Buffer.alloc(0);
|
|
312
|
-
nextRequestId = 1;
|
|
313
|
-
listening = false;
|
|
314
|
-
disposed = false;
|
|
315
312
|
constructor(reader, writer) {
|
|
316
313
|
this.reader = reader;
|
|
317
314
|
this.writer = writer;
|
|
315
|
+
this.pendingRequests = new Map;
|
|
316
|
+
this.notificationHandlers = new Map;
|
|
317
|
+
this.requestHandlers = new Map;
|
|
318
|
+
this.closeHandlers = [];
|
|
319
|
+
this.errorHandlers = [];
|
|
320
|
+
this.inputBuffer = Buffer.alloc(0);
|
|
321
|
+
this.nextRequestId = 1;
|
|
322
|
+
this.listening = false;
|
|
323
|
+
this.disposed = false;
|
|
324
|
+
this.handleData = (chunk) => {
|
|
325
|
+
const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
|
|
326
|
+
this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
|
|
327
|
+
this.drainInputBuffer();
|
|
328
|
+
};
|
|
329
|
+
this.handleClose = () => {
|
|
330
|
+
for (const handler of this.closeHandlers) {
|
|
331
|
+
handler();
|
|
332
|
+
}
|
|
333
|
+
};
|
|
334
|
+
this.handleStreamError = (error) => {
|
|
335
|
+
this.emitError(error);
|
|
336
|
+
};
|
|
318
337
|
}
|
|
319
338
|
listen() {
|
|
320
339
|
if (this.listening)
|
|
@@ -435,19 +454,6 @@ class JsonRpcConnection {
|
|
|
435
454
|
this.notificationHandlers.clear();
|
|
436
455
|
this.requestHandlers.clear();
|
|
437
456
|
}
|
|
438
|
-
handleData = (chunk) => {
|
|
439
|
-
const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
|
|
440
|
-
this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
|
|
441
|
-
this.drainInputBuffer();
|
|
442
|
-
};
|
|
443
|
-
handleClose = () => {
|
|
444
|
-
for (const handler of this.closeHandlers) {
|
|
445
|
-
handler();
|
|
446
|
-
}
|
|
447
|
-
};
|
|
448
|
-
handleStreamError = (error) => {
|
|
449
|
-
this.emitError(error);
|
|
450
|
-
};
|
|
451
457
|
drainInputBuffer() {
|
|
452
458
|
while (true) {
|
|
453
459
|
const headerEnd = this.inputBuffer.indexOf(HEADER_SEPARATOR);
|
|
@@ -795,31 +801,26 @@ function isPosition(value) {
|
|
|
795
801
|
|
|
796
802
|
// ../lsp-core/src/lsp/transport.ts
|
|
797
803
|
class LspClientNotStartedError extends Error {
|
|
798
|
-
serverId;
|
|
799
|
-
root;
|
|
800
|
-
name = "LspClientNotStartedError";
|
|
801
804
|
constructor(serverId, root) {
|
|
802
805
|
super("LSP client not started");
|
|
803
806
|
this.serverId = serverId;
|
|
804
807
|
this.root = root;
|
|
808
|
+
this.name = "LspClientNotStartedError";
|
|
805
809
|
}
|
|
806
810
|
}
|
|
807
811
|
|
|
808
812
|
class LspClientTransport {
|
|
809
|
-
root;
|
|
810
|
-
server;
|
|
811
|
-
proc = null;
|
|
812
|
-
connection = null;
|
|
813
|
-
stderrBuffer = [];
|
|
814
|
-
processExited = false;
|
|
815
|
-
diagnosticsStore = new Map;
|
|
816
|
-
requestTimeoutMs;
|
|
817
|
-
initializeTimeoutMs;
|
|
818
|
-
workspaceApplyEditHandler = null;
|
|
819
|
-
diagnosticPullSupported = false;
|
|
820
813
|
constructor(root, server, timeouts = {}) {
|
|
821
814
|
this.root = root;
|
|
822
815
|
this.server = server;
|
|
816
|
+
this.proc = null;
|
|
817
|
+
this.connection = null;
|
|
818
|
+
this.stderrBuffer = [];
|
|
819
|
+
this.processExited = false;
|
|
820
|
+
this.diagnosticsStore = new Map;
|
|
821
|
+
this.workspaceApplyEditHandler = null;
|
|
822
|
+
this.diagnosticPullSupported = false;
|
|
823
|
+
this.documentFormattingSupported = false;
|
|
823
824
|
this.requestTimeoutMs = timeouts.requestTimeoutMs ?? REQUEST_TIMEOUT_MS;
|
|
824
825
|
this.initializeTimeoutMs = timeouts.initializeTimeoutMs ?? INIT_TIMEOUT_MS;
|
|
825
826
|
}
|
|
@@ -841,6 +842,12 @@ class LspClientTransport {
|
|
|
841
842
|
isDiagnosticPullSupported() {
|
|
842
843
|
return this.diagnosticPullSupported;
|
|
843
844
|
}
|
|
845
|
+
setDocumentFormattingSupported(supported) {
|
|
846
|
+
this.documentFormattingSupported = supported;
|
|
847
|
+
}
|
|
848
|
+
isDocumentFormattingSupported() {
|
|
849
|
+
return this.documentFormattingSupported;
|
|
850
|
+
}
|
|
844
851
|
handlePublishDiagnostics(params) {
|
|
845
852
|
this.diagnosticsStore.set(params.uri, [...params.diagnostics]);
|
|
846
853
|
}
|
|
@@ -1054,6 +1061,14 @@ function supportsDiagnosticPull(capabilities) {
|
|
|
1054
1061
|
return false;
|
|
1055
1062
|
return Object.hasOwn(capabilities, "diagnosticProvider");
|
|
1056
1063
|
}
|
|
1064
|
+
function supportsDocumentFormatting(capabilities) {
|
|
1065
|
+
if (capabilities === undefined)
|
|
1066
|
+
return false;
|
|
1067
|
+
const provider = capabilities.documentFormattingProvider;
|
|
1068
|
+
if (provider === undefined || provider === null || provider === false)
|
|
1069
|
+
return false;
|
|
1070
|
+
return provider === true || typeof provider === "object";
|
|
1071
|
+
}
|
|
1057
1072
|
|
|
1058
1073
|
class LspClientConnection extends LspClientTransport {
|
|
1059
1074
|
async initialize() {
|
|
@@ -1070,6 +1085,7 @@ class LspClientConnection extends LspClientTransport {
|
|
|
1070
1085
|
references: {},
|
|
1071
1086
|
documentSymbol: { hierarchicalDocumentSymbolSupport: true },
|
|
1072
1087
|
publishDiagnostics: {},
|
|
1088
|
+
formatting: { dynamicRegistration: false },
|
|
1073
1089
|
rename: {
|
|
1074
1090
|
prepareSupport: true,
|
|
1075
1091
|
prepareSupportDefaultBehavior: 1
|
|
@@ -1111,6 +1127,7 @@ class LspClientConnection extends LspClientTransport {
|
|
|
1111
1127
|
initializationOptions: this.server.initialization
|
|
1112
1128
|
}, { timeoutMs: this.initializeTimeoutMs });
|
|
1113
1129
|
this.setDiagnosticPullSupported(supportsDiagnosticPull(result?.capabilities));
|
|
1130
|
+
this.setDocumentFormattingSupported(supportsDocumentFormatting(result?.capabilities));
|
|
1114
1131
|
await this.sendNotification("initialized", {});
|
|
1115
1132
|
await this.sendNotification("workspace/didChangeConfiguration", {
|
|
1116
1133
|
settings: { json: { validate: { enable: true } } }
|
|
@@ -1316,16 +1333,12 @@ function movedPath(candidate, oldPath, newPath) {
|
|
|
1316
1333
|
}
|
|
1317
1334
|
|
|
1318
1335
|
class WorkspaceDocumentState {
|
|
1319
|
-
sendNotification;
|
|
1320
|
-
clearDiagnostics;
|
|
1321
|
-
openDocuments = new Map;
|
|
1322
|
-
openByUri = new Map;
|
|
1323
|
-
openPromises = new Map;
|
|
1324
|
-
now;
|
|
1325
|
-
versionlessPublishQuiescenceMs;
|
|
1326
1336
|
constructor(sendNotification, clearDiagnostics, options = {}) {
|
|
1327
1337
|
this.sendNotification = sendNotification;
|
|
1328
1338
|
this.clearDiagnostics = clearDiagnostics;
|
|
1339
|
+
this.openDocuments = new Map;
|
|
1340
|
+
this.openByUri = new Map;
|
|
1341
|
+
this.openPromises = new Map;
|
|
1329
1342
|
this.now = options.now ?? (() => Date.now());
|
|
1330
1343
|
this.versionlessPublishQuiescenceMs = options.versionlessPublishQuiescenceMs ?? DEFAULT_VERSIONLESS_PUBLISH_QUIESCENCE_MS;
|
|
1331
1344
|
}
|
|
@@ -1589,13 +1602,11 @@ import { dirname as dirname2, isAbsolute as isAbsolute2, relative as relative3,
|
|
|
1589
1602
|
import { fileURLToPath } from "node:url";
|
|
1590
1603
|
|
|
1591
1604
|
class WorkspaceEditPathError extends Error {
|
|
1592
|
-
path;
|
|
1593
|
-
detail;
|
|
1594
|
-
name = "WorkspaceEditPathError";
|
|
1595
1605
|
constructor(path, detail) {
|
|
1596
1606
|
super(`${detail}: ${path}`);
|
|
1597
1607
|
this.path = path;
|
|
1598
1608
|
this.detail = detail;
|
|
1609
|
+
this.name = "WorkspaceEditPathError";
|
|
1599
1610
|
}
|
|
1600
1611
|
}
|
|
1601
1612
|
function isPathInsideWorkspace(filePath, workspaceRoot) {
|
|
@@ -1887,13 +1898,11 @@ function canonicalFingerprint(operations) {
|
|
|
1887
1898
|
|
|
1888
1899
|
// ../lsp-core/src/lsp/workspace-edit-types.ts
|
|
1889
1900
|
class WorkspaceEditValidationError extends Error {
|
|
1890
|
-
changeIndex;
|
|
1891
|
-
detail;
|
|
1892
|
-
name = "WorkspaceEditValidationError";
|
|
1893
1901
|
constructor(changeIndex, detail) {
|
|
1894
1902
|
super(`change ${changeIndex}: ${detail}`);
|
|
1895
1903
|
this.changeIndex = changeIndex;
|
|
1896
1904
|
this.detail = detail;
|
|
1905
|
+
this.name = "WorkspaceEditValidationError";
|
|
1897
1906
|
}
|
|
1898
1907
|
}
|
|
1899
1908
|
|
|
@@ -2391,10 +2400,9 @@ function simulateDelete(operation, virtual) {
|
|
|
2391
2400
|
import { existsSync as existsSync5, lstatSync as lstatSync3, readdirSync as readdirSync2 } from "node:fs";
|
|
2392
2401
|
import { dirname as dirname4, resolve as resolve5 } from "node:path";
|
|
2393
2402
|
class WorkspaceSnapshotBuilder {
|
|
2394
|
-
workspaceRoot;
|
|
2395
|
-
snapshots = new Map;
|
|
2396
2403
|
constructor(workspaceRoot) {
|
|
2397
2404
|
this.workspaceRoot = workspaceRoot;
|
|
2405
|
+
this.snapshots = new Map;
|
|
2398
2406
|
}
|
|
2399
2407
|
build(operations) {
|
|
2400
2408
|
this.add(this.workspaceRoot, false);
|
|
@@ -2438,8 +2446,10 @@ function snapshotOperations(operations, workspaceRoot) {
|
|
|
2438
2446
|
|
|
2439
2447
|
// ../lsp-core/src/lsp/workspace-edit-plan.ts
|
|
2440
2448
|
class PlanPathIndex {
|
|
2441
|
-
|
|
2442
|
-
|
|
2449
|
+
constructor() {
|
|
2450
|
+
this.firstChangeByPath = new Map;
|
|
2451
|
+
this.reportedPathByCanonical = new Map;
|
|
2452
|
+
}
|
|
2443
2453
|
build(operations) {
|
|
2444
2454
|
for (const operation of operations) {
|
|
2445
2455
|
switch (operation.kind) {
|
|
@@ -2528,14 +2538,11 @@ function isRecord4(value) {
|
|
|
2528
2538
|
}
|
|
2529
2539
|
|
|
2530
2540
|
class WorkspaceMutationController {
|
|
2531
|
-
workspaceRoot;
|
|
2532
|
-
documents;
|
|
2533
|
-
activeLease = null;
|
|
2534
|
-
nextLeaseId = 1;
|
|
2535
|
-
io;
|
|
2536
2541
|
constructor(workspaceRoot, documents) {
|
|
2537
2542
|
this.workspaceRoot = workspaceRoot;
|
|
2538
2543
|
this.documents = documents;
|
|
2544
|
+
this.activeLease = null;
|
|
2545
|
+
this.nextLeaseId = 1;
|
|
2539
2546
|
}
|
|
2540
2547
|
setIo(io) {
|
|
2541
2548
|
this.io = io;
|
|
@@ -2648,12 +2655,9 @@ var DIAGNOSTICS_FRESHNESS_TIMEOUT_MS = 3000;
|
|
|
2648
2655
|
var VERSIONLESS_PUBLISH_QUIESCENCE_MS = 250;
|
|
2649
2656
|
|
|
2650
2657
|
class LspClient extends LspClientConnection {
|
|
2651
|
-
diagnosticPullErrors = [];
|
|
2652
|
-
documents;
|
|
2653
|
-
workspaceMutations;
|
|
2654
|
-
diagnosticsFreshnessTimeoutMs;
|
|
2655
2658
|
constructor(root, server, options = {}) {
|
|
2656
2659
|
super(root, server, options);
|
|
2660
|
+
this.diagnosticPullErrors = [];
|
|
2657
2661
|
this.diagnosticsFreshnessTimeoutMs = options.diagnosticsFreshnessTimeoutMs ?? DIAGNOSTICS_FRESHNESS_TIMEOUT_MS;
|
|
2658
2662
|
this.documents = new WorkspaceDocumentState((method, params) => this.sendNotification(method, params), (uri) => this.diagnosticsStore.delete(uri), {
|
|
2659
2663
|
versionlessPublishQuiescenceMs: options.versionlessPublishQuiescenceMs ?? VERSIONLESS_PUBLISH_QUIESCENCE_MS
|
|
@@ -2708,6 +2712,18 @@ class LspClient extends LspClientConnection {
|
|
|
2708
2712
|
textDocument: { uri: pathToFileURL3(absPath).href }
|
|
2709
2713
|
}, options);
|
|
2710
2714
|
}
|
|
2715
|
+
async formatDocument(filePath, options, signal) {
|
|
2716
|
+
if (!this.isDocumentFormattingSupported())
|
|
2717
|
+
return null;
|
|
2718
|
+
const absPath = this.resolveWorkspacePath(filePath);
|
|
2719
|
+
await this.openFile(absPath);
|
|
2720
|
+
const requestOptions = signal === undefined ? {} : { signal };
|
|
2721
|
+
const edits = await this.sendRequest("textDocument/formatting", {
|
|
2722
|
+
textDocument: { uri: pathToFileURL3(absPath).href },
|
|
2723
|
+
options
|
|
2724
|
+
}, requestOptions);
|
|
2725
|
+
return edits ?? [];
|
|
2726
|
+
}
|
|
2711
2727
|
async workspaceSymbols(query, signal) {
|
|
2712
2728
|
const options = signal === undefined ? {} : { signal };
|
|
2713
2729
|
return this.sendRequest("workspace/symbol", { query }, options);
|
|
@@ -2953,18 +2969,16 @@ function awaitWithSignal(promise, signal) {
|
|
|
2953
2969
|
}
|
|
2954
2970
|
|
|
2955
2971
|
class LspManager {
|
|
2956
|
-
clients = new Map;
|
|
2957
|
-
reaperHandle = null;
|
|
2958
|
-
signalDisposer = null;
|
|
2959
|
-
disposed = false;
|
|
2960
|
-
idleTimeoutMs;
|
|
2961
|
-
initTimeoutMs;
|
|
2962
|
-
reaperIntervalMs;
|
|
2963
|
-
clientFactory;
|
|
2964
|
-
now;
|
|
2965
2972
|
constructor(options = {}) {
|
|
2973
|
+
this.clients = new Map;
|
|
2974
|
+
this.pendingStops = new Map;
|
|
2975
|
+
this.respawnBudgets = new Map;
|
|
2976
|
+
this.reaperHandle = null;
|
|
2977
|
+
this.signalDisposer = null;
|
|
2978
|
+
this.disposed = false;
|
|
2966
2979
|
this.idleTimeoutMs = options.idleTimeoutMs ?? IDLE_TIMEOUT_MS;
|
|
2967
2980
|
this.initTimeoutMs = options.initTimeoutMs ?? INIT_TIMEOUT_MS;
|
|
2981
|
+
this.maxResidentClients = options.maxResidentClients ?? MAX_RESIDENT_CLIENTS;
|
|
2968
2982
|
this.reaperIntervalMs = options.reaperIntervalMs ?? REAPER_INTERVAL_MS;
|
|
2969
2983
|
this.clientFactory = options.clientFactory ?? ((root, server) => new LspClient(root, server));
|
|
2970
2984
|
this.now = options.now ?? (() => Date.now());
|
|
@@ -2984,24 +2998,79 @@ class LspManager {
|
|
|
2984
2998
|
getKey(root, serverId) {
|
|
2985
2999
|
return `${root}::${serverId}`;
|
|
2986
3000
|
}
|
|
3001
|
+
tombstoneStop(key, client) {
|
|
3002
|
+
const stop = stopClientBestEffort(client);
|
|
3003
|
+
this.pendingStops.set(key, stop);
|
|
3004
|
+
stop.finally(() => {
|
|
3005
|
+
if (this.pendingStops.get(key) === stop) {
|
|
3006
|
+
this.pendingStops.delete(key);
|
|
3007
|
+
}
|
|
3008
|
+
});
|
|
3009
|
+
return stop;
|
|
3010
|
+
}
|
|
3011
|
+
recordDeadGeneration(key) {
|
|
3012
|
+
let budget = this.respawnBudgets.get(key);
|
|
3013
|
+
if (budget === undefined) {
|
|
3014
|
+
budget = { deadGenerations: 0, exhaustedAt: null };
|
|
3015
|
+
this.respawnBudgets.set(key, budget);
|
|
3016
|
+
}
|
|
3017
|
+
budget.deadGenerations += 1;
|
|
3018
|
+
}
|
|
3019
|
+
markHealthyGeneration(key) {
|
|
3020
|
+
this.respawnBudgets.delete(key);
|
|
3021
|
+
}
|
|
3022
|
+
ensureRespawnAllowed(key, root, serverId) {
|
|
3023
|
+
const budget = this.respawnBudgets.get(key);
|
|
3024
|
+
if (budget === undefined || budget.deadGenerations < CLIENT_RESPAWN_RETRY_LIMIT)
|
|
3025
|
+
return;
|
|
3026
|
+
if (budget.exhaustedAt === null) {
|
|
3027
|
+
budget.exhaustedAt = this.now();
|
|
3028
|
+
throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
|
|
3029
|
+
}
|
|
3030
|
+
if (this.now() - budget.exhaustedAt < CLIENT_RESPAWN_COOLDOWN_MS) {
|
|
3031
|
+
throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
|
|
3032
|
+
}
|
|
3033
|
+
budget.deadGenerations = 0;
|
|
3034
|
+
budget.exhaustedAt = null;
|
|
3035
|
+
}
|
|
2987
3036
|
reapStale() {
|
|
2988
3037
|
const t = this.now();
|
|
2989
3038
|
for (const [key, managed] of this.clients) {
|
|
2990
3039
|
if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
|
|
2991
|
-
stopClientBestEffort(managed.client);
|
|
2992
3040
|
this.clients.delete(key);
|
|
3041
|
+
this.tombstoneStop(key, managed.client);
|
|
2993
3042
|
continue;
|
|
2994
3043
|
}
|
|
2995
3044
|
if (!managed.isInitializing && managed.refCount === 0 && managed.pendingWaiters === 0 && t - managed.lastUsedAt > this.idleTimeoutMs) {
|
|
2996
|
-
stopClientBestEffort(managed.client);
|
|
2997
3045
|
this.clients.delete(key);
|
|
3046
|
+
this.tombstoneStop(key, managed.client);
|
|
3047
|
+
}
|
|
3048
|
+
}
|
|
3049
|
+
}
|
|
3050
|
+
evictForAdmission() {
|
|
3051
|
+
while (this.clients.size >= this.maxResidentClients) {
|
|
3052
|
+
const victim = this.leastRecentlyUsedIdleClient();
|
|
3053
|
+
if (!victim)
|
|
3054
|
+
return;
|
|
3055
|
+
this.clients.delete(victim.key);
|
|
3056
|
+
this.tombstoneStop(victim.key, victim.managed.client);
|
|
3057
|
+
}
|
|
3058
|
+
}
|
|
3059
|
+
leastRecentlyUsedIdleClient() {
|
|
3060
|
+
let candidate = null;
|
|
3061
|
+
for (const [key, managed] of this.clients) {
|
|
3062
|
+
if (managed.refCount > 0 || managed.pendingWaiters > 0 || managed.isInitializing)
|
|
3063
|
+
continue;
|
|
3064
|
+
if (candidate === null || managed.lastUsedAt < candidate.managed.lastUsedAt) {
|
|
3065
|
+
candidate = { key, managed };
|
|
2998
3066
|
}
|
|
2999
3067
|
}
|
|
3068
|
+
return candidate;
|
|
3000
3069
|
}
|
|
3001
3070
|
async tryDeleteIfOrphaned(key, managed) {
|
|
3002
3071
|
if (managed.refCount === 0 && managed.pendingWaiters === 0 && !managed.isInitializing && this.clients.get(key) === managed) {
|
|
3003
3072
|
this.clients.delete(key);
|
|
3004
|
-
await
|
|
3073
|
+
await this.tombstoneStop(key, managed.client);
|
|
3005
3074
|
}
|
|
3006
3075
|
}
|
|
3007
3076
|
async getClient(root, server, signal) {
|
|
@@ -3010,12 +3079,22 @@ class LspManager {
|
|
|
3010
3079
|
}
|
|
3011
3080
|
signal?.throwIfAborted();
|
|
3012
3081
|
const key = this.getKey(root, server.id);
|
|
3082
|
+
for (;; ) {
|
|
3083
|
+
const pendingStop = this.pendingStops.get(key);
|
|
3084
|
+
if (pendingStop === undefined)
|
|
3085
|
+
break;
|
|
3086
|
+
await awaitWithSignal(pendingStop, signal);
|
|
3087
|
+
signal?.throwIfAborted();
|
|
3088
|
+
}
|
|
3089
|
+
if (this.disposed) {
|
|
3090
|
+
throw new Error("LspManager has been disposed");
|
|
3091
|
+
}
|
|
3013
3092
|
let managed = this.clients.get(key);
|
|
3014
3093
|
if (managed) {
|
|
3015
3094
|
const t = this.now();
|
|
3016
3095
|
if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
|
|
3017
|
-
await stopClientBestEffort(managed.client);
|
|
3018
3096
|
this.clients.delete(key);
|
|
3097
|
+
await this.tombstoneStop(key, managed.client);
|
|
3019
3098
|
managed = undefined;
|
|
3020
3099
|
}
|
|
3021
3100
|
}
|
|
@@ -3036,14 +3115,20 @@ class LspManager {
|
|
|
3036
3115
|
signal.throwIfAborted();
|
|
3037
3116
|
}
|
|
3038
3117
|
if (!managed.client.isAlive()) {
|
|
3039
|
-
|
|
3040
|
-
this.clients.
|
|
3118
|
+
this.recordDeadGeneration(key);
|
|
3119
|
+
if (this.clients.get(key) === managed) {
|
|
3120
|
+
this.clients.delete(key);
|
|
3121
|
+
}
|
|
3122
|
+
await this.tombstoneStop(key, managed.client);
|
|
3041
3123
|
return this.getClient(root, server, signal);
|
|
3042
3124
|
}
|
|
3125
|
+
this.markHealthyGeneration(key);
|
|
3043
3126
|
managed.refCount++;
|
|
3044
3127
|
managed.lastUsedAt = this.now();
|
|
3045
3128
|
return managed.client;
|
|
3046
3129
|
}
|
|
3130
|
+
this.evictForAdmission();
|
|
3131
|
+
this.ensureRespawnAllowed(key, root, server.id);
|
|
3047
3132
|
const client = this.clientFactory(root, server);
|
|
3048
3133
|
const initStartedAt = this.now();
|
|
3049
3134
|
const initPromise = (async () => {
|
|
@@ -3067,7 +3152,7 @@ class LspManager {
|
|
|
3067
3152
|
if (this.clients.get(key) === newManaged) {
|
|
3068
3153
|
this.clients.delete(key);
|
|
3069
3154
|
}
|
|
3070
|
-
await
|
|
3155
|
+
await this.tombstoneStop(key, client);
|
|
3071
3156
|
throw err;
|
|
3072
3157
|
}
|
|
3073
3158
|
newManaged.pendingWaiters--;
|
|
@@ -3078,6 +3163,15 @@ class LspManager {
|
|
|
3078
3163
|
await this.tryDeleteIfOrphaned(key, newManaged);
|
|
3079
3164
|
signal.throwIfAborted();
|
|
3080
3165
|
}
|
|
3166
|
+
if (!client.isAlive()) {
|
|
3167
|
+
this.recordDeadGeneration(key);
|
|
3168
|
+
if (this.clients.get(key) === newManaged) {
|
|
3169
|
+
this.clients.delete(key);
|
|
3170
|
+
}
|
|
3171
|
+
await this.tombstoneStop(key, client);
|
|
3172
|
+
return this.getClient(root, server, signal);
|
|
3173
|
+
}
|
|
3174
|
+
this.markHealthyGeneration(key);
|
|
3081
3175
|
newManaged.refCount++;
|
|
3082
3176
|
newManaged.lastUsedAt = this.now();
|
|
3083
3177
|
return client;
|
|
@@ -3098,14 +3192,20 @@ class LspManager {
|
|
|
3098
3192
|
if (client && managed.client !== client)
|
|
3099
3193
|
return;
|
|
3100
3194
|
this.clients.delete(key);
|
|
3101
|
-
|
|
3195
|
+
this.tombstoneStop(key, managed.client);
|
|
3102
3196
|
}
|
|
3103
3197
|
warmupClient(root, server) {
|
|
3104
3198
|
if (this.disposed)
|
|
3105
3199
|
return;
|
|
3106
3200
|
const key = this.getKey(root, server.id);
|
|
3107
|
-
if (this.clients.has(key))
|
|
3201
|
+
if (this.clients.has(key) || this.pendingStops.has(key))
|
|
3108
3202
|
return;
|
|
3203
|
+
this.evictForAdmission();
|
|
3204
|
+
try {
|
|
3205
|
+
this.ensureRespawnAllowed(key, root, server.id);
|
|
3206
|
+
} catch {
|
|
3207
|
+
return;
|
|
3208
|
+
}
|
|
3109
3209
|
const client = this.clientFactory(root, server);
|
|
3110
3210
|
const initStartedAt = this.now();
|
|
3111
3211
|
const initPromise = (async () => {
|
|
@@ -3131,7 +3231,7 @@ class LspManager {
|
|
|
3131
3231
|
if (this.clients.get(key) === managed) {
|
|
3132
3232
|
this.clients.delete(key);
|
|
3133
3233
|
}
|
|
3134
|
-
|
|
3234
|
+
this.tombstoneStop(key, client);
|
|
3135
3235
|
});
|
|
3136
3236
|
}
|
|
3137
3237
|
isServerInitializing(root, serverId) {
|
|
@@ -3175,8 +3275,11 @@ class LspManager {
|
|
|
3175
3275
|
for (const managed of this.clients.values()) {
|
|
3176
3276
|
stopPromises.push(stopClientBestEffort(managed.client));
|
|
3177
3277
|
}
|
|
3278
|
+
const tombstonedStops = [...this.pendingStops.values()];
|
|
3178
3279
|
this.clients.clear();
|
|
3179
|
-
|
|
3280
|
+
this.respawnBudgets.clear();
|
|
3281
|
+
await Promise.allSettled([...stopPromises, ...tombstonedStops]);
|
|
3282
|
+
this.pendingStops.clear();
|
|
3180
3283
|
}
|
|
3181
3284
|
}
|
|
3182
3285
|
var _defaultInstance = null;
|
|
@@ -3194,57 +3297,52 @@ async function disposeDefaultLspManager() {
|
|
|
3194
3297
|
}
|
|
3195
3298
|
}
|
|
3196
3299
|
|
|
3197
|
-
// ../lsp-core/src/lsp/
|
|
3198
|
-
import { existsSync as existsSync6,
|
|
3199
|
-
import { dirname as dirname5 } from "node:path";
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3300
|
+
// ../lsp-core/src/lsp/outside-context-workspace.ts
|
|
3301
|
+
import { existsSync as existsSync6, realpathSync as realpathSync4 } from "node:fs";
|
|
3302
|
+
import { dirname as dirname5, join as join3 } from "node:path";
|
|
3303
|
+
|
|
3304
|
+
// ../lsp-core/src/lsp/workspace-markers.ts
|
|
3305
|
+
var GIT_WORKSPACE_MARKER = ".git";
|
|
3306
|
+
var PROJECT_WORKSPACE_MARKERS = [
|
|
3307
|
+
"package.json",
|
|
3308
|
+
"pyproject.toml",
|
|
3309
|
+
"Cargo.toml",
|
|
3310
|
+
"go.mod",
|
|
3311
|
+
"pom.xml",
|
|
3312
|
+
"build.gradle"
|
|
3313
|
+
];
|
|
3314
|
+
var WORKSPACE_MARKERS = [GIT_WORKSPACE_MARKER, ...PROJECT_WORKSPACE_MARKERS];
|
|
3315
|
+
|
|
3316
|
+
// ../lsp-core/src/lsp/outside-context-workspace.ts
|
|
3317
|
+
function findWorkspaceRootOutsideContext(directory) {
|
|
3318
|
+
const marked = nearestMarkedAncestor(directory);
|
|
3319
|
+
if (marked !== undefined)
|
|
3320
|
+
return marked;
|
|
3321
|
+
return realpathSync4(nearestExistingAncestor(directory));
|
|
3322
|
+
}
|
|
3323
|
+
function nearestMarkedAncestor(directory) {
|
|
3324
|
+
let current = directory;
|
|
3325
|
+
for (;; ) {
|
|
3326
|
+
if (existsSync6(current) && WORKSPACE_MARKERS.some((marker) => existsSync6(join3(current, marker)))) {
|
|
3327
|
+
return realpathSync4(current);
|
|
3328
|
+
}
|
|
3329
|
+
const parent = dirname5(current);
|
|
3330
|
+
if (parent === current)
|
|
3331
|
+
return;
|
|
3332
|
+
current = parent;
|
|
3212
3333
|
}
|
|
3213
3334
|
}
|
|
3214
|
-
function
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
}
|
|
3222
|
-
|
|
3223
|
-
return value === "declined" || value === "allowed";
|
|
3224
|
-
}
|
|
3225
|
-
function writeInstallDecisions(decisions) {
|
|
3226
|
-
const path = getInstallDecisionsPath();
|
|
3227
|
-
mkdirSync(dirname5(path), { recursive: true });
|
|
3228
|
-
const tmpPath = `${path}.tmp`;
|
|
3229
|
-
writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
|
|
3230
|
-
`, "utf8");
|
|
3231
|
-
renameSync2(tmpPath, path);
|
|
3232
|
-
}
|
|
3233
|
-
function isInstallDecisions(value) {
|
|
3234
|
-
return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
|
|
3235
|
-
}
|
|
3236
|
-
function isInstallDecisionRecord(value) {
|
|
3237
|
-
if (!isRecord5(value))
|
|
3238
|
-
return false;
|
|
3239
|
-
return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
|
|
3240
|
-
}
|
|
3241
|
-
function isRecord5(value) {
|
|
3242
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3335
|
+
function nearestExistingAncestor(directory) {
|
|
3336
|
+
let current = directory;
|
|
3337
|
+
while (!existsSync6(current)) {
|
|
3338
|
+
const parent = dirname5(current);
|
|
3339
|
+
if (parent === current)
|
|
3340
|
+
return current;
|
|
3341
|
+
current = parent;
|
|
3342
|
+
}
|
|
3343
|
+
return current;
|
|
3243
3344
|
}
|
|
3244
3345
|
|
|
3245
|
-
// ../lsp-core/src/lsp/config-loader.ts
|
|
3246
|
-
import { existsSync as existsSync7, readFileSync as readFileSync4 } from "node:fs";
|
|
3247
|
-
|
|
3248
3346
|
// ../lsp-core/src/lsp/server-definitions.ts
|
|
3249
3347
|
var LSP_INSTALL_HINTS = {
|
|
3250
3348
|
typescript: "npm install -g typescript-language-server typescript",
|
|
@@ -3290,6 +3388,26 @@ var LSP_INSTALL_HINTS = {
|
|
|
3290
3388
|
julials: `julia -e 'using Pkg; Pkg.add("LanguageServer")'`,
|
|
3291
3389
|
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"
|
|
3292
3390
|
};
|
|
3391
|
+
var LSP_LOCAL_INSTALL_HINTS = {
|
|
3392
|
+
typescript: "bun add -d typescript-language-server typescript",
|
|
3393
|
+
vue: "bun add -d @vue/language-server",
|
|
3394
|
+
eslint: "bun add -d vscode-langservers-extracted",
|
|
3395
|
+
oxlint: "bun add -d oxlint",
|
|
3396
|
+
biome: "bun add -d @biomejs/biome",
|
|
3397
|
+
svelte: "bun add -d svelte-language-server",
|
|
3398
|
+
astro: "bun add -d @astrojs/language-server",
|
|
3399
|
+
bash: "bun add -d bash-language-server",
|
|
3400
|
+
"bash-ls": "bun add -d bash-language-server",
|
|
3401
|
+
"yaml-ls": "bun add -d yaml-language-server",
|
|
3402
|
+
php: "bun add -d intelephense",
|
|
3403
|
+
prisma: "bun add -d prisma",
|
|
3404
|
+
dockerfile: "bun add -d dockerfile-language-server-nodejs",
|
|
3405
|
+
pyright: "uv add --dev pyright",
|
|
3406
|
+
basedpyright: "uv add --dev basedpyright",
|
|
3407
|
+
ruff: "uv add --dev ruff",
|
|
3408
|
+
ty: "uv add --dev ty",
|
|
3409
|
+
"ruby-lsp": "bundle add ruby-lsp --group development"
|
|
3410
|
+
};
|
|
3293
3411
|
var BUILTIN_SERVERS = {
|
|
3294
3412
|
typescript: {
|
|
3295
3413
|
command: ["typescript-language-server", "--stdio"],
|
|
@@ -3392,7 +3510,56 @@ var BUILTIN_SERVERS = {
|
|
|
3392
3510
|
}
|
|
3393
3511
|
};
|
|
3394
3512
|
|
|
3513
|
+
// ../lsp-core/src/lsp/server-install-state.ts
|
|
3514
|
+
import { existsSync as existsSync7, mkdirSync, readFileSync as readFileSync3, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
3515
|
+
import { dirname as dirname6 } from "node:path";
|
|
3516
|
+
function getInstallDecisionsPath() {
|
|
3517
|
+
return lspRequestContext().installDecisionsPath;
|
|
3518
|
+
}
|
|
3519
|
+
function loadInstallDecisions() {
|
|
3520
|
+
const path = getInstallDecisionsPath();
|
|
3521
|
+
if (!existsSync7(path))
|
|
3522
|
+
return {};
|
|
3523
|
+
try {
|
|
3524
|
+
const parsed = JSON.parse(readFileSync3(path, "utf8"));
|
|
3525
|
+
return isInstallDecisions(parsed) ? parsed : {};
|
|
3526
|
+
} catch {
|
|
3527
|
+
return {};
|
|
3528
|
+
}
|
|
3529
|
+
}
|
|
3530
|
+
function loadInstallDecision(serverId) {
|
|
3531
|
+
return loadInstallDecisions()[serverId];
|
|
3532
|
+
}
|
|
3533
|
+
function recordInstallDecision(serverId, decision, decidedAt = new Date().toISOString()) {
|
|
3534
|
+
const decisions = loadInstallDecisions();
|
|
3535
|
+
decisions[serverId] = { decision, decidedAt };
|
|
3536
|
+
writeInstallDecisions(decisions);
|
|
3537
|
+
}
|
|
3538
|
+
function isInstallDecision(value) {
|
|
3539
|
+
return value === "declined" || value === "allowed";
|
|
3540
|
+
}
|
|
3541
|
+
function writeInstallDecisions(decisions) {
|
|
3542
|
+
const path = getInstallDecisionsPath();
|
|
3543
|
+
mkdirSync(dirname6(path), { recursive: true });
|
|
3544
|
+
const tmpPath = `${path}.tmp`;
|
|
3545
|
+
writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
|
|
3546
|
+
`, "utf8");
|
|
3547
|
+
renameSync2(tmpPath, path);
|
|
3548
|
+
}
|
|
3549
|
+
function isInstallDecisions(value) {
|
|
3550
|
+
return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
|
|
3551
|
+
}
|
|
3552
|
+
function isInstallDecisionRecord(value) {
|
|
3553
|
+
if (!isRecord5(value))
|
|
3554
|
+
return false;
|
|
3555
|
+
return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
|
|
3556
|
+
}
|
|
3557
|
+
function isRecord5(value) {
|
|
3558
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3559
|
+
}
|
|
3560
|
+
|
|
3395
3561
|
// ../lsp-core/src/lsp/config-loader.ts
|
|
3562
|
+
import { existsSync as existsSync8, readFileSync as readFileSync4 } from "node:fs";
|
|
3396
3563
|
function getProjectConfigPaths() {
|
|
3397
3564
|
return lspRequestContext().projectConfigPaths;
|
|
3398
3565
|
}
|
|
@@ -3400,7 +3567,7 @@ function getUserConfigPath() {
|
|
|
3400
3567
|
return lspRequestContext().userConfigPath;
|
|
3401
3568
|
}
|
|
3402
3569
|
function loadJsonFile(path) {
|
|
3403
|
-
if (!
|
|
3570
|
+
if (!existsSync8(path))
|
|
3404
3571
|
return null;
|
|
3405
3572
|
try {
|
|
3406
3573
|
const parsed = JSON.parse(readFileSync4(path, "utf-8"));
|
|
@@ -3588,54 +3755,155 @@ function getDisabledServerIds() {
|
|
|
3588
3755
|
}
|
|
3589
3756
|
|
|
3590
3757
|
// ../lsp-core/src/lsp/server-installation.ts
|
|
3591
|
-
import { existsSync as
|
|
3592
|
-
import { delimiter as delimiter3, join as
|
|
3593
|
-
|
|
3594
|
-
|
|
3595
|
-
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
3758
|
+
import { existsSync as existsSync9 } from "node:fs";
|
|
3759
|
+
import { delimiter as delimiter3, dirname as dirname7, isAbsolute as isAbsolute3, join as join4, resolve as resolve7 } from "node:path";
|
|
3760
|
+
var LOCAL_BIN_RULES = [
|
|
3761
|
+
{
|
|
3762
|
+
markers: ["package.json", "bun.lock", "bun.lockb", "package-lock.json", "yarn.lock", "pnpm-lock.yaml"],
|
|
3763
|
+
binDirs: [join4("node_modules", ".bin")]
|
|
3764
|
+
},
|
|
3765
|
+
{
|
|
3766
|
+
markers: [
|
|
3767
|
+
"pyproject.toml",
|
|
3768
|
+
"ty.toml",
|
|
3769
|
+
"requirements.txt",
|
|
3770
|
+
"setup.py",
|
|
3771
|
+
"setup.cfg",
|
|
3772
|
+
"Pipfile",
|
|
3773
|
+
"pyrightconfig.json",
|
|
3774
|
+
"ruff.toml",
|
|
3775
|
+
".ruff.toml"
|
|
3776
|
+
],
|
|
3777
|
+
binDirs: [
|
|
3778
|
+
join4(".venv", "bin"),
|
|
3779
|
+
join4(".venv", "Scripts"),
|
|
3780
|
+
join4("venv", "bin"),
|
|
3781
|
+
join4("venv", "Scripts"),
|
|
3782
|
+
join4(".env", "bin"),
|
|
3783
|
+
join4(".env", "Scripts")
|
|
3784
|
+
]
|
|
3785
|
+
},
|
|
3786
|
+
{
|
|
3787
|
+
markers: ["Gemfile", "Gemfile.lock"],
|
|
3788
|
+
binDirs: [join4("vendor", "bundle", "bin"), "bin"]
|
|
3789
|
+
},
|
|
3790
|
+
{
|
|
3791
|
+
markers: ["go.mod", "go.sum", "go.work"],
|
|
3792
|
+
binDirs: ["bin"]
|
|
3602
3793
|
}
|
|
3603
|
-
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
|
|
3794
|
+
];
|
|
3795
|
+
var resolutionCache = new Map;
|
|
3796
|
+
var probeCount = 0;
|
|
3797
|
+
function probe(path) {
|
|
3798
|
+
probeCount += 1;
|
|
3799
|
+
return existsSync9(path);
|
|
3800
|
+
}
|
|
3801
|
+
function executableSuffixes(platform, pathExt) {
|
|
3802
|
+
if (platform !== "win32")
|
|
3803
|
+
return [""];
|
|
3804
|
+
const configured = pathExt ?? process.env["PATHEXT"] ?? "";
|
|
3805
|
+
const systemExts = configured.split(";").filter((entry) => entry.length > 0).map((entry) => entry.toLowerCase());
|
|
3806
|
+
return [...new Set(["", ...systemExts, ".exe", ".cmd", ".bat", ".ps1"])];
|
|
3807
|
+
}
|
|
3808
|
+
function probeWithSuffixes(directory, command, suffixes) {
|
|
3809
|
+
for (const suffix of suffixes) {
|
|
3810
|
+
const candidate = join4(directory, command + suffix);
|
|
3811
|
+
if (probe(candidate))
|
|
3812
|
+
return candidate;
|
|
3813
|
+
}
|
|
3814
|
+
return null;
|
|
3815
|
+
}
|
|
3816
|
+
function resolveLocal(command, workingDirectory, suffixes, stopAt) {
|
|
3817
|
+
const boundary = stopAt === undefined ? undefined : resolve7(stopAt);
|
|
3818
|
+
let current = resolve7(workingDirectory);
|
|
3819
|
+
while (true) {
|
|
3820
|
+
for (const rule of LOCAL_BIN_RULES) {
|
|
3821
|
+
if (!rule.markers.some((marker) => probe(join4(current, marker))))
|
|
3822
|
+
continue;
|
|
3823
|
+
for (const binDir of rule.binDirs) {
|
|
3824
|
+
const found = probeWithSuffixes(join4(current, binDir), command, suffixes);
|
|
3825
|
+
if (found !== null)
|
|
3826
|
+
return found;
|
|
3827
|
+
}
|
|
3612
3828
|
}
|
|
3829
|
+
if (probe(join4(current, ".git")))
|
|
3830
|
+
return null;
|
|
3831
|
+
if (boundary !== undefined && current === boundary)
|
|
3832
|
+
return null;
|
|
3833
|
+
const parent = dirname7(current);
|
|
3834
|
+
if (parent === current)
|
|
3835
|
+
return null;
|
|
3836
|
+
current = parent;
|
|
3613
3837
|
}
|
|
3614
|
-
|
|
3615
|
-
|
|
3838
|
+
}
|
|
3839
|
+
function resolveFromPath(command, suffixes, platform, pathEnvOverride) {
|
|
3840
|
+
let pathEnv = pathEnvOverride ?? process.env["PATH"] ?? "";
|
|
3841
|
+
if (platform === "win32" && !pathEnv) {
|
|
3616
3842
|
pathEnv = process.env["Path"] ?? "";
|
|
3617
3843
|
}
|
|
3618
|
-
const
|
|
3619
|
-
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
}
|
|
3844
|
+
for (const entry of pathEnv.split(delimiter3)) {
|
|
3845
|
+
if (entry.length === 0)
|
|
3846
|
+
continue;
|
|
3847
|
+
const found = probeWithSuffixes(entry, command, suffixes);
|
|
3848
|
+
if (found !== null)
|
|
3849
|
+
return found;
|
|
3625
3850
|
}
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
|
|
3851
|
+
return null;
|
|
3852
|
+
}
|
|
3853
|
+
function resolveServerBinary(command, workingDirectory, options = {}) {
|
|
3854
|
+
if (command.length === 0)
|
|
3855
|
+
return null;
|
|
3856
|
+
const [cmd] = command;
|
|
3857
|
+
if (cmd === undefined || cmd.length === 0)
|
|
3858
|
+
return null;
|
|
3859
|
+
const platform = options.platform ?? process.platform;
|
|
3860
|
+
const suffixes = executableSuffixes(platform, options.pathExt);
|
|
3861
|
+
if (cmd.includes("/") || cmd.includes("\\")) {
|
|
3862
|
+
const explicit = isAbsolute3(cmd) ? cmd : resolve7(workingDirectory ?? process.cwd(), cmd);
|
|
3863
|
+
return probe(explicit) ? explicit : null;
|
|
3864
|
+
}
|
|
3865
|
+
const cacheKey = JSON.stringify([
|
|
3866
|
+
workingDirectory ?? "",
|
|
3867
|
+
cmd,
|
|
3868
|
+
platform,
|
|
3869
|
+
options.stopAt ?? "",
|
|
3870
|
+
options.pathExt ?? "",
|
|
3871
|
+
options.pathEnv ?? process.env["PATH"] ?? ""
|
|
3872
|
+
]);
|
|
3873
|
+
const cached = resolutionCache.get(cacheKey);
|
|
3874
|
+
if (cached !== undefined)
|
|
3875
|
+
return cached;
|
|
3876
|
+
let resolved = null;
|
|
3877
|
+
if (workingDirectory !== undefined && workingDirectory.length > 0) {
|
|
3878
|
+
resolved = resolveLocal(cmd, workingDirectory, suffixes, options.stopAt);
|
|
3879
|
+
}
|
|
3880
|
+
resolved ??= resolveFromPath(cmd, suffixes, platform, options.pathEnv);
|
|
3881
|
+
if (resolved === null && cmd === "node")
|
|
3882
|
+
resolved = cmd;
|
|
3883
|
+
resolutionCache.set(cacheKey, resolved);
|
|
3884
|
+
return resolved;
|
|
3885
|
+
}
|
|
3886
|
+
function isServerInstalled(command, workingDirectory, options = {}) {
|
|
3887
|
+
if (command.length === 0)
|
|
3888
|
+
return false;
|
|
3889
|
+
return resolveServerBinary(command, workingDirectory, options) !== null;
|
|
3629
3890
|
}
|
|
3630
3891
|
|
|
3631
3892
|
// ../lsp-core/src/lsp/server-resolution.ts
|
|
3893
|
+
function withResolvedCommand(command, binaryPath) {
|
|
3894
|
+
return [binaryPath, ...command.slice(1)];
|
|
3895
|
+
}
|
|
3632
3896
|
function findServerForExtension(ext) {
|
|
3633
3897
|
const servers = getMergedServers();
|
|
3898
|
+
const workingDirectory = contextCwd();
|
|
3634
3899
|
for (const server of servers) {
|
|
3635
|
-
if (server.extensions.includes(ext)
|
|
3900
|
+
if (!server.extensions.includes(ext))
|
|
3901
|
+
continue;
|
|
3902
|
+
const binaryPath = resolveServerBinary(server.command, workingDirectory);
|
|
3903
|
+
if (binaryPath !== null) {
|
|
3636
3904
|
const resolvedServer = {
|
|
3637
3905
|
id: server.id,
|
|
3638
|
-
command: server.command,
|
|
3906
|
+
command: withResolvedCommand(server.command, binaryPath),
|
|
3639
3907
|
extensions: server.extensions,
|
|
3640
3908
|
priority: server.priority
|
|
3641
3909
|
};
|
|
@@ -3682,6 +3950,7 @@ function findServerForExtension(ext) {
|
|
|
3682
3950
|
function getAllServers() {
|
|
3683
3951
|
const servers = getMergedServers();
|
|
3684
3952
|
const disabled = getDisabledServerIds();
|
|
3953
|
+
const workingDirectory = contextCwd();
|
|
3685
3954
|
const result = [];
|
|
3686
3955
|
const seen = new Set;
|
|
3687
3956
|
for (const server of servers) {
|
|
@@ -3689,7 +3958,7 @@ function getAllServers() {
|
|
|
3689
3958
|
continue;
|
|
3690
3959
|
result.push({
|
|
3691
3960
|
id: server.id,
|
|
3692
|
-
installed: isServerInstalled(server.command),
|
|
3961
|
+
installed: isServerInstalled(server.command, workingDirectory),
|
|
3693
3962
|
extensions: server.extensions,
|
|
3694
3963
|
disabled: false,
|
|
3695
3964
|
source: server.source,
|
|
@@ -3703,7 +3972,7 @@ function getAllServers() {
|
|
|
3703
3972
|
const builtin = BUILTIN_SERVERS[id];
|
|
3704
3973
|
result.push({
|
|
3705
3974
|
id,
|
|
3706
|
-
installed: builtin ? isServerInstalled(builtin.command) : false,
|
|
3975
|
+
installed: builtin ? isServerInstalled(builtin.command, workingDirectory) : false,
|
|
3707
3976
|
extensions: builtin?.extensions ?? [],
|
|
3708
3977
|
disabled: true,
|
|
3709
3978
|
source: "disabled",
|
|
@@ -3714,7 +3983,6 @@ function getAllServers() {
|
|
|
3714
3983
|
}
|
|
3715
3984
|
|
|
3716
3985
|
// ../lsp-core/src/lsp/client-wrapper.ts
|
|
3717
|
-
var WORKSPACE_MARKERS = [".git", "package.json", "pyproject.toml", "Cargo.toml", "go.mod", "pom.xml", "build.gradle"];
|
|
3718
3986
|
function isDirectoryPath(filePath) {
|
|
3719
3987
|
try {
|
|
3720
3988
|
return statSync3(filePath).isDirectory();
|
|
@@ -3723,32 +3991,90 @@ function isDirectoryPath(filePath) {
|
|
|
3723
3991
|
}
|
|
3724
3992
|
}
|
|
3725
3993
|
function findWorkspaceRoot(filePath) {
|
|
3726
|
-
const
|
|
3994
|
+
const cwd = contextCwd();
|
|
3995
|
+
const abs = resolveReadablePathInsideContext(filePath);
|
|
3727
3996
|
let dir = abs;
|
|
3728
3997
|
if (!isDirectoryPath(dir)) {
|
|
3729
|
-
dir =
|
|
3730
|
-
}
|
|
3731
|
-
|
|
3732
|
-
|
|
3733
|
-
|
|
3734
|
-
|
|
3735
|
-
|
|
3998
|
+
dir = dirname8(dir);
|
|
3999
|
+
}
|
|
4000
|
+
if (!isPathInside(cwd, abs))
|
|
4001
|
+
return findWorkspaceRootOutsideContext(dir);
|
|
4002
|
+
const fallbackRoot = nearestExistingDirectoryInsideContext(dir, cwd) ?? cwd;
|
|
4003
|
+
let nearestPackageRoot;
|
|
4004
|
+
while (isPathInside(cwd, dir)) {
|
|
4005
|
+
const canonicalDir = existingDirectoryInsideContext(dir, cwd);
|
|
4006
|
+
if (canonicalDir !== undefined) {
|
|
4007
|
+
if (existsSync10(join5(dir, GIT_WORKSPACE_MARKER))) {
|
|
4008
|
+
return canonicalDir;
|
|
4009
|
+
}
|
|
4010
|
+
if (nearestPackageRoot === undefined && hasProjectWorkspaceMarker(dir)) {
|
|
4011
|
+
nearestPackageRoot = canonicalDir;
|
|
3736
4012
|
}
|
|
3737
4013
|
}
|
|
3738
|
-
|
|
3739
|
-
|
|
4014
|
+
if (dir === cwd)
|
|
4015
|
+
break;
|
|
4016
|
+
dir = dirname8(dir);
|
|
3740
4017
|
}
|
|
3741
|
-
return
|
|
4018
|
+
return nearestPackageRoot ?? fallbackRoot;
|
|
4019
|
+
}
|
|
4020
|
+
function hasProjectWorkspaceMarker(directory) {
|
|
4021
|
+
return PROJECT_WORKSPACE_MARKERS.some((marker) => existsSync10(join5(directory, marker)));
|
|
4022
|
+
}
|
|
4023
|
+
function resolveReadablePathInsideContext(filePath) {
|
|
4024
|
+
const cwd = contextCwd();
|
|
4025
|
+
const abs = resolve8(cwd, filePath);
|
|
4026
|
+
if (isPathInside(cwd, abs))
|
|
4027
|
+
return abs;
|
|
4028
|
+
const rebased = rebaseThroughCanonicalAncestor(abs, cwd);
|
|
4029
|
+
if (rebased !== undefined)
|
|
4030
|
+
return rebased;
|
|
4031
|
+
return canonicalizeExistingOrNearestAncestor(abs);
|
|
3742
4032
|
}
|
|
3743
4033
|
function resolvePathInsideContext(filePath) {
|
|
3744
4034
|
const cwd = contextCwd();
|
|
3745
|
-
const abs =
|
|
4035
|
+
const abs = resolveReadablePathInsideContext(filePath);
|
|
3746
4036
|
const canonical = canonicalizeExistingOrNearestAncestor(abs);
|
|
3747
4037
|
if (!isPathInside(cwd, canonical)) {
|
|
3748
4038
|
throw new LspInvalidPathError(`LSP file path must be inside request cwd: ${filePath}`);
|
|
3749
4039
|
}
|
|
3750
4040
|
return canonical;
|
|
3751
4041
|
}
|
|
4042
|
+
function rebaseThroughCanonicalAncestor(path, cwd) {
|
|
4043
|
+
let current = path;
|
|
4044
|
+
const suffix = [];
|
|
4045
|
+
while (true) {
|
|
4046
|
+
if (existsSync10(current)) {
|
|
4047
|
+
const canonical = realpathSync5(current);
|
|
4048
|
+
if (isPathInside(cwd, canonical))
|
|
4049
|
+
return suffix.length === 0 ? canonical : join5(canonical, ...suffix);
|
|
4050
|
+
}
|
|
4051
|
+
const parent = dirname8(current);
|
|
4052
|
+
if (parent === current)
|
|
4053
|
+
return;
|
|
4054
|
+
suffix.unshift(basename3(current));
|
|
4055
|
+
current = parent;
|
|
4056
|
+
}
|
|
4057
|
+
}
|
|
4058
|
+
function existingDirectoryInsideContext(directory, cwd) {
|
|
4059
|
+
if (!existsSync10(directory))
|
|
4060
|
+
return;
|
|
4061
|
+
const canonical = realpathSync5(directory);
|
|
4062
|
+
if (!statSync3(canonical).isDirectory())
|
|
4063
|
+
return;
|
|
4064
|
+
return isPathInside(cwd, canonical) ? canonical : undefined;
|
|
4065
|
+
}
|
|
4066
|
+
function nearestExistingDirectoryInsideContext(directory, cwd) {
|
|
4067
|
+
let current = directory;
|
|
4068
|
+
while (isPathInside(cwd, current)) {
|
|
4069
|
+
const canonical = existingDirectoryInsideContext(current, cwd);
|
|
4070
|
+
if (canonical !== undefined)
|
|
4071
|
+
return canonical;
|
|
4072
|
+
if (current === cwd)
|
|
4073
|
+
return;
|
|
4074
|
+
current = dirname8(current);
|
|
4075
|
+
}
|
|
4076
|
+
return;
|
|
4077
|
+
}
|
|
3752
4078
|
function formatServerLookupError(result) {
|
|
3753
4079
|
if (result.status === "not_installed") {
|
|
3754
4080
|
return formatNotInstalled(result);
|
|
@@ -3772,6 +4098,19 @@ function formatServerLookupError(result) {
|
|
|
3772
4098
|
].join(`
|
|
3773
4099
|
`);
|
|
3774
4100
|
}
|
|
4101
|
+
function formatInstallOptions(serverId, installHint) {
|
|
4102
|
+
const localHint = LSP_LOCAL_INSTALL_HINTS[serverId];
|
|
4103
|
+
if (localHint === undefined) {
|
|
4104
|
+
return ["To install, run:", ` ${installHint}`];
|
|
4105
|
+
}
|
|
4106
|
+
return [
|
|
4107
|
+
"To install in THIS repository (preferred — no global install needed):",
|
|
4108
|
+
` ${localHint}`,
|
|
4109
|
+
"",
|
|
4110
|
+
"Or install it globally:",
|
|
4111
|
+
` ${installHint}`
|
|
4112
|
+
];
|
|
4113
|
+
}
|
|
3775
4114
|
function formatNotInstalled(result) {
|
|
3776
4115
|
const { server, installHint } = result;
|
|
3777
4116
|
const extensions = server.extensions.join(", ");
|
|
@@ -3786,19 +4125,19 @@ function formatNotInstalled(result) {
|
|
|
3786
4125
|
`Command not found: ${server.command[0]}`,
|
|
3787
4126
|
""
|
|
3788
4127
|
];
|
|
4128
|
+
const installOptions = formatInstallOptions(server.id, installHint);
|
|
3789
4129
|
if (decision === "allowed") {
|
|
3790
4130
|
return [
|
|
3791
4131
|
...header,
|
|
3792
4132
|
"The user has pre-authorized LSP installation. Run the install command, then retry this tool:",
|
|
3793
|
-
|
|
4133
|
+
...installOptions.slice(1)
|
|
3794
4134
|
].join(`
|
|
3795
4135
|
`);
|
|
3796
4136
|
}
|
|
3797
4137
|
if (!context.capabilities.installDecisionTool) {
|
|
3798
4138
|
return [
|
|
3799
4139
|
...header,
|
|
3800
|
-
|
|
3801
|
-
` ${installHint}`,
|
|
4140
|
+
...installOptions,
|
|
3802
4141
|
"",
|
|
3803
4142
|
"ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
|
|
3804
4143
|
"Install-decision recording is unavailable in this harness; proceed without LSP if the user declines."
|
|
@@ -3807,8 +4146,7 @@ function formatNotInstalled(result) {
|
|
|
3807
4146
|
}
|
|
3808
4147
|
return [
|
|
3809
4148
|
...header,
|
|
3810
|
-
|
|
3811
|
-
` ${installHint}`,
|
|
4149
|
+
...installOptions,
|
|
3812
4150
|
"",
|
|
3813
4151
|
"ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
|
|
3814
4152
|
"- If the user agrees: run the install command above, then retry this tool.",
|
|
@@ -3819,7 +4157,7 @@ function formatNotInstalled(result) {
|
|
|
3819
4157
|
].join(`
|
|
3820
4158
|
`);
|
|
3821
4159
|
}
|
|
3822
|
-
var
|
|
4160
|
+
var READ_ONLY_TOOLS = new Set([
|
|
3823
4161
|
"diagnostics",
|
|
3824
4162
|
"definition",
|
|
3825
4163
|
"references",
|
|
@@ -3828,7 +4166,7 @@ var READ_ONLY_RETRY_TOOLS = new Set([
|
|
|
3828
4166
|
"prepareRename"
|
|
3829
4167
|
]);
|
|
3830
4168
|
async function withLspClient(filePath, fn, toolName, options = {}) {
|
|
3831
|
-
const absPath = resolvePathInsideContext(filePath);
|
|
4169
|
+
const absPath = READ_ONLY_TOOLS.has(toolName) ? resolveReadablePathInsideContext(filePath) : resolvePathInsideContext(filePath);
|
|
3832
4170
|
if (isDirectoryPath(absPath)) {
|
|
3833
4171
|
throw new LspInvalidPathError("Directory paths are not supported by this LSP tool. " + "Use lsp.diagnostics with a directory path for directory diagnostics.");
|
|
3834
4172
|
}
|
|
@@ -3843,9 +4181,9 @@ async function withLspClient(filePath, fn, toolName, options = {}) {
|
|
|
3843
4181
|
const acquireAndCall = async (allowRetry) => {
|
|
3844
4182
|
const client = await manager.getClient(root, server, options.signal);
|
|
3845
4183
|
try {
|
|
3846
|
-
return await fn(client, root);
|
|
4184
|
+
return await fn(client, root, absPath);
|
|
3847
4185
|
} catch (err) {
|
|
3848
|
-
if (allowRetry &&
|
|
4186
|
+
if (allowRetry && READ_ONLY_TOOLS.has(toolName) && isLspDeadConnectionError(err)) {
|
|
3849
4187
|
manager.invalidateClient(root, server.id, client);
|
|
3850
4188
|
return acquireAndCall(false);
|
|
3851
4189
|
}
|
|
@@ -3863,8 +4201,8 @@ async function withLspClient(filePath, fn, toolName, options = {}) {
|
|
|
3863
4201
|
}
|
|
3864
4202
|
|
|
3865
4203
|
// ../lsp-core/src/lsp/directory-diagnostics.ts
|
|
3866
|
-
import { existsSync as
|
|
3867
|
-
import { join as
|
|
4204
|
+
import { existsSync as existsSync11, lstatSync as lstatSync4, readdirSync as readdirSync3 } from "node:fs";
|
|
4205
|
+
import { join as join6, resolve as resolve9 } from "node:path";
|
|
3868
4206
|
|
|
3869
4207
|
// ../lsp-core/src/lsp/formatters.ts
|
|
3870
4208
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
@@ -3994,7 +4332,7 @@ function collectFilesWithExtension(dir, extension, maxFiles) {
|
|
|
3994
4332
|
for (const entry of entries) {
|
|
3995
4333
|
if (files.length >= maxFiles)
|
|
3996
4334
|
return;
|
|
3997
|
-
const fullPath =
|
|
4335
|
+
const fullPath = join6(currentDir, entry);
|
|
3998
4336
|
let stat;
|
|
3999
4337
|
try {
|
|
4000
4338
|
stat = lstatSync4(fullPath);
|
|
@@ -4019,8 +4357,8 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
|
|
|
4019
4357
|
if (!extension.startsWith(".")) {
|
|
4020
4358
|
throw new LspInvalidPathError(`Extension must start with a dot (e.g., ".ts", not "${extension}"). Use ".${extension}" instead.`);
|
|
4021
4359
|
}
|
|
4022
|
-
const absDir =
|
|
4023
|
-
if (!
|
|
4360
|
+
const absDir = resolve9(options.workspaceRoot ?? contextCwd(), directory);
|
|
4361
|
+
if (!existsSync11(absDir)) {
|
|
4024
4362
|
throw new LspInvalidPathError(`Directory does not exist: ${absDir}`);
|
|
4025
4363
|
}
|
|
4026
4364
|
const serverResult = options.server === undefined ? findServerForExtension(extension) : { status: "found", server: options.server };
|
|
@@ -4107,7 +4445,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
|
|
|
4107
4445
|
|
|
4108
4446
|
// ../lsp-core/src/lsp/infer-extension.ts
|
|
4109
4447
|
import { lstatSync as lstatSync5, readdirSync as readdirSync4 } from "node:fs";
|
|
4110
|
-
import { join as
|
|
4448
|
+
import { join as join7 } from "node:path";
|
|
4111
4449
|
var SKIP_DIRECTORIES2 = new Set(["node_modules", ".git", "dist", "build", ".next", "out"]);
|
|
4112
4450
|
var MAX_SCAN_ENTRIES = 500;
|
|
4113
4451
|
function inferExtensionFromDirectory(directory) {
|
|
@@ -4125,7 +4463,7 @@ function inferExtensionFromDirectory(directory) {
|
|
|
4125
4463
|
for (const entry of entries) {
|
|
4126
4464
|
if (scanned >= MAX_SCAN_ENTRIES)
|
|
4127
4465
|
return;
|
|
4128
|
-
const fullPath =
|
|
4466
|
+
const fullPath = join7(dir, entry);
|
|
4129
4467
|
let stat;
|
|
4130
4468
|
try {
|
|
4131
4469
|
stat = lstatSync5(fullPath);
|
|
@@ -4300,7 +4638,7 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
4300
4638
|
const filePath = requireString(params, "filePath");
|
|
4301
4639
|
const severity = severityFilter(params);
|
|
4302
4640
|
try {
|
|
4303
|
-
const absPath =
|
|
4641
|
+
const absPath = resolveReadablePathInsideContext(filePath);
|
|
4304
4642
|
if (isDirectoryPath(absPath)) {
|
|
4305
4643
|
const extension = inferExtensionFromDirectory(absPath);
|
|
4306
4644
|
if (!extension) {
|
|
@@ -4329,7 +4667,7 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
4329
4667
|
};
|
|
4330
4668
|
return text(output2.output, details2);
|
|
4331
4669
|
}
|
|
4332
|
-
const result = await withLspClient(filePath, async (client) => client.diagnostics(
|
|
4670
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.diagnostics(resolvedFilePath, signal), "diagnostics", clientOptions(signal));
|
|
4333
4671
|
if (result.transientError) {
|
|
4334
4672
|
const message = result.transientError.message;
|
|
4335
4673
|
const details2 = {
|
|
@@ -4376,6 +4714,96 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
4376
4714
|
throw error;
|
|
4377
4715
|
}
|
|
4378
4716
|
}
|
|
4717
|
+
// ../lsp-core/src/lsp/format-document.ts
|
|
4718
|
+
import { readFileSync as readFileSync5, renameSync as renameSync3, unlinkSync, writeFileSync as writeFileSync3 } from "node:fs";
|
|
4719
|
+
var DEFAULT_FORMATTING_OPTIONS = {
|
|
4720
|
+
tabSize: 4,
|
|
4721
|
+
insertSpaces: false,
|
|
4722
|
+
trimTrailingWhitespace: true,
|
|
4723
|
+
insertFinalNewline: true,
|
|
4724
|
+
trimFinalNewlines: true
|
|
4725
|
+
};
|
|
4726
|
+
var UNCHANGED = { status: "unchanged", linesAdded: 0, linesRemoved: 0 };
|
|
4727
|
+
async function formatDocumentWithClient(client, filePath, options = {}) {
|
|
4728
|
+
const edits = await client.formatDocument(filePath, options.formattingOptions ?? DEFAULT_FORMATTING_OPTIONS, options.signal);
|
|
4729
|
+
if (edits === null)
|
|
4730
|
+
return { status: "unavailable", reason: "capability_not_advertised" };
|
|
4731
|
+
if (edits.length === 0)
|
|
4732
|
+
return UNCHANGED;
|
|
4733
|
+
const before = readFileSync5(filePath, "utf-8");
|
|
4734
|
+
const normalized = normalizeTextEdits(before, edits, 0);
|
|
4735
|
+
if (normalized.text === before)
|
|
4736
|
+
return UNCHANGED;
|
|
4737
|
+
writeAtomically(filePath, normalized.text);
|
|
4738
|
+
await client.openFile(filePath);
|
|
4739
|
+
return {
|
|
4740
|
+
status: "formatted",
|
|
4741
|
+
...lineDelta(normalized.edits)
|
|
4742
|
+
};
|
|
4743
|
+
}
|
|
4744
|
+
function lineDelta(edits) {
|
|
4745
|
+
let linesAdded = 0;
|
|
4746
|
+
let linesRemoved = 0;
|
|
4747
|
+
for (const edit of edits) {
|
|
4748
|
+
linesRemoved += edit.range.end.line - edit.range.start.line + 1;
|
|
4749
|
+
linesAdded += edit.newText.split(`
|
|
4750
|
+
`).length;
|
|
4751
|
+
}
|
|
4752
|
+
return { linesAdded, linesRemoved };
|
|
4753
|
+
}
|
|
4754
|
+
function writeAtomically(filePath, content) {
|
|
4755
|
+
const tempPath = `${filePath}.omo-format.tmp`;
|
|
4756
|
+
writeFileSync3(tempPath, content, "utf-8");
|
|
4757
|
+
try {
|
|
4758
|
+
renameSync3(tempPath, filePath);
|
|
4759
|
+
} catch (error) {
|
|
4760
|
+
try {
|
|
4761
|
+
unlinkSync(tempPath);
|
|
4762
|
+
} catch {}
|
|
4763
|
+
throw error;
|
|
4764
|
+
}
|
|
4765
|
+
}
|
|
4766
|
+
|
|
4767
|
+
// ../lsp-core/src/tools/format.ts
|
|
4768
|
+
async function executeLspFormat(params, signal) {
|
|
4769
|
+
const filePath = requireString(params, "filePath");
|
|
4770
|
+
try {
|
|
4771
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => formatDocumentWithClient(client, resolvedFilePath, signal === undefined ? {} : { signal }), "format", clientOptions(signal));
|
|
4772
|
+
return text(describeResult(filePath, result), formatDetails(filePath, result));
|
|
4773
|
+
} catch (error) {
|
|
4774
|
+
const missingDependency = missingDependencyResult(error, {
|
|
4775
|
+
filePath,
|
|
4776
|
+
status: "unavailable",
|
|
4777
|
+
reason: "server_unavailable",
|
|
4778
|
+
linesAdded: 0,
|
|
4779
|
+
linesRemoved: 0
|
|
4780
|
+
});
|
|
4781
|
+
if (missingDependency)
|
|
4782
|
+
return missingDependency;
|
|
4783
|
+
throw error;
|
|
4784
|
+
}
|
|
4785
|
+
}
|
|
4786
|
+
function formatDetails(filePath, result) {
|
|
4787
|
+
if (result.status === "unavailable") {
|
|
4788
|
+
return { filePath, status: "unavailable", reason: result.reason, linesAdded: 0, linesRemoved: 0 };
|
|
4789
|
+
}
|
|
4790
|
+
return {
|
|
4791
|
+
filePath,
|
|
4792
|
+
status: result.status,
|
|
4793
|
+
linesAdded: result.linesAdded,
|
|
4794
|
+
linesRemoved: result.linesRemoved
|
|
4795
|
+
};
|
|
4796
|
+
}
|
|
4797
|
+
function describeResult(filePath, result) {
|
|
4798
|
+
if (result.status === "unavailable") {
|
|
4799
|
+
return `Formatting unavailable for ${filePath}: the language server does not advertise documentFormattingProvider.`;
|
|
4800
|
+
}
|
|
4801
|
+
if (result.status === "unchanged") {
|
|
4802
|
+
return `Already formatted: ${filePath}`;
|
|
4803
|
+
}
|
|
4804
|
+
return `Formatted ${filePath} (+${result.linesAdded}/-${result.linesRemoved} lines)`;
|
|
4805
|
+
}
|
|
4806
|
+
|
|
4379
4807
|
// ../lsp-core/src/tools/install-decision.ts
|
|
4380
4808
|
async function executeLspInstallDecision(params) {
|
|
4381
4809
|
const serverId = requireString(params, "server_id");
|
|
@@ -4404,7 +4832,7 @@ async function executeLspGotoDefinition(params, signal) {
|
|
|
4404
4832
|
const line = requireNumber(params, "line");
|
|
4405
4833
|
const character = requireNumber(params, "character");
|
|
4406
4834
|
try {
|
|
4407
|
-
const result = await withLspClient(filePath, async (client) => client.definition(
|
|
4835
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.definition(resolvedFilePath, line, character, signal), "definition", clientOptions(signal));
|
|
4408
4836
|
const locations = !result ? [] : Array.isArray(result) ? result : [result];
|
|
4409
4837
|
const details = { filePath, line, character, locations };
|
|
4410
4838
|
if (locations.length === 0)
|
|
@@ -4429,7 +4857,7 @@ async function executeLspFindReferences(params, signal) {
|
|
|
4429
4857
|
const character = requireNumber(params, "character");
|
|
4430
4858
|
const includeDeclaration = optionalBoolean(params, "includeDeclaration") ?? true;
|
|
4431
4859
|
try {
|
|
4432
|
-
const result = await withLspClient(filePath, async (client) => client.references(
|
|
4860
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.references(resolvedFilePath, line, character, includeDeclaration, signal), "references", clientOptions(signal));
|
|
4433
4861
|
const references = Array.isArray(result) ? result : [];
|
|
4434
4862
|
const total = references.length;
|
|
4435
4863
|
const truncated = total > DEFAULT_MAX_REFERENCES;
|
|
@@ -4471,7 +4899,7 @@ async function executeLspPrepareRename(params, signal) {
|
|
|
4471
4899
|
const line = requireNumber(params, "line");
|
|
4472
4900
|
const character = requireNumber(params, "character");
|
|
4473
4901
|
try {
|
|
4474
|
-
const result = await withLspClient(filePath, async (client) => client.prepareRename(
|
|
4902
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.prepareRename(resolvedFilePath, line, character, signal), "prepareRename", clientOptions(signal));
|
|
4475
4903
|
const details = { filePath, line, character, result };
|
|
4476
4904
|
return text(formatPrepareRenameResult(result), details);
|
|
4477
4905
|
} catch (error) {
|
|
@@ -4492,7 +4920,7 @@ async function executeLspRename(params, signal) {
|
|
|
4492
4920
|
const character = requireNumber(params, "character");
|
|
4493
4921
|
const newName = requireString(params, "newName");
|
|
4494
4922
|
try {
|
|
4495
|
-
const result = await withLspClient(filePath, async (client) => client.rename(
|
|
4923
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.rename(resolvedFilePath, line, character, newName, signal), "rename", clientOptions(signal));
|
|
4496
4924
|
const details = { filePath, line, character, newName, apply: result.apply, edit: result.edit };
|
|
4497
4925
|
return text(formatApplyResult(result.apply), details, !result.apply.success);
|
|
4498
4926
|
} catch (error) {
|
|
@@ -4572,7 +5000,7 @@ async function executeLspSymbols(params, signal) {
|
|
|
4572
5000
|
const symbols2 = await withLspClient(filePath, async (client) => client.workspaceSymbols(query, signal), "workspaceSymbols", clientOptions(signal));
|
|
4573
5001
|
return formatSymbolsResult(filePath, scope, symbols2, limit, query);
|
|
4574
5002
|
}
|
|
4575
|
-
const symbols = await withLspClient(filePath, async (client) => client.documentSymbols(
|
|
5003
|
+
const symbols = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.documentSymbols(resolvedFilePath, signal), "documentSymbols", clientOptions(signal));
|
|
4576
5004
|
return formatSymbolsResult(filePath, scope, symbols, limit);
|
|
4577
5005
|
} catch (error) {
|
|
4578
5006
|
const query = optionalString(params, "query");
|
|
@@ -4708,6 +5136,16 @@ var LSP_MCP_TOOLS = [
|
|
|
4708
5136
|
}, ["filePath", "line", "character", "newName"]),
|
|
4709
5137
|
execute: executeLspRename
|
|
4710
5138
|
},
|
|
5139
|
+
{
|
|
5140
|
+
name: "format",
|
|
5141
|
+
aliases: ["lsp_format"],
|
|
5142
|
+
title: "LSP Format",
|
|
5143
|
+
description: "Format a source file with its language server and write the returned edits to disk.",
|
|
5144
|
+
inputSchema: objectSchema({
|
|
5145
|
+
filePath: { type: "string", description: "Source file path to format." }
|
|
5146
|
+
}, ["filePath"]),
|
|
5147
|
+
execute: executeLspFormat
|
|
5148
|
+
},
|
|
4711
5149
|
{
|
|
4712
5150
|
name: "install_decision",
|
|
4713
5151
|
aliases: ["lsp_install_decision"],
|
|
@@ -4741,16 +5179,17 @@ function coerceToolArguments(value) {
|
|
|
4741
5179
|
return isRecord7(value) ? value : {};
|
|
4742
5180
|
}
|
|
4743
5181
|
export {
|
|
4744
|
-
|
|
4745
|
-
executeLspTool,
|
|
4746
|
-
executeLspSymbols,
|
|
4747
|
-
executeLspStatus,
|
|
4748
|
-
executeLspRename,
|
|
4749
|
-
executeLspPrepareRename,
|
|
4750
|
-
executeLspInstallDecision,
|
|
4751
|
-
executeLspGotoDefinition,
|
|
4752
|
-
executeLspFindReferences,
|
|
4753
|
-
executeLspDiagnostics,
|
|
5182
|
+
LSP_MCP_TOOLS,
|
|
4754
5183
|
coerceToolArguments,
|
|
4755
|
-
|
|
5184
|
+
executeLspDiagnostics,
|
|
5185
|
+
executeLspFindReferences,
|
|
5186
|
+
executeLspFormat,
|
|
5187
|
+
executeLspGotoDefinition,
|
|
5188
|
+
executeLspInstallDecision,
|
|
5189
|
+
executeLspPrepareRename,
|
|
5190
|
+
executeLspRename,
|
|
5191
|
+
executeLspStatus,
|
|
5192
|
+
executeLspSymbols,
|
|
5193
|
+
executeLspTool,
|
|
5194
|
+
isRecord7 as isRecord
|
|
4756
5195
|
};
|