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
|
@@ -23,28 +23,24 @@ var DEFAULT_MAX_DIRECTORY_FILES = 50;
|
|
|
23
23
|
var REQUEST_TIMEOUT_MS = 15000;
|
|
24
24
|
var INIT_TIMEOUT_MS = 60000;
|
|
25
25
|
var IDLE_TIMEOUT_MS = 5 * 60000;
|
|
26
|
+
var MAX_RESIDENT_CLIENTS = 6;
|
|
26
27
|
var REAPER_INTERVAL_MS = 60000;
|
|
27
28
|
var STOP_HARD_KILL_TIMEOUT_MS = 5000;
|
|
28
29
|
var STOP_SIGKILL_GRACE_MS = 1000;
|
|
30
|
+
var CLIENT_RESPAWN_RETRY_LIMIT = 2;
|
|
31
|
+
var CLIENT_RESPAWN_COOLDOWN_MS = 60000;
|
|
29
32
|
|
|
30
33
|
// ../lsp-core/src/lsp/errors.ts
|
|
31
34
|
class LspConnectionClosedError extends Error {
|
|
32
|
-
serverId;
|
|
33
|
-
root;
|
|
34
|
-
name = "LspConnectionClosedError";
|
|
35
35
|
constructor(serverId, root, message) {
|
|
36
36
|
super(message ?? `LSP connection closed for ${serverId} at ${root}`);
|
|
37
37
|
this.serverId = serverId;
|
|
38
38
|
this.root = root;
|
|
39
|
+
this.name = "LspConnectionClosedError";
|
|
39
40
|
}
|
|
40
41
|
}
|
|
41
42
|
|
|
42
43
|
class LspProcessExitedError extends Error {
|
|
43
|
-
serverId;
|
|
44
|
-
root;
|
|
45
|
-
exitCode;
|
|
46
|
-
stderrTail;
|
|
47
|
-
name = "LspProcessExitedError";
|
|
48
44
|
constructor(serverId, root, exitCode, stderrTail) {
|
|
49
45
|
const stderrSuffix = stderrTail ? `
|
|
50
46
|
stderr tail: ${stderrTail}` : "";
|
|
@@ -53,46 +49,59 @@ stderr tail: ${stderrTail}` : "";
|
|
|
53
49
|
this.root = root;
|
|
54
50
|
this.exitCode = exitCode;
|
|
55
51
|
this.stderrTail = stderrTail;
|
|
52
|
+
this.name = "LspProcessExitedError";
|
|
56
53
|
}
|
|
57
54
|
}
|
|
58
55
|
|
|
59
56
|
class LspRequestTimeoutError extends Error {
|
|
60
|
-
method;
|
|
61
|
-
stderrTail;
|
|
62
|
-
name = "LspRequestTimeoutError";
|
|
63
57
|
constructor(method, stderrTail) {
|
|
64
58
|
const stderrSuffix = stderrTail ? `
|
|
65
59
|
recent stderr: ${stderrTail}` : "";
|
|
66
60
|
super(`LSP request timeout (method: ${method})${stderrSuffix}`);
|
|
67
61
|
this.method = method;
|
|
68
62
|
this.stderrTail = stderrTail;
|
|
63
|
+
this.name = "LspRequestTimeoutError";
|
|
69
64
|
}
|
|
70
65
|
}
|
|
71
66
|
|
|
72
67
|
class LspInvalidPathError extends Error {
|
|
73
|
-
|
|
68
|
+
constructor() {
|
|
69
|
+
super(...arguments);
|
|
70
|
+
this.name = "LspInvalidPathError";
|
|
71
|
+
}
|
|
74
72
|
}
|
|
75
73
|
|
|
76
74
|
class LspServerLookupError extends Error {
|
|
77
|
-
lookup;
|
|
78
|
-
name = "LspServerLookupError";
|
|
79
75
|
constructor(message, lookup) {
|
|
80
76
|
super(message);
|
|
81
77
|
this.lookup = lookup;
|
|
78
|
+
this.name = "LspServerLookupError";
|
|
82
79
|
}
|
|
83
80
|
}
|
|
84
81
|
|
|
85
82
|
class LspServerInitializingError extends Error {
|
|
86
|
-
originalError;
|
|
87
|
-
name = "LspServerInitializingError";
|
|
88
83
|
constructor(originalError) {
|
|
89
84
|
super(`LSP server is still initializing. Please retry in a few seconds. Original error: ${originalError.message}`);
|
|
90
85
|
this.originalError = originalError;
|
|
86
|
+
this.name = "LspServerInitializingError";
|
|
91
87
|
}
|
|
92
88
|
}
|
|
93
89
|
|
|
94
90
|
class LspProcessSpawnError extends Error {
|
|
95
|
-
|
|
91
|
+
constructor() {
|
|
92
|
+
super(...arguments);
|
|
93
|
+
this.name = "LspProcessSpawnError";
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
class LspClientRespawnBudgetExceededError extends Error {
|
|
98
|
+
constructor(serverId, root, retryLimit) {
|
|
99
|
+
super(`LSP server ${serverId} at ${root} failed to stay alive; respawn budget exhausted ` + `(${retryLimit} consecutive dead generations). Retrying after the cooldown may succeed.`);
|
|
100
|
+
this.serverId = serverId;
|
|
101
|
+
this.root = root;
|
|
102
|
+
this.retryLimit = retryLimit;
|
|
103
|
+
this.name = "LspClientRespawnBudgetExceededError";
|
|
104
|
+
}
|
|
96
105
|
}
|
|
97
106
|
function isLspDeadConnectionError(err) {
|
|
98
107
|
return err instanceof LspConnectionClosedError || err instanceof LspProcessExitedError;
|
|
@@ -108,20 +117,31 @@ var METHOD_NOT_FOUND = -32601;
|
|
|
108
117
|
var INTERNAL_ERROR = -32603;
|
|
109
118
|
|
|
110
119
|
class JsonRpcConnection {
|
|
111
|
-
reader;
|
|
112
|
-
writer;
|
|
113
|
-
pendingRequests = new Map;
|
|
114
|
-
notificationHandlers = new Map;
|
|
115
|
-
requestHandlers = new Map;
|
|
116
|
-
closeHandlers = [];
|
|
117
|
-
errorHandlers = [];
|
|
118
|
-
inputBuffer = Buffer.alloc(0);
|
|
119
|
-
nextRequestId = 1;
|
|
120
|
-
listening = false;
|
|
121
|
-
disposed = false;
|
|
122
120
|
constructor(reader, writer) {
|
|
123
121
|
this.reader = reader;
|
|
124
122
|
this.writer = writer;
|
|
123
|
+
this.pendingRequests = new Map;
|
|
124
|
+
this.notificationHandlers = new Map;
|
|
125
|
+
this.requestHandlers = new Map;
|
|
126
|
+
this.closeHandlers = [];
|
|
127
|
+
this.errorHandlers = [];
|
|
128
|
+
this.inputBuffer = Buffer.alloc(0);
|
|
129
|
+
this.nextRequestId = 1;
|
|
130
|
+
this.listening = false;
|
|
131
|
+
this.disposed = false;
|
|
132
|
+
this.handleData = (chunk) => {
|
|
133
|
+
const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
|
|
134
|
+
this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
|
|
135
|
+
this.drainInputBuffer();
|
|
136
|
+
};
|
|
137
|
+
this.handleClose = () => {
|
|
138
|
+
for (const handler of this.closeHandlers) {
|
|
139
|
+
handler();
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
this.handleStreamError = (error) => {
|
|
143
|
+
this.emitError(error);
|
|
144
|
+
};
|
|
125
145
|
}
|
|
126
146
|
listen() {
|
|
127
147
|
if (this.listening)
|
|
@@ -242,19 +262,6 @@ class JsonRpcConnection {
|
|
|
242
262
|
this.notificationHandlers.clear();
|
|
243
263
|
this.requestHandlers.clear();
|
|
244
264
|
}
|
|
245
|
-
handleData = (chunk) => {
|
|
246
|
-
const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
|
|
247
|
-
this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
|
|
248
|
-
this.drainInputBuffer();
|
|
249
|
-
};
|
|
250
|
-
handleClose = () => {
|
|
251
|
-
for (const handler of this.closeHandlers) {
|
|
252
|
-
handler();
|
|
253
|
-
}
|
|
254
|
-
};
|
|
255
|
-
handleStreamError = (error) => {
|
|
256
|
-
this.emitError(error);
|
|
257
|
-
};
|
|
258
265
|
drainInputBuffer() {
|
|
259
266
|
while (true) {
|
|
260
267
|
const headerEnd = this.inputBuffer.indexOf(HEADER_SEPARATOR);
|
|
@@ -602,31 +609,26 @@ function isPosition(value) {
|
|
|
602
609
|
|
|
603
610
|
// ../lsp-core/src/lsp/transport.ts
|
|
604
611
|
class LspClientNotStartedError extends Error {
|
|
605
|
-
serverId;
|
|
606
|
-
root;
|
|
607
|
-
name = "LspClientNotStartedError";
|
|
608
612
|
constructor(serverId, root) {
|
|
609
613
|
super("LSP client not started");
|
|
610
614
|
this.serverId = serverId;
|
|
611
615
|
this.root = root;
|
|
616
|
+
this.name = "LspClientNotStartedError";
|
|
612
617
|
}
|
|
613
618
|
}
|
|
614
619
|
|
|
615
620
|
class LspClientTransport {
|
|
616
|
-
root;
|
|
617
|
-
server;
|
|
618
|
-
proc = null;
|
|
619
|
-
connection = null;
|
|
620
|
-
stderrBuffer = [];
|
|
621
|
-
processExited = false;
|
|
622
|
-
diagnosticsStore = new Map;
|
|
623
|
-
requestTimeoutMs;
|
|
624
|
-
initializeTimeoutMs;
|
|
625
|
-
workspaceApplyEditHandler = null;
|
|
626
|
-
diagnosticPullSupported = false;
|
|
627
621
|
constructor(root, server, timeouts = {}) {
|
|
628
622
|
this.root = root;
|
|
629
623
|
this.server = server;
|
|
624
|
+
this.proc = null;
|
|
625
|
+
this.connection = null;
|
|
626
|
+
this.stderrBuffer = [];
|
|
627
|
+
this.processExited = false;
|
|
628
|
+
this.diagnosticsStore = new Map;
|
|
629
|
+
this.workspaceApplyEditHandler = null;
|
|
630
|
+
this.diagnosticPullSupported = false;
|
|
631
|
+
this.documentFormattingSupported = false;
|
|
630
632
|
this.requestTimeoutMs = timeouts.requestTimeoutMs ?? REQUEST_TIMEOUT_MS;
|
|
631
633
|
this.initializeTimeoutMs = timeouts.initializeTimeoutMs ?? INIT_TIMEOUT_MS;
|
|
632
634
|
}
|
|
@@ -648,6 +650,12 @@ class LspClientTransport {
|
|
|
648
650
|
isDiagnosticPullSupported() {
|
|
649
651
|
return this.diagnosticPullSupported;
|
|
650
652
|
}
|
|
653
|
+
setDocumentFormattingSupported(supported) {
|
|
654
|
+
this.documentFormattingSupported = supported;
|
|
655
|
+
}
|
|
656
|
+
isDocumentFormattingSupported() {
|
|
657
|
+
return this.documentFormattingSupported;
|
|
658
|
+
}
|
|
651
659
|
handlePublishDiagnostics(params) {
|
|
652
660
|
this.diagnosticsStore.set(params.uri, [...params.diagnostics]);
|
|
653
661
|
}
|
|
@@ -861,6 +869,14 @@ function supportsDiagnosticPull(capabilities) {
|
|
|
861
869
|
return false;
|
|
862
870
|
return Object.hasOwn(capabilities, "diagnosticProvider");
|
|
863
871
|
}
|
|
872
|
+
function supportsDocumentFormatting(capabilities) {
|
|
873
|
+
if (capabilities === undefined)
|
|
874
|
+
return false;
|
|
875
|
+
const provider = capabilities.documentFormattingProvider;
|
|
876
|
+
if (provider === undefined || provider === null || provider === false)
|
|
877
|
+
return false;
|
|
878
|
+
return provider === true || typeof provider === "object";
|
|
879
|
+
}
|
|
864
880
|
|
|
865
881
|
class LspClientConnection extends LspClientTransport {
|
|
866
882
|
async initialize() {
|
|
@@ -877,6 +893,7 @@ class LspClientConnection extends LspClientTransport {
|
|
|
877
893
|
references: {},
|
|
878
894
|
documentSymbol: { hierarchicalDocumentSymbolSupport: true },
|
|
879
895
|
publishDiagnostics: {},
|
|
896
|
+
formatting: { dynamicRegistration: false },
|
|
880
897
|
rename: {
|
|
881
898
|
prepareSupport: true,
|
|
882
899
|
prepareSupportDefaultBehavior: 1
|
|
@@ -918,6 +935,7 @@ class LspClientConnection extends LspClientTransport {
|
|
|
918
935
|
initializationOptions: this.server.initialization
|
|
919
936
|
}, { timeoutMs: this.initializeTimeoutMs });
|
|
920
937
|
this.setDiagnosticPullSupported(supportsDiagnosticPull(result?.capabilities));
|
|
938
|
+
this.setDocumentFormattingSupported(supportsDocumentFormatting(result?.capabilities));
|
|
921
939
|
await this.sendNotification("initialized", {});
|
|
922
940
|
await this.sendNotification("workspace/didChangeConfiguration", {
|
|
923
941
|
settings: { json: { validate: { enable: true } } }
|
|
@@ -1133,16 +1151,12 @@ function movedPath(candidate, oldPath, newPath) {
|
|
|
1133
1151
|
}
|
|
1134
1152
|
|
|
1135
1153
|
class WorkspaceDocumentState {
|
|
1136
|
-
sendNotification;
|
|
1137
|
-
clearDiagnostics;
|
|
1138
|
-
openDocuments = new Map;
|
|
1139
|
-
openByUri = new Map;
|
|
1140
|
-
openPromises = new Map;
|
|
1141
|
-
now;
|
|
1142
|
-
versionlessPublishQuiescenceMs;
|
|
1143
1154
|
constructor(sendNotification, clearDiagnostics, options = {}) {
|
|
1144
1155
|
this.sendNotification = sendNotification;
|
|
1145
1156
|
this.clearDiagnostics = clearDiagnostics;
|
|
1157
|
+
this.openDocuments = new Map;
|
|
1158
|
+
this.openByUri = new Map;
|
|
1159
|
+
this.openPromises = new Map;
|
|
1146
1160
|
this.now = options.now ?? (() => Date.now());
|
|
1147
1161
|
this.versionlessPublishQuiescenceMs = options.versionlessPublishQuiescenceMs ?? DEFAULT_VERSIONLESS_PUBLISH_QUIESCENCE_MS;
|
|
1148
1162
|
}
|
|
@@ -1406,13 +1420,11 @@ import { dirname, isAbsolute, relative as relative2, resolve as resolve2 } from
|
|
|
1406
1420
|
import { fileURLToPath } from "node:url";
|
|
1407
1421
|
|
|
1408
1422
|
class WorkspaceEditPathError extends Error {
|
|
1409
|
-
path;
|
|
1410
|
-
detail;
|
|
1411
|
-
name = "WorkspaceEditPathError";
|
|
1412
1423
|
constructor(path, detail) {
|
|
1413
1424
|
super(`${detail}: ${path}`);
|
|
1414
1425
|
this.path = path;
|
|
1415
1426
|
this.detail = detail;
|
|
1427
|
+
this.name = "WorkspaceEditPathError";
|
|
1416
1428
|
}
|
|
1417
1429
|
}
|
|
1418
1430
|
function isPathInsideWorkspace(filePath, workspaceRoot) {
|
|
@@ -1704,13 +1716,11 @@ function canonicalFingerprint(operations) {
|
|
|
1704
1716
|
|
|
1705
1717
|
// ../lsp-core/src/lsp/workspace-edit-types.ts
|
|
1706
1718
|
class WorkspaceEditValidationError extends Error {
|
|
1707
|
-
changeIndex;
|
|
1708
|
-
detail;
|
|
1709
|
-
name = "WorkspaceEditValidationError";
|
|
1710
1719
|
constructor(changeIndex, detail) {
|
|
1711
1720
|
super(`change ${changeIndex}: ${detail}`);
|
|
1712
1721
|
this.changeIndex = changeIndex;
|
|
1713
1722
|
this.detail = detail;
|
|
1723
|
+
this.name = "WorkspaceEditValidationError";
|
|
1714
1724
|
}
|
|
1715
1725
|
}
|
|
1716
1726
|
|
|
@@ -2208,10 +2218,9 @@ function simulateDelete(operation, virtual) {
|
|
|
2208
2218
|
import { existsSync as existsSync4, lstatSync as lstatSync3, readdirSync as readdirSync2 } from "node:fs";
|
|
2209
2219
|
import { dirname as dirname3, resolve as resolve4 } from "node:path";
|
|
2210
2220
|
class WorkspaceSnapshotBuilder {
|
|
2211
|
-
workspaceRoot;
|
|
2212
|
-
snapshots = new Map;
|
|
2213
2221
|
constructor(workspaceRoot) {
|
|
2214
2222
|
this.workspaceRoot = workspaceRoot;
|
|
2223
|
+
this.snapshots = new Map;
|
|
2215
2224
|
}
|
|
2216
2225
|
build(operations) {
|
|
2217
2226
|
this.add(this.workspaceRoot, false);
|
|
@@ -2255,8 +2264,10 @@ function snapshotOperations(operations, workspaceRoot) {
|
|
|
2255
2264
|
|
|
2256
2265
|
// ../lsp-core/src/lsp/workspace-edit-plan.ts
|
|
2257
2266
|
class PlanPathIndex {
|
|
2258
|
-
|
|
2259
|
-
|
|
2267
|
+
constructor() {
|
|
2268
|
+
this.firstChangeByPath = new Map;
|
|
2269
|
+
this.reportedPathByCanonical = new Map;
|
|
2270
|
+
}
|
|
2260
2271
|
build(operations) {
|
|
2261
2272
|
for (const operation of operations) {
|
|
2262
2273
|
switch (operation.kind) {
|
|
@@ -2345,14 +2356,11 @@ function isRecord3(value) {
|
|
|
2345
2356
|
}
|
|
2346
2357
|
|
|
2347
2358
|
class WorkspaceMutationController {
|
|
2348
|
-
workspaceRoot;
|
|
2349
|
-
documents;
|
|
2350
|
-
activeLease = null;
|
|
2351
|
-
nextLeaseId = 1;
|
|
2352
|
-
io;
|
|
2353
2359
|
constructor(workspaceRoot, documents) {
|
|
2354
2360
|
this.workspaceRoot = workspaceRoot;
|
|
2355
2361
|
this.documents = documents;
|
|
2362
|
+
this.activeLease = null;
|
|
2363
|
+
this.nextLeaseId = 1;
|
|
2356
2364
|
}
|
|
2357
2365
|
setIo(io) {
|
|
2358
2366
|
this.io = io;
|
|
@@ -2465,12 +2473,9 @@ var DIAGNOSTICS_FRESHNESS_TIMEOUT_MS = 3000;
|
|
|
2465
2473
|
var VERSIONLESS_PUBLISH_QUIESCENCE_MS = 250;
|
|
2466
2474
|
|
|
2467
2475
|
class LspClient extends LspClientConnection {
|
|
2468
|
-
diagnosticPullErrors = [];
|
|
2469
|
-
documents;
|
|
2470
|
-
workspaceMutations;
|
|
2471
|
-
diagnosticsFreshnessTimeoutMs;
|
|
2472
2476
|
constructor(root, server, options = {}) {
|
|
2473
2477
|
super(root, server, options);
|
|
2478
|
+
this.diagnosticPullErrors = [];
|
|
2474
2479
|
this.diagnosticsFreshnessTimeoutMs = options.diagnosticsFreshnessTimeoutMs ?? DIAGNOSTICS_FRESHNESS_TIMEOUT_MS;
|
|
2475
2480
|
this.documents = new WorkspaceDocumentState((method, params) => this.sendNotification(method, params), (uri) => this.diagnosticsStore.delete(uri), {
|
|
2476
2481
|
versionlessPublishQuiescenceMs: options.versionlessPublishQuiescenceMs ?? VERSIONLESS_PUBLISH_QUIESCENCE_MS
|
|
@@ -2525,6 +2530,18 @@ class LspClient extends LspClientConnection {
|
|
|
2525
2530
|
textDocument: { uri: pathToFileURL3(absPath).href }
|
|
2526
2531
|
}, options);
|
|
2527
2532
|
}
|
|
2533
|
+
async formatDocument(filePath, options, signal) {
|
|
2534
|
+
if (!this.isDocumentFormattingSupported())
|
|
2535
|
+
return null;
|
|
2536
|
+
const absPath = this.resolveWorkspacePath(filePath);
|
|
2537
|
+
await this.openFile(absPath);
|
|
2538
|
+
const requestOptions = signal === undefined ? {} : { signal };
|
|
2539
|
+
const edits = await this.sendRequest("textDocument/formatting", {
|
|
2540
|
+
textDocument: { uri: pathToFileURL3(absPath).href },
|
|
2541
|
+
options
|
|
2542
|
+
}, requestOptions);
|
|
2543
|
+
return edits ?? [];
|
|
2544
|
+
}
|
|
2528
2545
|
async workspaceSymbols(query, signal) {
|
|
2529
2546
|
const options = signal === undefined ? {} : { signal };
|
|
2530
2547
|
return this.sendRequest("workspace/symbol", { query }, options);
|
|
@@ -2770,18 +2787,16 @@ function awaitWithSignal(promise, signal) {
|
|
|
2770
2787
|
}
|
|
2771
2788
|
|
|
2772
2789
|
class LspManager {
|
|
2773
|
-
clients = new Map;
|
|
2774
|
-
reaperHandle = null;
|
|
2775
|
-
signalDisposer = null;
|
|
2776
|
-
disposed = false;
|
|
2777
|
-
idleTimeoutMs;
|
|
2778
|
-
initTimeoutMs;
|
|
2779
|
-
reaperIntervalMs;
|
|
2780
|
-
clientFactory;
|
|
2781
|
-
now;
|
|
2782
2790
|
constructor(options = {}) {
|
|
2791
|
+
this.clients = new Map;
|
|
2792
|
+
this.pendingStops = new Map;
|
|
2793
|
+
this.respawnBudgets = new Map;
|
|
2794
|
+
this.reaperHandle = null;
|
|
2795
|
+
this.signalDisposer = null;
|
|
2796
|
+
this.disposed = false;
|
|
2783
2797
|
this.idleTimeoutMs = options.idleTimeoutMs ?? IDLE_TIMEOUT_MS;
|
|
2784
2798
|
this.initTimeoutMs = options.initTimeoutMs ?? INIT_TIMEOUT_MS;
|
|
2799
|
+
this.maxResidentClients = options.maxResidentClients ?? MAX_RESIDENT_CLIENTS;
|
|
2785
2800
|
this.reaperIntervalMs = options.reaperIntervalMs ?? REAPER_INTERVAL_MS;
|
|
2786
2801
|
this.clientFactory = options.clientFactory ?? ((root, server) => new LspClient(root, server));
|
|
2787
2802
|
this.now = options.now ?? (() => Date.now());
|
|
@@ -2801,24 +2816,79 @@ class LspManager {
|
|
|
2801
2816
|
getKey(root, serverId) {
|
|
2802
2817
|
return `${root}::${serverId}`;
|
|
2803
2818
|
}
|
|
2819
|
+
tombstoneStop(key, client) {
|
|
2820
|
+
const stop = stopClientBestEffort(client);
|
|
2821
|
+
this.pendingStops.set(key, stop);
|
|
2822
|
+
stop.finally(() => {
|
|
2823
|
+
if (this.pendingStops.get(key) === stop) {
|
|
2824
|
+
this.pendingStops.delete(key);
|
|
2825
|
+
}
|
|
2826
|
+
});
|
|
2827
|
+
return stop;
|
|
2828
|
+
}
|
|
2829
|
+
recordDeadGeneration(key) {
|
|
2830
|
+
let budget = this.respawnBudgets.get(key);
|
|
2831
|
+
if (budget === undefined) {
|
|
2832
|
+
budget = { deadGenerations: 0, exhaustedAt: null };
|
|
2833
|
+
this.respawnBudgets.set(key, budget);
|
|
2834
|
+
}
|
|
2835
|
+
budget.deadGenerations += 1;
|
|
2836
|
+
}
|
|
2837
|
+
markHealthyGeneration(key) {
|
|
2838
|
+
this.respawnBudgets.delete(key);
|
|
2839
|
+
}
|
|
2840
|
+
ensureRespawnAllowed(key, root, serverId) {
|
|
2841
|
+
const budget = this.respawnBudgets.get(key);
|
|
2842
|
+
if (budget === undefined || budget.deadGenerations < CLIENT_RESPAWN_RETRY_LIMIT)
|
|
2843
|
+
return;
|
|
2844
|
+
if (budget.exhaustedAt === null) {
|
|
2845
|
+
budget.exhaustedAt = this.now();
|
|
2846
|
+
throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
|
|
2847
|
+
}
|
|
2848
|
+
if (this.now() - budget.exhaustedAt < CLIENT_RESPAWN_COOLDOWN_MS) {
|
|
2849
|
+
throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
|
|
2850
|
+
}
|
|
2851
|
+
budget.deadGenerations = 0;
|
|
2852
|
+
budget.exhaustedAt = null;
|
|
2853
|
+
}
|
|
2804
2854
|
reapStale() {
|
|
2805
2855
|
const t = this.now();
|
|
2806
2856
|
for (const [key, managed] of this.clients) {
|
|
2807
2857
|
if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
|
|
2808
|
-
stopClientBestEffort(managed.client);
|
|
2809
2858
|
this.clients.delete(key);
|
|
2859
|
+
this.tombstoneStop(key, managed.client);
|
|
2810
2860
|
continue;
|
|
2811
2861
|
}
|
|
2812
2862
|
if (!managed.isInitializing && managed.refCount === 0 && managed.pendingWaiters === 0 && t - managed.lastUsedAt > this.idleTimeoutMs) {
|
|
2813
|
-
stopClientBestEffort(managed.client);
|
|
2814
2863
|
this.clients.delete(key);
|
|
2864
|
+
this.tombstoneStop(key, managed.client);
|
|
2815
2865
|
}
|
|
2816
2866
|
}
|
|
2817
2867
|
}
|
|
2868
|
+
evictForAdmission() {
|
|
2869
|
+
while (this.clients.size >= this.maxResidentClients) {
|
|
2870
|
+
const victim = this.leastRecentlyUsedIdleClient();
|
|
2871
|
+
if (!victim)
|
|
2872
|
+
return;
|
|
2873
|
+
this.clients.delete(victim.key);
|
|
2874
|
+
this.tombstoneStop(victim.key, victim.managed.client);
|
|
2875
|
+
}
|
|
2876
|
+
}
|
|
2877
|
+
leastRecentlyUsedIdleClient() {
|
|
2878
|
+
let candidate = null;
|
|
2879
|
+
for (const [key, managed] of this.clients) {
|
|
2880
|
+
if (managed.refCount > 0 || managed.pendingWaiters > 0 || managed.isInitializing)
|
|
2881
|
+
continue;
|
|
2882
|
+
if (candidate === null || managed.lastUsedAt < candidate.managed.lastUsedAt) {
|
|
2883
|
+
candidate = { key, managed };
|
|
2884
|
+
}
|
|
2885
|
+
}
|
|
2886
|
+
return candidate;
|
|
2887
|
+
}
|
|
2818
2888
|
async tryDeleteIfOrphaned(key, managed) {
|
|
2819
2889
|
if (managed.refCount === 0 && managed.pendingWaiters === 0 && !managed.isInitializing && this.clients.get(key) === managed) {
|
|
2820
2890
|
this.clients.delete(key);
|
|
2821
|
-
await
|
|
2891
|
+
await this.tombstoneStop(key, managed.client);
|
|
2822
2892
|
}
|
|
2823
2893
|
}
|
|
2824
2894
|
async getClient(root, server, signal) {
|
|
@@ -2827,12 +2897,22 @@ class LspManager {
|
|
|
2827
2897
|
}
|
|
2828
2898
|
signal?.throwIfAborted();
|
|
2829
2899
|
const key = this.getKey(root, server.id);
|
|
2900
|
+
for (;; ) {
|
|
2901
|
+
const pendingStop = this.pendingStops.get(key);
|
|
2902
|
+
if (pendingStop === undefined)
|
|
2903
|
+
break;
|
|
2904
|
+
await awaitWithSignal(pendingStop, signal);
|
|
2905
|
+
signal?.throwIfAborted();
|
|
2906
|
+
}
|
|
2907
|
+
if (this.disposed) {
|
|
2908
|
+
throw new Error("LspManager has been disposed");
|
|
2909
|
+
}
|
|
2830
2910
|
let managed = this.clients.get(key);
|
|
2831
2911
|
if (managed) {
|
|
2832
2912
|
const t = this.now();
|
|
2833
2913
|
if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
|
|
2834
|
-
await stopClientBestEffort(managed.client);
|
|
2835
2914
|
this.clients.delete(key);
|
|
2915
|
+
await this.tombstoneStop(key, managed.client);
|
|
2836
2916
|
managed = undefined;
|
|
2837
2917
|
}
|
|
2838
2918
|
}
|
|
@@ -2853,14 +2933,20 @@ class LspManager {
|
|
|
2853
2933
|
signal.throwIfAborted();
|
|
2854
2934
|
}
|
|
2855
2935
|
if (!managed.client.isAlive()) {
|
|
2856
|
-
|
|
2857
|
-
this.clients.
|
|
2936
|
+
this.recordDeadGeneration(key);
|
|
2937
|
+
if (this.clients.get(key) === managed) {
|
|
2938
|
+
this.clients.delete(key);
|
|
2939
|
+
}
|
|
2940
|
+
await this.tombstoneStop(key, managed.client);
|
|
2858
2941
|
return this.getClient(root, server, signal);
|
|
2859
2942
|
}
|
|
2943
|
+
this.markHealthyGeneration(key);
|
|
2860
2944
|
managed.refCount++;
|
|
2861
2945
|
managed.lastUsedAt = this.now();
|
|
2862
2946
|
return managed.client;
|
|
2863
2947
|
}
|
|
2948
|
+
this.evictForAdmission();
|
|
2949
|
+
this.ensureRespawnAllowed(key, root, server.id);
|
|
2864
2950
|
const client = this.clientFactory(root, server);
|
|
2865
2951
|
const initStartedAt = this.now();
|
|
2866
2952
|
const initPromise = (async () => {
|
|
@@ -2884,7 +2970,7 @@ class LspManager {
|
|
|
2884
2970
|
if (this.clients.get(key) === newManaged) {
|
|
2885
2971
|
this.clients.delete(key);
|
|
2886
2972
|
}
|
|
2887
|
-
await
|
|
2973
|
+
await this.tombstoneStop(key, client);
|
|
2888
2974
|
throw err;
|
|
2889
2975
|
}
|
|
2890
2976
|
newManaged.pendingWaiters--;
|
|
@@ -2895,6 +2981,15 @@ class LspManager {
|
|
|
2895
2981
|
await this.tryDeleteIfOrphaned(key, newManaged);
|
|
2896
2982
|
signal.throwIfAborted();
|
|
2897
2983
|
}
|
|
2984
|
+
if (!client.isAlive()) {
|
|
2985
|
+
this.recordDeadGeneration(key);
|
|
2986
|
+
if (this.clients.get(key) === newManaged) {
|
|
2987
|
+
this.clients.delete(key);
|
|
2988
|
+
}
|
|
2989
|
+
await this.tombstoneStop(key, client);
|
|
2990
|
+
return this.getClient(root, server, signal);
|
|
2991
|
+
}
|
|
2992
|
+
this.markHealthyGeneration(key);
|
|
2898
2993
|
newManaged.refCount++;
|
|
2899
2994
|
newManaged.lastUsedAt = this.now();
|
|
2900
2995
|
return client;
|
|
@@ -2915,14 +3010,20 @@ class LspManager {
|
|
|
2915
3010
|
if (client && managed.client !== client)
|
|
2916
3011
|
return;
|
|
2917
3012
|
this.clients.delete(key);
|
|
2918
|
-
|
|
3013
|
+
this.tombstoneStop(key, managed.client);
|
|
2919
3014
|
}
|
|
2920
3015
|
warmupClient(root, server) {
|
|
2921
3016
|
if (this.disposed)
|
|
2922
3017
|
return;
|
|
2923
3018
|
const key = this.getKey(root, server.id);
|
|
2924
|
-
if (this.clients.has(key))
|
|
3019
|
+
if (this.clients.has(key) || this.pendingStops.has(key))
|
|
2925
3020
|
return;
|
|
3021
|
+
this.evictForAdmission();
|
|
3022
|
+
try {
|
|
3023
|
+
this.ensureRespawnAllowed(key, root, server.id);
|
|
3024
|
+
} catch {
|
|
3025
|
+
return;
|
|
3026
|
+
}
|
|
2926
3027
|
const client = this.clientFactory(root, server);
|
|
2927
3028
|
const initStartedAt = this.now();
|
|
2928
3029
|
const initPromise = (async () => {
|
|
@@ -2948,7 +3049,7 @@ class LspManager {
|
|
|
2948
3049
|
if (this.clients.get(key) === managed) {
|
|
2949
3050
|
this.clients.delete(key);
|
|
2950
3051
|
}
|
|
2951
|
-
|
|
3052
|
+
this.tombstoneStop(key, client);
|
|
2952
3053
|
});
|
|
2953
3054
|
}
|
|
2954
3055
|
isServerInitializing(root, serverId) {
|
|
@@ -2992,8 +3093,11 @@ class LspManager {
|
|
|
2992
3093
|
for (const managed of this.clients.values()) {
|
|
2993
3094
|
stopPromises.push(stopClientBestEffort(managed.client));
|
|
2994
3095
|
}
|
|
3096
|
+
const tombstonedStops = [...this.pendingStops.values()];
|
|
2995
3097
|
this.clients.clear();
|
|
2996
|
-
|
|
3098
|
+
this.respawnBudgets.clear();
|
|
3099
|
+
await Promise.allSettled([...stopPromises, ...tombstonedStops]);
|
|
3100
|
+
this.pendingStops.clear();
|
|
2997
3101
|
}
|
|
2998
3102
|
}
|
|
2999
3103
|
var _defaultInstance = null;
|
|
@@ -3013,7 +3117,7 @@ async function disposeDefaultLspManager() {
|
|
|
3013
3117
|
// src/daemon-client.ts
|
|
3014
3118
|
import { connect } from "node:net";
|
|
3015
3119
|
import { homedir as homedir3 } from "node:os";
|
|
3016
|
-
import { join as
|
|
3120
|
+
import { join as join8 } from "node:path";
|
|
3017
3121
|
|
|
3018
3122
|
// ../lsp-core/src/request-context.ts
|
|
3019
3123
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
@@ -3022,18 +3126,17 @@ import { homedir } from "node:os";
|
|
|
3022
3126
|
import { basename as basename2, delimiter as delimiter2, dirname as dirname4, isAbsolute as isAbsolute2, join as join2, relative as relative4, resolve as resolve6 } from "node:path";
|
|
3023
3127
|
|
|
3024
3128
|
class LspRequestContextParseError extends Error {
|
|
3025
|
-
code;
|
|
3026
|
-
name = "LspRequestContextParseError";
|
|
3027
3129
|
constructor(code, message) {
|
|
3028
3130
|
super(message);
|
|
3029
3131
|
this.code = code;
|
|
3132
|
+
this.name = "LspRequestContextParseError";
|
|
3030
3133
|
}
|
|
3031
3134
|
}
|
|
3032
3135
|
|
|
3033
3136
|
class LspRequestContextUnavailableError extends Error {
|
|
3034
|
-
name = "LspRequestContextUnavailableError";
|
|
3035
3137
|
constructor() {
|
|
3036
3138
|
super("LSP request context is required. Standalone MCP startup must install one with runWithRequestContext(createStandaloneMcpRequestContext()).");
|
|
3139
|
+
this.name = "LspRequestContextUnavailableError";
|
|
3037
3140
|
}
|
|
3038
3141
|
}
|
|
3039
3142
|
var storage = new AsyncLocalStorage;
|
|
@@ -3053,7 +3156,7 @@ function contextCwd() {
|
|
|
3053
3156
|
}
|
|
3054
3157
|
function createStandaloneMcpRequestContext(input = {}) {
|
|
3055
3158
|
const env = input.env ?? process.env;
|
|
3056
|
-
const cwd = canonicalCwd(input.cwd ?? process.cwd());
|
|
3159
|
+
const cwd = canonicalCwd(input.cwd ?? env["LSP_TOOLS_MCP_CWD"] ?? process.cwd());
|
|
3057
3160
|
const home = input.homeDir ?? homedir();
|
|
3058
3161
|
const projectConfigPaths = translateProjectConfigEnv(env["LSP_TOOLS_MCP_PROJECT_CONFIG"], cwd);
|
|
3059
3162
|
const userConfigPath = translateHomeConfigEnv(env["LSP_TOOLS_MCP_USER_CONFIG"], home, ".codex/lsp-client.json");
|
|
@@ -3191,7 +3294,6 @@ function isPlainRecord(value) {
|
|
|
3191
3294
|
|
|
3192
3295
|
// src/daemon-request-error.ts
|
|
3193
3296
|
class DaemonRequestError extends Error {
|
|
3194
|
-
requestWritten;
|
|
3195
3297
|
constructor(message, requestWritten) {
|
|
3196
3298
|
super(message);
|
|
3197
3299
|
this.name = "DaemonRequestError";
|
|
@@ -3214,7 +3316,6 @@ class DaemonRequestCancelledError extends DaemonRequestError {
|
|
|
3214
3316
|
}
|
|
3215
3317
|
|
|
3216
3318
|
class DaemonRequestTimedOutError extends DaemonRequestError {
|
|
3217
|
-
timeoutMs;
|
|
3218
3319
|
constructor(requestWritten, timeoutMs) {
|
|
3219
3320
|
super("daemon request timed out", requestWritten);
|
|
3220
3321
|
this.name = "DaemonRequestTimedOutError";
|
|
@@ -3293,14 +3394,12 @@ var PROTOCOL_ERROR_CODE = -32002;
|
|
|
3293
3394
|
var AUTH_TOKEN_BYTES = 32;
|
|
3294
3395
|
|
|
3295
3396
|
class UnsafePrivateDirectoryError extends Error {
|
|
3296
|
-
path;
|
|
3297
|
-
reason;
|
|
3298
|
-
name = "UnsafePrivateDirectoryError";
|
|
3299
|
-
code = "unsafe_private_directory";
|
|
3300
3397
|
constructor(path, reason) {
|
|
3301
3398
|
super(`unsafe private directory ${path}: ${reason}`);
|
|
3302
3399
|
this.path = path;
|
|
3303
3400
|
this.reason = reason;
|
|
3401
|
+
this.name = "UnsafePrivateDirectoryError";
|
|
3402
|
+
this.code = "unsafe_private_directory";
|
|
3304
3403
|
}
|
|
3305
3404
|
}
|
|
3306
3405
|
function authEnvelope(token) {
|
|
@@ -3484,20 +3583,18 @@ var OMO_LSP_DAEMON_VERSION = "OMO_LSP_DAEMON_VERSION";
|
|
|
3484
3583
|
var DAEMON_VERSION_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._+-]{0,127}$/;
|
|
3485
3584
|
|
|
3486
3585
|
class InvalidRuntimeOverrideError extends Error {
|
|
3487
|
-
code = "invalid_runtime_override";
|
|
3488
|
-
reason;
|
|
3489
3586
|
constructor(reason, message) {
|
|
3490
3587
|
super(message);
|
|
3588
|
+
this.code = "invalid_runtime_override";
|
|
3491
3589
|
this.name = "InvalidRuntimeOverrideError";
|
|
3492
3590
|
this.reason = reason;
|
|
3493
3591
|
}
|
|
3494
3592
|
}
|
|
3495
3593
|
|
|
3496
3594
|
class InvalidDaemonVersionError extends Error {
|
|
3497
|
-
code = "invalid_daemon_version";
|
|
3498
|
-
version;
|
|
3499
3595
|
constructor(version) {
|
|
3500
3596
|
super("LSP daemon version must match [A-Za-z0-9][A-Za-z0-9._+-]{0,127}");
|
|
3597
|
+
this.code = "invalid_daemon_version";
|
|
3501
3598
|
this.name = "InvalidDaemonVersionError";
|
|
3502
3599
|
this.version = version;
|
|
3503
3600
|
}
|
|
@@ -3543,10 +3640,9 @@ var requireFromHere = createRequire(import.meta.url);
|
|
|
3543
3640
|
var MAX_SOCKET_PATH_LENGTH = 100;
|
|
3544
3641
|
|
|
3545
3642
|
class InvalidDaemonDirectoryError extends Error {
|
|
3546
|
-
code = "invalid_daemon_directory";
|
|
3547
|
-
directory;
|
|
3548
3643
|
constructor(directory) {
|
|
3549
3644
|
super(`${OMO_LSP_DAEMON_DIR} must be an absolute path`);
|
|
3645
|
+
this.code = "invalid_daemon_directory";
|
|
3550
3646
|
this.name = "InvalidDaemonDirectoryError";
|
|
3551
3647
|
this.directory = directory;
|
|
3552
3648
|
}
|
|
@@ -3741,7 +3837,8 @@ function spawnDaemonProcess(paths) {
|
|
|
3741
3837
|
try {
|
|
3742
3838
|
const child = spawn2(resolveDaemonNodeExecutable(), [paths.cliPath, "daemon"], {
|
|
3743
3839
|
detached: true,
|
|
3744
|
-
stdio: ["ignore", logFd, logFd]
|
|
3840
|
+
stdio: ["ignore", logFd, logFd],
|
|
3841
|
+
windowsHide: true
|
|
3745
3842
|
});
|
|
3746
3843
|
child.once("spawn", () => closeSync2(logFd));
|
|
3747
3844
|
child.once("error", (error) => {
|
|
@@ -4022,6 +4119,7 @@ async function runJsonRpcStdioServer(config) {
|
|
|
4022
4119
|
const idleTimer = createIdleTimer(idleTimeoutMs, log, () => {
|
|
4023
4120
|
isClosed = true;
|
|
4024
4121
|
config.onIdleTimeout?.();
|
|
4122
|
+
config.input.destroy();
|
|
4025
4123
|
});
|
|
4026
4124
|
const watchdog = createParentWatchdog(config.parentWatchdog, (parentPid, pollIntervalMs) => {
|
|
4027
4125
|
isClosed = true;
|
|
@@ -4118,7 +4216,11 @@ function createParentWatchdog(config, onDeadParent) {
|
|
|
4118
4216
|
const probeAlive = config.probeAlive ?? isProcessAlive;
|
|
4119
4217
|
let fired = false;
|
|
4120
4218
|
const timer = setInterval(() => {
|
|
4121
|
-
if (fired
|
|
4219
|
+
if (fired)
|
|
4220
|
+
return;
|
|
4221
|
+
const alive = probeAlive(parentPid);
|
|
4222
|
+
config.onPoll?.(alive);
|
|
4223
|
+
if (alive)
|
|
4122
4224
|
return;
|
|
4123
4225
|
fired = true;
|
|
4124
4226
|
onDeadParent(parentPid, pollIntervalMs);
|
|
@@ -4153,60 +4255,55 @@ function createIdleTimer(idleTimeoutMs, log, onTimeout) {
|
|
|
4153
4255
|
};
|
|
4154
4256
|
}
|
|
4155
4257
|
// ../lsp-core/src/lsp/client-wrapper.ts
|
|
4156
|
-
import { existsSync as
|
|
4157
|
-
import { dirname as
|
|
4258
|
+
import { existsSync as existsSync11, realpathSync as realpathSync5, statSync as statSync4 } from "node:fs";
|
|
4259
|
+
import { basename as basename3, dirname as dirname10, join as join5, resolve as resolve8 } from "node:path";
|
|
4158
4260
|
|
|
4159
|
-
// ../lsp-core/src/lsp/
|
|
4160
|
-
import { existsSync as existsSync7,
|
|
4161
|
-
import { dirname as dirname7 } from "node:path";
|
|
4162
|
-
|
|
4163
|
-
|
|
4164
|
-
|
|
4165
|
-
|
|
4166
|
-
|
|
4167
|
-
|
|
4168
|
-
|
|
4169
|
-
|
|
4170
|
-
|
|
4171
|
-
|
|
4172
|
-
|
|
4173
|
-
|
|
4261
|
+
// ../lsp-core/src/lsp/outside-context-workspace.ts
|
|
4262
|
+
import { existsSync as existsSync7, realpathSync as realpathSync4 } from "node:fs";
|
|
4263
|
+
import { dirname as dirname7, join as join3 } from "node:path";
|
|
4264
|
+
|
|
4265
|
+
// ../lsp-core/src/lsp/workspace-markers.ts
|
|
4266
|
+
var GIT_WORKSPACE_MARKER = ".git";
|
|
4267
|
+
var PROJECT_WORKSPACE_MARKERS = [
|
|
4268
|
+
"package.json",
|
|
4269
|
+
"pyproject.toml",
|
|
4270
|
+
"Cargo.toml",
|
|
4271
|
+
"go.mod",
|
|
4272
|
+
"pom.xml",
|
|
4273
|
+
"build.gradle"
|
|
4274
|
+
];
|
|
4275
|
+
var WORKSPACE_MARKERS = [GIT_WORKSPACE_MARKER, ...PROJECT_WORKSPACE_MARKERS];
|
|
4276
|
+
|
|
4277
|
+
// ../lsp-core/src/lsp/outside-context-workspace.ts
|
|
4278
|
+
function findWorkspaceRootOutsideContext(directory) {
|
|
4279
|
+
const marked = nearestMarkedAncestor(directory);
|
|
4280
|
+
if (marked !== undefined)
|
|
4281
|
+
return marked;
|
|
4282
|
+
return realpathSync4(nearestExistingAncestor(directory));
|
|
4283
|
+
}
|
|
4284
|
+
function nearestMarkedAncestor(directory) {
|
|
4285
|
+
let current = directory;
|
|
4286
|
+
for (;; ) {
|
|
4287
|
+
if (existsSync7(current) && WORKSPACE_MARKERS.some((marker) => existsSync7(join3(current, marker)))) {
|
|
4288
|
+
return realpathSync4(current);
|
|
4289
|
+
}
|
|
4290
|
+
const parent = dirname7(current);
|
|
4291
|
+
if (parent === current)
|
|
4292
|
+
return;
|
|
4293
|
+
current = parent;
|
|
4174
4294
|
}
|
|
4175
4295
|
}
|
|
4176
|
-
function
|
|
4177
|
-
|
|
4178
|
-
|
|
4179
|
-
|
|
4180
|
-
|
|
4181
|
-
|
|
4182
|
-
|
|
4183
|
-
}
|
|
4184
|
-
|
|
4185
|
-
return value === "declined" || value === "allowed";
|
|
4186
|
-
}
|
|
4187
|
-
function writeInstallDecisions(decisions) {
|
|
4188
|
-
const path2 = getInstallDecisionsPath();
|
|
4189
|
-
mkdirSync3(dirname7(path2), { recursive: true });
|
|
4190
|
-
const tmpPath = `${path2}.tmp`;
|
|
4191
|
-
writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
|
|
4192
|
-
`, "utf8");
|
|
4193
|
-
renameSync2(tmpPath, path2);
|
|
4194
|
-
}
|
|
4195
|
-
function isInstallDecisions(value) {
|
|
4196
|
-
return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
|
|
4197
|
-
}
|
|
4198
|
-
function isInstallDecisionRecord(value) {
|
|
4199
|
-
if (!isRecord5(value))
|
|
4200
|
-
return false;
|
|
4201
|
-
return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
|
|
4202
|
-
}
|
|
4203
|
-
function isRecord5(value) {
|
|
4204
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4296
|
+
function nearestExistingAncestor(directory) {
|
|
4297
|
+
let current = directory;
|
|
4298
|
+
while (!existsSync7(current)) {
|
|
4299
|
+
const parent = dirname7(current);
|
|
4300
|
+
if (parent === current)
|
|
4301
|
+
return current;
|
|
4302
|
+
current = parent;
|
|
4303
|
+
}
|
|
4304
|
+
return current;
|
|
4205
4305
|
}
|
|
4206
4306
|
|
|
4207
|
-
// ../lsp-core/src/lsp/config-loader.ts
|
|
4208
|
-
import { existsSync as existsSync8, readFileSync as readFileSync5 } from "node:fs";
|
|
4209
|
-
|
|
4210
4307
|
// ../lsp-core/src/lsp/server-definitions.ts
|
|
4211
4308
|
var LSP_INSTALL_HINTS = {
|
|
4212
4309
|
typescript: "npm install -g typescript-language-server typescript",
|
|
@@ -4252,6 +4349,26 @@ var LSP_INSTALL_HINTS = {
|
|
|
4252
4349
|
julials: `julia -e 'using Pkg; Pkg.add("LanguageServer")'`,
|
|
4253
4350
|
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"
|
|
4254
4351
|
};
|
|
4352
|
+
var LSP_LOCAL_INSTALL_HINTS = {
|
|
4353
|
+
typescript: "bun add -d typescript-language-server typescript",
|
|
4354
|
+
vue: "bun add -d @vue/language-server",
|
|
4355
|
+
eslint: "bun add -d vscode-langservers-extracted",
|
|
4356
|
+
oxlint: "bun add -d oxlint",
|
|
4357
|
+
biome: "bun add -d @biomejs/biome",
|
|
4358
|
+
svelte: "bun add -d svelte-language-server",
|
|
4359
|
+
astro: "bun add -d @astrojs/language-server",
|
|
4360
|
+
bash: "bun add -d bash-language-server",
|
|
4361
|
+
"bash-ls": "bun add -d bash-language-server",
|
|
4362
|
+
"yaml-ls": "bun add -d yaml-language-server",
|
|
4363
|
+
php: "bun add -d intelephense",
|
|
4364
|
+
prisma: "bun add -d prisma",
|
|
4365
|
+
dockerfile: "bun add -d dockerfile-language-server-nodejs",
|
|
4366
|
+
pyright: "uv add --dev pyright",
|
|
4367
|
+
basedpyright: "uv add --dev basedpyright",
|
|
4368
|
+
ruff: "uv add --dev ruff",
|
|
4369
|
+
ty: "uv add --dev ty",
|
|
4370
|
+
"ruby-lsp": "bundle add ruby-lsp --group development"
|
|
4371
|
+
};
|
|
4255
4372
|
var BUILTIN_SERVERS = {
|
|
4256
4373
|
typescript: {
|
|
4257
4374
|
command: ["typescript-language-server", "--stdio"],
|
|
@@ -4354,7 +4471,56 @@ var BUILTIN_SERVERS = {
|
|
|
4354
4471
|
}
|
|
4355
4472
|
};
|
|
4356
4473
|
|
|
4474
|
+
// ../lsp-core/src/lsp/server-install-state.ts
|
|
4475
|
+
import { existsSync as existsSync8, mkdirSync as mkdirSync3, readFileSync as readFileSync4, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
4476
|
+
import { dirname as dirname8 } from "node:path";
|
|
4477
|
+
function getInstallDecisionsPath() {
|
|
4478
|
+
return lspRequestContext().installDecisionsPath;
|
|
4479
|
+
}
|
|
4480
|
+
function loadInstallDecisions() {
|
|
4481
|
+
const path2 = getInstallDecisionsPath();
|
|
4482
|
+
if (!existsSync8(path2))
|
|
4483
|
+
return {};
|
|
4484
|
+
try {
|
|
4485
|
+
const parsed = JSON.parse(readFileSync4(path2, "utf8"));
|
|
4486
|
+
return isInstallDecisions(parsed) ? parsed : {};
|
|
4487
|
+
} catch {
|
|
4488
|
+
return {};
|
|
4489
|
+
}
|
|
4490
|
+
}
|
|
4491
|
+
function loadInstallDecision(serverId) {
|
|
4492
|
+
return loadInstallDecisions()[serverId];
|
|
4493
|
+
}
|
|
4494
|
+
function recordInstallDecision(serverId, decision, decidedAt = new Date().toISOString()) {
|
|
4495
|
+
const decisions = loadInstallDecisions();
|
|
4496
|
+
decisions[serverId] = { decision, decidedAt };
|
|
4497
|
+
writeInstallDecisions(decisions);
|
|
4498
|
+
}
|
|
4499
|
+
function isInstallDecision(value) {
|
|
4500
|
+
return value === "declined" || value === "allowed";
|
|
4501
|
+
}
|
|
4502
|
+
function writeInstallDecisions(decisions) {
|
|
4503
|
+
const path2 = getInstallDecisionsPath();
|
|
4504
|
+
mkdirSync3(dirname8(path2), { recursive: true });
|
|
4505
|
+
const tmpPath = `${path2}.tmp`;
|
|
4506
|
+
writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
|
|
4507
|
+
`, "utf8");
|
|
4508
|
+
renameSync2(tmpPath, path2);
|
|
4509
|
+
}
|
|
4510
|
+
function isInstallDecisions(value) {
|
|
4511
|
+
return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
|
|
4512
|
+
}
|
|
4513
|
+
function isInstallDecisionRecord(value) {
|
|
4514
|
+
if (!isRecord5(value))
|
|
4515
|
+
return false;
|
|
4516
|
+
return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
|
|
4517
|
+
}
|
|
4518
|
+
function isRecord5(value) {
|
|
4519
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4520
|
+
}
|
|
4521
|
+
|
|
4357
4522
|
// ../lsp-core/src/lsp/config-loader.ts
|
|
4523
|
+
import { existsSync as existsSync9, readFileSync as readFileSync5 } from "node:fs";
|
|
4358
4524
|
function getProjectConfigPaths() {
|
|
4359
4525
|
return lspRequestContext().projectConfigPaths;
|
|
4360
4526
|
}
|
|
@@ -4362,7 +4528,7 @@ function getUserConfigPath() {
|
|
|
4362
4528
|
return lspRequestContext().userConfigPath;
|
|
4363
4529
|
}
|
|
4364
4530
|
function loadJsonFile(path2) {
|
|
4365
|
-
if (!
|
|
4531
|
+
if (!existsSync9(path2))
|
|
4366
4532
|
return null;
|
|
4367
4533
|
try {
|
|
4368
4534
|
const parsed = JSON.parse(readFileSync5(path2, "utf-8"));
|
|
@@ -4550,54 +4716,155 @@ function getDisabledServerIds() {
|
|
|
4550
4716
|
}
|
|
4551
4717
|
|
|
4552
4718
|
// ../lsp-core/src/lsp/server-installation.ts
|
|
4553
|
-
import { existsSync as
|
|
4554
|
-
import { delimiter as delimiter3, join as
|
|
4555
|
-
|
|
4556
|
-
|
|
4557
|
-
|
|
4558
|
-
|
|
4559
|
-
|
|
4560
|
-
|
|
4561
|
-
|
|
4562
|
-
|
|
4563
|
-
|
|
4719
|
+
import { existsSync as existsSync10 } from "node:fs";
|
|
4720
|
+
import { delimiter as delimiter3, dirname as dirname9, isAbsolute as isAbsolute5, join as join4, resolve as resolve7 } from "node:path";
|
|
4721
|
+
var LOCAL_BIN_RULES = [
|
|
4722
|
+
{
|
|
4723
|
+
markers: ["package.json", "bun.lock", "bun.lockb", "package-lock.json", "yarn.lock", "pnpm-lock.yaml"],
|
|
4724
|
+
binDirs: [join4("node_modules", ".bin")]
|
|
4725
|
+
},
|
|
4726
|
+
{
|
|
4727
|
+
markers: [
|
|
4728
|
+
"pyproject.toml",
|
|
4729
|
+
"ty.toml",
|
|
4730
|
+
"requirements.txt",
|
|
4731
|
+
"setup.py",
|
|
4732
|
+
"setup.cfg",
|
|
4733
|
+
"Pipfile",
|
|
4734
|
+
"pyrightconfig.json",
|
|
4735
|
+
"ruff.toml",
|
|
4736
|
+
".ruff.toml"
|
|
4737
|
+
],
|
|
4738
|
+
binDirs: [
|
|
4739
|
+
join4(".venv", "bin"),
|
|
4740
|
+
join4(".venv", "Scripts"),
|
|
4741
|
+
join4("venv", "bin"),
|
|
4742
|
+
join4("venv", "Scripts"),
|
|
4743
|
+
join4(".env", "bin"),
|
|
4744
|
+
join4(".env", "Scripts")
|
|
4745
|
+
]
|
|
4746
|
+
},
|
|
4747
|
+
{
|
|
4748
|
+
markers: ["Gemfile", "Gemfile.lock"],
|
|
4749
|
+
binDirs: [join4("vendor", "bundle", "bin"), "bin"]
|
|
4750
|
+
},
|
|
4751
|
+
{
|
|
4752
|
+
markers: ["go.mod", "go.sum", "go.work"],
|
|
4753
|
+
binDirs: ["bin"]
|
|
4564
4754
|
}
|
|
4565
|
-
|
|
4566
|
-
|
|
4567
|
-
|
|
4568
|
-
|
|
4569
|
-
|
|
4570
|
-
|
|
4571
|
-
|
|
4572
|
-
|
|
4573
|
-
|
|
4755
|
+
];
|
|
4756
|
+
var resolutionCache = new Map;
|
|
4757
|
+
var probeCount = 0;
|
|
4758
|
+
function probe(path2) {
|
|
4759
|
+
probeCount += 1;
|
|
4760
|
+
return existsSync10(path2);
|
|
4761
|
+
}
|
|
4762
|
+
function executableSuffixes(platform, pathExt) {
|
|
4763
|
+
if (platform !== "win32")
|
|
4764
|
+
return [""];
|
|
4765
|
+
const configured = pathExt ?? process.env["PATHEXT"] ?? "";
|
|
4766
|
+
const systemExts = configured.split(";").filter((entry) => entry.length > 0).map((entry) => entry.toLowerCase());
|
|
4767
|
+
return [...new Set(["", ...systemExts, ".exe", ".cmd", ".bat", ".ps1"])];
|
|
4768
|
+
}
|
|
4769
|
+
function probeWithSuffixes(directory, command, suffixes) {
|
|
4770
|
+
for (const suffix of suffixes) {
|
|
4771
|
+
const candidate = join4(directory, command + suffix);
|
|
4772
|
+
if (probe(candidate))
|
|
4773
|
+
return candidate;
|
|
4774
|
+
}
|
|
4775
|
+
return null;
|
|
4776
|
+
}
|
|
4777
|
+
function resolveLocal(command, workingDirectory, suffixes, stopAt) {
|
|
4778
|
+
const boundary = stopAt === undefined ? undefined : resolve7(stopAt);
|
|
4779
|
+
let current = resolve7(workingDirectory);
|
|
4780
|
+
while (true) {
|
|
4781
|
+
for (const rule of LOCAL_BIN_RULES) {
|
|
4782
|
+
if (!rule.markers.some((marker) => probe(join4(current, marker))))
|
|
4783
|
+
continue;
|
|
4784
|
+
for (const binDir of rule.binDirs) {
|
|
4785
|
+
const found = probeWithSuffixes(join4(current, binDir), command, suffixes);
|
|
4786
|
+
if (found !== null)
|
|
4787
|
+
return found;
|
|
4788
|
+
}
|
|
4574
4789
|
}
|
|
4790
|
+
if (probe(join4(current, ".git")))
|
|
4791
|
+
return null;
|
|
4792
|
+
if (boundary !== undefined && current === boundary)
|
|
4793
|
+
return null;
|
|
4794
|
+
const parent = dirname9(current);
|
|
4795
|
+
if (parent === current)
|
|
4796
|
+
return null;
|
|
4797
|
+
current = parent;
|
|
4575
4798
|
}
|
|
4576
|
-
|
|
4577
|
-
|
|
4799
|
+
}
|
|
4800
|
+
function resolveFromPath(command, suffixes, platform, pathEnvOverride) {
|
|
4801
|
+
let pathEnv = pathEnvOverride ?? process.env["PATH"] ?? "";
|
|
4802
|
+
if (platform === "win32" && !pathEnv) {
|
|
4578
4803
|
pathEnv = process.env["Path"] ?? "";
|
|
4579
4804
|
}
|
|
4580
|
-
const
|
|
4581
|
-
|
|
4582
|
-
|
|
4583
|
-
|
|
4584
|
-
|
|
4585
|
-
|
|
4586
|
-
}
|
|
4805
|
+
for (const entry of pathEnv.split(delimiter3)) {
|
|
4806
|
+
if (entry.length === 0)
|
|
4807
|
+
continue;
|
|
4808
|
+
const found = probeWithSuffixes(entry, command, suffixes);
|
|
4809
|
+
if (found !== null)
|
|
4810
|
+
return found;
|
|
4587
4811
|
}
|
|
4588
|
-
|
|
4589
|
-
|
|
4590
|
-
|
|
4812
|
+
return null;
|
|
4813
|
+
}
|
|
4814
|
+
function resolveServerBinary(command, workingDirectory, options = {}) {
|
|
4815
|
+
if (command.length === 0)
|
|
4816
|
+
return null;
|
|
4817
|
+
const [cmd] = command;
|
|
4818
|
+
if (cmd === undefined || cmd.length === 0)
|
|
4819
|
+
return null;
|
|
4820
|
+
const platform = options.platform ?? process.platform;
|
|
4821
|
+
const suffixes = executableSuffixes(platform, options.pathExt);
|
|
4822
|
+
if (cmd.includes("/") || cmd.includes("\\")) {
|
|
4823
|
+
const explicit = isAbsolute5(cmd) ? cmd : resolve7(workingDirectory ?? process.cwd(), cmd);
|
|
4824
|
+
return probe(explicit) ? explicit : null;
|
|
4825
|
+
}
|
|
4826
|
+
const cacheKey = JSON.stringify([
|
|
4827
|
+
workingDirectory ?? "",
|
|
4828
|
+
cmd,
|
|
4829
|
+
platform,
|
|
4830
|
+
options.stopAt ?? "",
|
|
4831
|
+
options.pathExt ?? "",
|
|
4832
|
+
options.pathEnv ?? process.env["PATH"] ?? ""
|
|
4833
|
+
]);
|
|
4834
|
+
const cached = resolutionCache.get(cacheKey);
|
|
4835
|
+
if (cached !== undefined)
|
|
4836
|
+
return cached;
|
|
4837
|
+
let resolved = null;
|
|
4838
|
+
if (workingDirectory !== undefined && workingDirectory.length > 0) {
|
|
4839
|
+
resolved = resolveLocal(cmd, workingDirectory, suffixes, options.stopAt);
|
|
4840
|
+
}
|
|
4841
|
+
resolved ??= resolveFromPath(cmd, suffixes, platform, options.pathEnv);
|
|
4842
|
+
if (resolved === null && cmd === "node")
|
|
4843
|
+
resolved = cmd;
|
|
4844
|
+
resolutionCache.set(cacheKey, resolved);
|
|
4845
|
+
return resolved;
|
|
4846
|
+
}
|
|
4847
|
+
function isServerInstalled(command, workingDirectory, options = {}) {
|
|
4848
|
+
if (command.length === 0)
|
|
4849
|
+
return false;
|
|
4850
|
+
return resolveServerBinary(command, workingDirectory, options) !== null;
|
|
4591
4851
|
}
|
|
4592
4852
|
|
|
4593
4853
|
// ../lsp-core/src/lsp/server-resolution.ts
|
|
4854
|
+
function withResolvedCommand(command, binaryPath) {
|
|
4855
|
+
return [binaryPath, ...command.slice(1)];
|
|
4856
|
+
}
|
|
4594
4857
|
function findServerForExtension(ext) {
|
|
4595
4858
|
const servers = getMergedServers();
|
|
4859
|
+
const workingDirectory = contextCwd();
|
|
4596
4860
|
for (const server2 of servers) {
|
|
4597
|
-
if (server2.extensions.includes(ext)
|
|
4861
|
+
if (!server2.extensions.includes(ext))
|
|
4862
|
+
continue;
|
|
4863
|
+
const binaryPath = resolveServerBinary(server2.command, workingDirectory);
|
|
4864
|
+
if (binaryPath !== null) {
|
|
4598
4865
|
const resolvedServer = {
|
|
4599
4866
|
id: server2.id,
|
|
4600
|
-
command: server2.command,
|
|
4867
|
+
command: withResolvedCommand(server2.command, binaryPath),
|
|
4601
4868
|
extensions: server2.extensions,
|
|
4602
4869
|
priority: server2.priority
|
|
4603
4870
|
};
|
|
@@ -4644,6 +4911,7 @@ function findServerForExtension(ext) {
|
|
|
4644
4911
|
function getAllServers() {
|
|
4645
4912
|
const servers = getMergedServers();
|
|
4646
4913
|
const disabled = getDisabledServerIds();
|
|
4914
|
+
const workingDirectory = contextCwd();
|
|
4647
4915
|
const result = [];
|
|
4648
4916
|
const seen = new Set;
|
|
4649
4917
|
for (const server2 of servers) {
|
|
@@ -4651,7 +4919,7 @@ function getAllServers() {
|
|
|
4651
4919
|
continue;
|
|
4652
4920
|
result.push({
|
|
4653
4921
|
id: server2.id,
|
|
4654
|
-
installed: isServerInstalled(server2.command),
|
|
4922
|
+
installed: isServerInstalled(server2.command, workingDirectory),
|
|
4655
4923
|
extensions: server2.extensions,
|
|
4656
4924
|
disabled: false,
|
|
4657
4925
|
source: server2.source,
|
|
@@ -4665,7 +4933,7 @@ function getAllServers() {
|
|
|
4665
4933
|
const builtin = BUILTIN_SERVERS[id];
|
|
4666
4934
|
result.push({
|
|
4667
4935
|
id,
|
|
4668
|
-
installed: builtin ? isServerInstalled(builtin.command) : false,
|
|
4936
|
+
installed: builtin ? isServerInstalled(builtin.command, workingDirectory) : false,
|
|
4669
4937
|
extensions: builtin?.extensions ?? [],
|
|
4670
4938
|
disabled: true,
|
|
4671
4939
|
source: "disabled",
|
|
@@ -4676,7 +4944,6 @@ function getAllServers() {
|
|
|
4676
4944
|
}
|
|
4677
4945
|
|
|
4678
4946
|
// ../lsp-core/src/lsp/client-wrapper.ts
|
|
4679
|
-
var WORKSPACE_MARKERS = [".git", "package.json", "pyproject.toml", "Cargo.toml", "go.mod", "pom.xml", "build.gradle"];
|
|
4680
4947
|
function isDirectoryPath(filePath) {
|
|
4681
4948
|
try {
|
|
4682
4949
|
return statSync4(filePath).isDirectory();
|
|
@@ -4685,32 +4952,90 @@ function isDirectoryPath(filePath) {
|
|
|
4685
4952
|
}
|
|
4686
4953
|
}
|
|
4687
4954
|
function findWorkspaceRoot(filePath) {
|
|
4688
|
-
const
|
|
4955
|
+
const cwd = contextCwd();
|
|
4956
|
+
const abs = resolveReadablePathInsideContext(filePath);
|
|
4689
4957
|
let dir = abs;
|
|
4690
4958
|
if (!isDirectoryPath(dir)) {
|
|
4691
|
-
dir =
|
|
4692
|
-
}
|
|
4693
|
-
|
|
4694
|
-
|
|
4695
|
-
|
|
4696
|
-
|
|
4697
|
-
|
|
4959
|
+
dir = dirname10(dir);
|
|
4960
|
+
}
|
|
4961
|
+
if (!isPathInside(cwd, abs))
|
|
4962
|
+
return findWorkspaceRootOutsideContext(dir);
|
|
4963
|
+
const fallbackRoot = nearestExistingDirectoryInsideContext(dir, cwd) ?? cwd;
|
|
4964
|
+
let nearestPackageRoot;
|
|
4965
|
+
while (isPathInside(cwd, dir)) {
|
|
4966
|
+
const canonicalDir = existingDirectoryInsideContext(dir, cwd);
|
|
4967
|
+
if (canonicalDir !== undefined) {
|
|
4968
|
+
if (existsSync11(join5(dir, GIT_WORKSPACE_MARKER))) {
|
|
4969
|
+
return canonicalDir;
|
|
4970
|
+
}
|
|
4971
|
+
if (nearestPackageRoot === undefined && hasProjectWorkspaceMarker(dir)) {
|
|
4972
|
+
nearestPackageRoot = canonicalDir;
|
|
4698
4973
|
}
|
|
4699
4974
|
}
|
|
4700
|
-
|
|
4701
|
-
|
|
4975
|
+
if (dir === cwd)
|
|
4976
|
+
break;
|
|
4977
|
+
dir = dirname10(dir);
|
|
4702
4978
|
}
|
|
4703
|
-
return
|
|
4979
|
+
return nearestPackageRoot ?? fallbackRoot;
|
|
4980
|
+
}
|
|
4981
|
+
function hasProjectWorkspaceMarker(directory) {
|
|
4982
|
+
return PROJECT_WORKSPACE_MARKERS.some((marker) => existsSync11(join5(directory, marker)));
|
|
4983
|
+
}
|
|
4984
|
+
function resolveReadablePathInsideContext(filePath) {
|
|
4985
|
+
const cwd = contextCwd();
|
|
4986
|
+
const abs = resolve8(cwd, filePath);
|
|
4987
|
+
if (isPathInside(cwd, abs))
|
|
4988
|
+
return abs;
|
|
4989
|
+
const rebased = rebaseThroughCanonicalAncestor(abs, cwd);
|
|
4990
|
+
if (rebased !== undefined)
|
|
4991
|
+
return rebased;
|
|
4992
|
+
return canonicalizeExistingOrNearestAncestor(abs);
|
|
4704
4993
|
}
|
|
4705
4994
|
function resolvePathInsideContext(filePath) {
|
|
4706
4995
|
const cwd = contextCwd();
|
|
4707
|
-
const abs =
|
|
4996
|
+
const abs = resolveReadablePathInsideContext(filePath);
|
|
4708
4997
|
const canonical = canonicalizeExistingOrNearestAncestor(abs);
|
|
4709
4998
|
if (!isPathInside(cwd, canonical)) {
|
|
4710
4999
|
throw new LspInvalidPathError(`LSP file path must be inside request cwd: ${filePath}`);
|
|
4711
5000
|
}
|
|
4712
5001
|
return canonical;
|
|
4713
5002
|
}
|
|
5003
|
+
function rebaseThroughCanonicalAncestor(path2, cwd) {
|
|
5004
|
+
let current = path2;
|
|
5005
|
+
const suffix = [];
|
|
5006
|
+
while (true) {
|
|
5007
|
+
if (existsSync11(current)) {
|
|
5008
|
+
const canonical = realpathSync5(current);
|
|
5009
|
+
if (isPathInside(cwd, canonical))
|
|
5010
|
+
return suffix.length === 0 ? canonical : join5(canonical, ...suffix);
|
|
5011
|
+
}
|
|
5012
|
+
const parent = dirname10(current);
|
|
5013
|
+
if (parent === current)
|
|
5014
|
+
return;
|
|
5015
|
+
suffix.unshift(basename3(current));
|
|
5016
|
+
current = parent;
|
|
5017
|
+
}
|
|
5018
|
+
}
|
|
5019
|
+
function existingDirectoryInsideContext(directory, cwd) {
|
|
5020
|
+
if (!existsSync11(directory))
|
|
5021
|
+
return;
|
|
5022
|
+
const canonical = realpathSync5(directory);
|
|
5023
|
+
if (!statSync4(canonical).isDirectory())
|
|
5024
|
+
return;
|
|
5025
|
+
return isPathInside(cwd, canonical) ? canonical : undefined;
|
|
5026
|
+
}
|
|
5027
|
+
function nearestExistingDirectoryInsideContext(directory, cwd) {
|
|
5028
|
+
let current = directory;
|
|
5029
|
+
while (isPathInside(cwd, current)) {
|
|
5030
|
+
const canonical = existingDirectoryInsideContext(current, cwd);
|
|
5031
|
+
if (canonical !== undefined)
|
|
5032
|
+
return canonical;
|
|
5033
|
+
if (current === cwd)
|
|
5034
|
+
return;
|
|
5035
|
+
current = dirname10(current);
|
|
5036
|
+
}
|
|
5037
|
+
return;
|
|
5038
|
+
}
|
|
4714
5039
|
function formatServerLookupError(result) {
|
|
4715
5040
|
if (result.status === "not_installed") {
|
|
4716
5041
|
return formatNotInstalled(result);
|
|
@@ -4734,6 +5059,19 @@ function formatServerLookupError(result) {
|
|
|
4734
5059
|
].join(`
|
|
4735
5060
|
`);
|
|
4736
5061
|
}
|
|
5062
|
+
function formatInstallOptions(serverId, installHint) {
|
|
5063
|
+
const localHint = LSP_LOCAL_INSTALL_HINTS[serverId];
|
|
5064
|
+
if (localHint === undefined) {
|
|
5065
|
+
return ["To install, run:", ` ${installHint}`];
|
|
5066
|
+
}
|
|
5067
|
+
return [
|
|
5068
|
+
"To install in THIS repository (preferred — no global install needed):",
|
|
5069
|
+
` ${localHint}`,
|
|
5070
|
+
"",
|
|
5071
|
+
"Or install it globally:",
|
|
5072
|
+
` ${installHint}`
|
|
5073
|
+
];
|
|
5074
|
+
}
|
|
4737
5075
|
function formatNotInstalled(result) {
|
|
4738
5076
|
const { server: server2, installHint } = result;
|
|
4739
5077
|
const extensions = server2.extensions.join(", ");
|
|
@@ -4748,19 +5086,19 @@ function formatNotInstalled(result) {
|
|
|
4748
5086
|
`Command not found: ${server2.command[0]}`,
|
|
4749
5087
|
""
|
|
4750
5088
|
];
|
|
5089
|
+
const installOptions = formatInstallOptions(server2.id, installHint);
|
|
4751
5090
|
if (decision === "allowed") {
|
|
4752
5091
|
return [
|
|
4753
5092
|
...header,
|
|
4754
5093
|
"The user has pre-authorized LSP installation. Run the install command, then retry this tool:",
|
|
4755
|
-
|
|
5094
|
+
...installOptions.slice(1)
|
|
4756
5095
|
].join(`
|
|
4757
5096
|
`);
|
|
4758
5097
|
}
|
|
4759
5098
|
if (!context.capabilities.installDecisionTool) {
|
|
4760
5099
|
return [
|
|
4761
5100
|
...header,
|
|
4762
|
-
|
|
4763
|
-
` ${installHint}`,
|
|
5101
|
+
...installOptions,
|
|
4764
5102
|
"",
|
|
4765
5103
|
"ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
|
|
4766
5104
|
"Install-decision recording is unavailable in this harness; proceed without LSP if the user declines."
|
|
@@ -4769,8 +5107,7 @@ function formatNotInstalled(result) {
|
|
|
4769
5107
|
}
|
|
4770
5108
|
return [
|
|
4771
5109
|
...header,
|
|
4772
|
-
|
|
4773
|
-
` ${installHint}`,
|
|
5110
|
+
...installOptions,
|
|
4774
5111
|
"",
|
|
4775
5112
|
"ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
|
|
4776
5113
|
"- If the user agrees: run the install command above, then retry this tool.",
|
|
@@ -4781,7 +5118,7 @@ function formatNotInstalled(result) {
|
|
|
4781
5118
|
].join(`
|
|
4782
5119
|
`);
|
|
4783
5120
|
}
|
|
4784
|
-
var
|
|
5121
|
+
var READ_ONLY_TOOLS = new Set([
|
|
4785
5122
|
"diagnostics",
|
|
4786
5123
|
"definition",
|
|
4787
5124
|
"references",
|
|
@@ -4790,7 +5127,7 @@ var READ_ONLY_RETRY_TOOLS = new Set([
|
|
|
4790
5127
|
"prepareRename"
|
|
4791
5128
|
]);
|
|
4792
5129
|
async function withLspClient(filePath, fn, toolName, options = {}) {
|
|
4793
|
-
const absPath = resolvePathInsideContext(filePath);
|
|
5130
|
+
const absPath = READ_ONLY_TOOLS.has(toolName) ? resolveReadablePathInsideContext(filePath) : resolvePathInsideContext(filePath);
|
|
4794
5131
|
if (isDirectoryPath(absPath)) {
|
|
4795
5132
|
throw new LspInvalidPathError("Directory paths are not supported by this LSP tool. " + "Use lsp.diagnostics with a directory path for directory diagnostics.");
|
|
4796
5133
|
}
|
|
@@ -4805,9 +5142,9 @@ async function withLspClient(filePath, fn, toolName, options = {}) {
|
|
|
4805
5142
|
const acquireAndCall = async (allowRetry) => {
|
|
4806
5143
|
const client = await manager.getClient(root, server2, options.signal);
|
|
4807
5144
|
try {
|
|
4808
|
-
return await fn(client, root);
|
|
5145
|
+
return await fn(client, root, absPath);
|
|
4809
5146
|
} catch (err) {
|
|
4810
|
-
if (allowRetry &&
|
|
5147
|
+
if (allowRetry && READ_ONLY_TOOLS.has(toolName) && isLspDeadConnectionError(err)) {
|
|
4811
5148
|
manager.invalidateClient(root, server2.id, client);
|
|
4812
5149
|
return acquireAndCall(false);
|
|
4813
5150
|
}
|
|
@@ -4825,8 +5162,8 @@ async function withLspClient(filePath, fn, toolName, options = {}) {
|
|
|
4825
5162
|
}
|
|
4826
5163
|
|
|
4827
5164
|
// ../lsp-core/src/lsp/directory-diagnostics.ts
|
|
4828
|
-
import { existsSync as
|
|
4829
|
-
import { join as
|
|
5165
|
+
import { existsSync as existsSync12, lstatSync as lstatSync5, readdirSync as readdirSync3 } from "node:fs";
|
|
5166
|
+
import { join as join6, resolve as resolve9 } from "node:path";
|
|
4830
5167
|
|
|
4831
5168
|
// ../lsp-core/src/lsp/formatters.ts
|
|
4832
5169
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
@@ -4956,7 +5293,7 @@ function collectFilesWithExtension(dir, extension, maxFiles) {
|
|
|
4956
5293
|
for (const entry of entries) {
|
|
4957
5294
|
if (files.length >= maxFiles)
|
|
4958
5295
|
return;
|
|
4959
|
-
const fullPath =
|
|
5296
|
+
const fullPath = join6(currentDir, entry);
|
|
4960
5297
|
let stat;
|
|
4961
5298
|
try {
|
|
4962
5299
|
stat = lstatSync5(fullPath);
|
|
@@ -4981,8 +5318,8 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
|
|
|
4981
5318
|
if (!extension.startsWith(".")) {
|
|
4982
5319
|
throw new LspInvalidPathError(`Extension must start with a dot (e.g., ".ts", not "${extension}"). Use ".${extension}" instead.`);
|
|
4983
5320
|
}
|
|
4984
|
-
const absDir =
|
|
4985
|
-
if (!
|
|
5321
|
+
const absDir = resolve9(options.workspaceRoot ?? contextCwd(), directory);
|
|
5322
|
+
if (!existsSync12(absDir)) {
|
|
4986
5323
|
throw new LspInvalidPathError(`Directory does not exist: ${absDir}`);
|
|
4987
5324
|
}
|
|
4988
5325
|
const serverResult = options.server === undefined ? findServerForExtension(extension) : { status: "found", server: options.server };
|
|
@@ -5069,7 +5406,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
|
|
|
5069
5406
|
|
|
5070
5407
|
// ../lsp-core/src/lsp/infer-extension.ts
|
|
5071
5408
|
import { lstatSync as lstatSync6, readdirSync as readdirSync4 } from "node:fs";
|
|
5072
|
-
import { join as
|
|
5409
|
+
import { join as join7 } from "node:path";
|
|
5073
5410
|
var SKIP_DIRECTORIES2 = new Set(["node_modules", ".git", "dist", "build", ".next", "out"]);
|
|
5074
5411
|
var MAX_SCAN_ENTRIES = 500;
|
|
5075
5412
|
function inferExtensionFromDirectory(directory) {
|
|
@@ -5087,7 +5424,7 @@ function inferExtensionFromDirectory(directory) {
|
|
|
5087
5424
|
for (const entry of entries) {
|
|
5088
5425
|
if (scanned >= MAX_SCAN_ENTRIES)
|
|
5089
5426
|
return;
|
|
5090
|
-
const fullPath =
|
|
5427
|
+
const fullPath = join7(dir, entry);
|
|
5091
5428
|
let stat;
|
|
5092
5429
|
try {
|
|
5093
5430
|
stat = lstatSync6(fullPath);
|
|
@@ -5262,7 +5599,7 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
5262
5599
|
const filePath = requireString(params, "filePath");
|
|
5263
5600
|
const severity = severityFilter(params);
|
|
5264
5601
|
try {
|
|
5265
|
-
const absPath =
|
|
5602
|
+
const absPath = resolveReadablePathInsideContext(filePath);
|
|
5266
5603
|
if (isDirectoryPath(absPath)) {
|
|
5267
5604
|
const extension = inferExtensionFromDirectory(absPath);
|
|
5268
5605
|
if (!extension) {
|
|
@@ -5291,7 +5628,7 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
5291
5628
|
};
|
|
5292
5629
|
return text(output2.output, details2);
|
|
5293
5630
|
}
|
|
5294
|
-
const result = await withLspClient(filePath, async (client) => client.diagnostics(
|
|
5631
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.diagnostics(resolvedFilePath, signal), "diagnostics", clientOptions(signal));
|
|
5295
5632
|
if (result.transientError) {
|
|
5296
5633
|
const message = result.transientError.message;
|
|
5297
5634
|
const details2 = {
|
|
@@ -5338,6 +5675,96 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
5338
5675
|
throw error;
|
|
5339
5676
|
}
|
|
5340
5677
|
}
|
|
5678
|
+
// ../lsp-core/src/lsp/format-document.ts
|
|
5679
|
+
import { readFileSync as readFileSync6, renameSync as renameSync3, unlinkSync as unlinkSync2, writeFileSync as writeFileSync3 } from "node:fs";
|
|
5680
|
+
var DEFAULT_FORMATTING_OPTIONS = {
|
|
5681
|
+
tabSize: 4,
|
|
5682
|
+
insertSpaces: false,
|
|
5683
|
+
trimTrailingWhitespace: true,
|
|
5684
|
+
insertFinalNewline: true,
|
|
5685
|
+
trimFinalNewlines: true
|
|
5686
|
+
};
|
|
5687
|
+
var UNCHANGED = { status: "unchanged", linesAdded: 0, linesRemoved: 0 };
|
|
5688
|
+
async function formatDocumentWithClient(client, filePath, options = {}) {
|
|
5689
|
+
const edits = await client.formatDocument(filePath, options.formattingOptions ?? DEFAULT_FORMATTING_OPTIONS, options.signal);
|
|
5690
|
+
if (edits === null)
|
|
5691
|
+
return { status: "unavailable", reason: "capability_not_advertised" };
|
|
5692
|
+
if (edits.length === 0)
|
|
5693
|
+
return UNCHANGED;
|
|
5694
|
+
const before = readFileSync6(filePath, "utf-8");
|
|
5695
|
+
const normalized = normalizeTextEdits(before, edits, 0);
|
|
5696
|
+
if (normalized.text === before)
|
|
5697
|
+
return UNCHANGED;
|
|
5698
|
+
writeAtomically(filePath, normalized.text);
|
|
5699
|
+
await client.openFile(filePath);
|
|
5700
|
+
return {
|
|
5701
|
+
status: "formatted",
|
|
5702
|
+
...lineDelta(normalized.edits)
|
|
5703
|
+
};
|
|
5704
|
+
}
|
|
5705
|
+
function lineDelta(edits) {
|
|
5706
|
+
let linesAdded = 0;
|
|
5707
|
+
let linesRemoved = 0;
|
|
5708
|
+
for (const edit of edits) {
|
|
5709
|
+
linesRemoved += edit.range.end.line - edit.range.start.line + 1;
|
|
5710
|
+
linesAdded += edit.newText.split(`
|
|
5711
|
+
`).length;
|
|
5712
|
+
}
|
|
5713
|
+
return { linesAdded, linesRemoved };
|
|
5714
|
+
}
|
|
5715
|
+
function writeAtomically(filePath, content) {
|
|
5716
|
+
const tempPath = `${filePath}.omo-format.tmp`;
|
|
5717
|
+
writeFileSync3(tempPath, content, "utf-8");
|
|
5718
|
+
try {
|
|
5719
|
+
renameSync3(tempPath, filePath);
|
|
5720
|
+
} catch (error) {
|
|
5721
|
+
try {
|
|
5722
|
+
unlinkSync2(tempPath);
|
|
5723
|
+
} catch {}
|
|
5724
|
+
throw error;
|
|
5725
|
+
}
|
|
5726
|
+
}
|
|
5727
|
+
|
|
5728
|
+
// ../lsp-core/src/tools/format.ts
|
|
5729
|
+
async function executeLspFormat(params, signal) {
|
|
5730
|
+
const filePath = requireString(params, "filePath");
|
|
5731
|
+
try {
|
|
5732
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => formatDocumentWithClient(client, resolvedFilePath, signal === undefined ? {} : { signal }), "format", clientOptions(signal));
|
|
5733
|
+
return text(describeResult(filePath, result), formatDetails(filePath, result));
|
|
5734
|
+
} catch (error) {
|
|
5735
|
+
const missingDependency = missingDependencyResult(error, {
|
|
5736
|
+
filePath,
|
|
5737
|
+
status: "unavailable",
|
|
5738
|
+
reason: "server_unavailable",
|
|
5739
|
+
linesAdded: 0,
|
|
5740
|
+
linesRemoved: 0
|
|
5741
|
+
});
|
|
5742
|
+
if (missingDependency)
|
|
5743
|
+
return missingDependency;
|
|
5744
|
+
throw error;
|
|
5745
|
+
}
|
|
5746
|
+
}
|
|
5747
|
+
function formatDetails(filePath, result) {
|
|
5748
|
+
if (result.status === "unavailable") {
|
|
5749
|
+
return { filePath, status: "unavailable", reason: result.reason, linesAdded: 0, linesRemoved: 0 };
|
|
5750
|
+
}
|
|
5751
|
+
return {
|
|
5752
|
+
filePath,
|
|
5753
|
+
status: result.status,
|
|
5754
|
+
linesAdded: result.linesAdded,
|
|
5755
|
+
linesRemoved: result.linesRemoved
|
|
5756
|
+
};
|
|
5757
|
+
}
|
|
5758
|
+
function describeResult(filePath, result) {
|
|
5759
|
+
if (result.status === "unavailable") {
|
|
5760
|
+
return `Formatting unavailable for ${filePath}: the language server does not advertise documentFormattingProvider.`;
|
|
5761
|
+
}
|
|
5762
|
+
if (result.status === "unchanged") {
|
|
5763
|
+
return `Already formatted: ${filePath}`;
|
|
5764
|
+
}
|
|
5765
|
+
return `Formatted ${filePath} (+${result.linesAdded}/-${result.linesRemoved} lines)`;
|
|
5766
|
+
}
|
|
5767
|
+
|
|
5341
5768
|
// ../lsp-core/src/tools/install-decision.ts
|
|
5342
5769
|
async function executeLspInstallDecision(params) {
|
|
5343
5770
|
const serverId = requireString(params, "server_id");
|
|
@@ -5366,7 +5793,7 @@ async function executeLspGotoDefinition(params, signal) {
|
|
|
5366
5793
|
const line = requireNumber(params, "line");
|
|
5367
5794
|
const character = requireNumber(params, "character");
|
|
5368
5795
|
try {
|
|
5369
|
-
const result = await withLspClient(filePath, async (client) => client.definition(
|
|
5796
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.definition(resolvedFilePath, line, character, signal), "definition", clientOptions(signal));
|
|
5370
5797
|
const locations = !result ? [] : Array.isArray(result) ? result : [result];
|
|
5371
5798
|
const details = { filePath, line, character, locations };
|
|
5372
5799
|
if (locations.length === 0)
|
|
@@ -5391,7 +5818,7 @@ async function executeLspFindReferences(params, signal) {
|
|
|
5391
5818
|
const character = requireNumber(params, "character");
|
|
5392
5819
|
const includeDeclaration = optionalBoolean(params, "includeDeclaration") ?? true;
|
|
5393
5820
|
try {
|
|
5394
|
-
const result = await withLspClient(filePath, async (client) => client.references(
|
|
5821
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.references(resolvedFilePath, line, character, includeDeclaration, signal), "references", clientOptions(signal));
|
|
5395
5822
|
const references = Array.isArray(result) ? result : [];
|
|
5396
5823
|
const total = references.length;
|
|
5397
5824
|
const truncated = total > DEFAULT_MAX_REFERENCES;
|
|
@@ -5433,7 +5860,7 @@ async function executeLspPrepareRename(params, signal) {
|
|
|
5433
5860
|
const line = requireNumber(params, "line");
|
|
5434
5861
|
const character = requireNumber(params, "character");
|
|
5435
5862
|
try {
|
|
5436
|
-
const result = await withLspClient(filePath, async (client) => client.prepareRename(
|
|
5863
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.prepareRename(resolvedFilePath, line, character, signal), "prepareRename", clientOptions(signal));
|
|
5437
5864
|
const details = { filePath, line, character, result };
|
|
5438
5865
|
return text(formatPrepareRenameResult(result), details);
|
|
5439
5866
|
} catch (error) {
|
|
@@ -5454,7 +5881,7 @@ async function executeLspRename(params, signal) {
|
|
|
5454
5881
|
const character = requireNumber(params, "character");
|
|
5455
5882
|
const newName = requireString(params, "newName");
|
|
5456
5883
|
try {
|
|
5457
|
-
const result = await withLspClient(filePath, async (client) => client.rename(
|
|
5884
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.rename(resolvedFilePath, line, character, newName, signal), "rename", clientOptions(signal));
|
|
5458
5885
|
const details = { filePath, line, character, newName, apply: result.apply, edit: result.edit };
|
|
5459
5886
|
return text(formatApplyResult(result.apply), details, !result.apply.success);
|
|
5460
5887
|
} catch (error) {
|
|
@@ -5534,7 +5961,7 @@ async function executeLspSymbols(params, signal) {
|
|
|
5534
5961
|
const symbols2 = await withLspClient(filePath, async (client) => client.workspaceSymbols(query, signal), "workspaceSymbols", clientOptions(signal));
|
|
5535
5962
|
return formatSymbolsResult(filePath, scope, symbols2, limit, query);
|
|
5536
5963
|
}
|
|
5537
|
-
const symbols = await withLspClient(filePath, async (client) => client.documentSymbols(
|
|
5964
|
+
const symbols = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.documentSymbols(resolvedFilePath, signal), "documentSymbols", clientOptions(signal));
|
|
5538
5965
|
return formatSymbolsResult(filePath, scope, symbols, limit);
|
|
5539
5966
|
} catch (error) {
|
|
5540
5967
|
const query = optionalString(params, "query");
|
|
@@ -5670,6 +6097,16 @@ var LSP_MCP_TOOLS = [
|
|
|
5670
6097
|
}, ["filePath", "line", "character", "newName"]),
|
|
5671
6098
|
execute: executeLspRename
|
|
5672
6099
|
},
|
|
6100
|
+
{
|
|
6101
|
+
name: "format",
|
|
6102
|
+
aliases: ["lsp_format"],
|
|
6103
|
+
title: "LSP Format",
|
|
6104
|
+
description: "Format a source file with its language server and write the returned edits to disk.",
|
|
6105
|
+
inputSchema: objectSchema({
|
|
6106
|
+
filePath: { type: "string", description: "Source file path to format." }
|
|
6107
|
+
}, ["filePath"]),
|
|
6108
|
+
execute: executeLspFormat
|
|
6109
|
+
},
|
|
5673
6110
|
{
|
|
5674
6111
|
name: "install_decision",
|
|
5675
6112
|
aliases: ["lsp_install_decision"],
|
|
@@ -5770,7 +6207,10 @@ function requestedProtocolVersion(params) {
|
|
|
5770
6207
|
var CONTEXT_KEY = "_context";
|
|
5771
6208
|
|
|
5772
6209
|
class InvalidDaemonRequestError extends Error {
|
|
5773
|
-
|
|
6210
|
+
constructor() {
|
|
6211
|
+
super(...arguments);
|
|
6212
|
+
this.name = "InvalidDaemonRequestError";
|
|
6213
|
+
}
|
|
5774
6214
|
}
|
|
5775
6215
|
function extractRequestContext(raw) {
|
|
5776
6216
|
if (!isPlainRecord(raw) || raw["method"] !== "tools/call")
|
|
@@ -5886,14 +6326,17 @@ async function callToolViaDaemon(name, args, options) {
|
|
|
5886
6326
|
function callDiagnosticsViaDaemon(filePath, options) {
|
|
5887
6327
|
return callToolViaDaemon("diagnostics", { filePath, severity: "error" }, options);
|
|
5888
6328
|
}
|
|
6329
|
+
function callFormatViaDaemon(filePath, options) {
|
|
6330
|
+
return callToolViaDaemon("format", { filePath }, options);
|
|
6331
|
+
}
|
|
5889
6332
|
function currentRequestContext(env = process.env) {
|
|
5890
6333
|
const cwd = process.cwd();
|
|
5891
6334
|
const home = env["HOME"] ?? homedir3();
|
|
5892
6335
|
return parseLspRequestContext({
|
|
5893
6336
|
cwd,
|
|
5894
|
-
projectConfigPaths: [
|
|
5895
|
-
userConfigPath:
|
|
5896
|
-
installDecisionsPath:
|
|
6337
|
+
projectConfigPaths: [join8(cwd, ".codex", "lsp-client.json")],
|
|
6338
|
+
userConfigPath: join8(home, ".codex", "lsp-client.json"),
|
|
6339
|
+
installDecisionsPath: join8(home, ".codex", "lsp-install-decisions.json"),
|
|
5897
6340
|
capabilities: { installDecisionTool: true }
|
|
5898
6341
|
});
|
|
5899
6342
|
}
|
|
@@ -5908,7 +6351,7 @@ function withContext(args, context) {
|
|
|
5908
6351
|
function ensureDaemonAvailable(paths, ensure, signal) {
|
|
5909
6352
|
if (!signal)
|
|
5910
6353
|
return ensure(paths);
|
|
5911
|
-
return new Promise((
|
|
6354
|
+
return new Promise((resolve10, reject) => {
|
|
5912
6355
|
let settled = false;
|
|
5913
6356
|
const finish = (run) => {
|
|
5914
6357
|
if (settled)
|
|
@@ -5923,11 +6366,11 @@ function ensureDaemonAvailable(paths, ensure, signal) {
|
|
|
5923
6366
|
return;
|
|
5924
6367
|
}
|
|
5925
6368
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
5926
|
-
Promise.resolve().then(() => ensure(paths, signal)).then(() => finish(() =>
|
|
6369
|
+
Promise.resolve().then(() => ensure(paths, signal)).then(() => finish(() => resolve10()), (error) => finish(() => reject(signal.aborted ? new DaemonRequestCancelledError(false) : error)));
|
|
5927
6370
|
});
|
|
5928
6371
|
}
|
|
5929
6372
|
function sendToolCall(paths, token, name, args, options) {
|
|
5930
|
-
return new Promise((
|
|
6373
|
+
return new Promise((resolve10, reject) => {
|
|
5931
6374
|
const socket = connect(paths.socket);
|
|
5932
6375
|
const requestId = allocateProxyRequestId();
|
|
5933
6376
|
let settled = false;
|
|
@@ -5980,7 +6423,7 @@ function sendToolCall(paths, token, name, args, options) {
|
|
|
5980
6423
|
}
|
|
5981
6424
|
const result = toToolResult(message, requestId);
|
|
5982
6425
|
if (result)
|
|
5983
|
-
finish(() =>
|
|
6426
|
+
finish(() => resolve10(result));
|
|
5984
6427
|
else
|
|
5985
6428
|
finish(() => reject(new DaemonRequestError("invalid daemon response", requestWritten)));
|
|
5986
6429
|
});
|
|
@@ -6025,8 +6468,8 @@ function isRetryableTool(name) {
|
|
|
6025
6468
|
return name !== "rename" && name !== "lsp_rename";
|
|
6026
6469
|
}
|
|
6027
6470
|
// src/proxy.ts
|
|
6028
|
-
import { existsSync as
|
|
6029
|
-
import { basename as
|
|
6471
|
+
import { existsSync as existsSync13, realpathSync as realpathSync6 } from "node:fs";
|
|
6472
|
+
import { basename as basename4, delimiter as delimiter4, dirname as dirname11, isAbsolute as isAbsolute6 } from "node:path";
|
|
6030
6473
|
var DEFAULT_STARTUP_TIMEOUT_MS = 1e4;
|
|
6031
6474
|
async function runMcpStdioProxy(options = {}) {
|
|
6032
6475
|
const input = options.input ?? process.stdin;
|
|
@@ -6149,34 +6592,34 @@ function canonicalizePathList(value) {
|
|
|
6149
6592
|
return value.split(delimiter4).map((entry) => canonicalizePath(entry) ?? entry).join(delimiter4);
|
|
6150
6593
|
}
|
|
6151
6594
|
function canonicalizePath(value) {
|
|
6152
|
-
if (value === undefined || !
|
|
6595
|
+
if (value === undefined || !isAbsolute6(value) || !existsSync13(value))
|
|
6153
6596
|
return value;
|
|
6154
|
-
return
|
|
6597
|
+
return realpathSync6(value);
|
|
6155
6598
|
}
|
|
6156
6599
|
function projectRootFromOpenCodeConfigPath(path2) {
|
|
6157
|
-
if (
|
|
6600
|
+
if (basename4(path2) !== "lsp.json" && basename4(path2) !== "lsp-client.json")
|
|
6158
6601
|
return;
|
|
6159
|
-
const configDir =
|
|
6160
|
-
const configDirName =
|
|
6602
|
+
const configDir = dirname11(path2);
|
|
6603
|
+
const configDirName = basename4(configDir);
|
|
6161
6604
|
if (configDirName !== ".opencode" && configDirName !== ".omo")
|
|
6162
6605
|
return;
|
|
6163
|
-
return
|
|
6606
|
+
return dirname11(configDir);
|
|
6164
6607
|
}
|
|
6165
6608
|
export {
|
|
6166
|
-
|
|
6167
|
-
runMcpStdioProxy,
|
|
6168
|
-
resolveDaemonRuntime,
|
|
6169
|
-
probeDaemon,
|
|
6170
|
-
ensureDaemonRunning,
|
|
6171
|
-
disposeDefaultLspManager,
|
|
6172
|
-
daemonPaths,
|
|
6173
|
-
currentRequestContext,
|
|
6174
|
-
callToolViaDaemon,
|
|
6175
|
-
callDiagnosticsViaDaemon,
|
|
6176
|
-
OMO_LSP_DAEMON_VERSION,
|
|
6177
|
-
OMO_LSP_DAEMON_DIR,
|
|
6178
|
-
OMO_LSP_DAEMON_CLI,
|
|
6179
|
-
InvalidRuntimeOverrideError,
|
|
6609
|
+
InvalidDaemonDirectoryError,
|
|
6180
6610
|
InvalidDaemonVersionError,
|
|
6181
|
-
|
|
6611
|
+
InvalidRuntimeOverrideError,
|
|
6612
|
+
OMO_LSP_DAEMON_CLI,
|
|
6613
|
+
OMO_LSP_DAEMON_DIR,
|
|
6614
|
+
OMO_LSP_DAEMON_VERSION,
|
|
6615
|
+
callDiagnosticsViaDaemon,
|
|
6616
|
+
callToolViaDaemon,
|
|
6617
|
+
currentRequestContext,
|
|
6618
|
+
daemonPaths,
|
|
6619
|
+
disposeDefaultLspManager,
|
|
6620
|
+
ensureDaemonRunning,
|
|
6621
|
+
probeDaemon,
|
|
6622
|
+
resolveDaemonRuntime,
|
|
6623
|
+
runMcpStdioProxy,
|
|
6624
|
+
validateDaemonVersion
|
|
6182
6625
|
};
|