oh-my-opencode 5.0.0-beta.3 → 5.0.0-beta.30
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 +22572 -20322
- 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 +22190 -19917
- 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 +4 -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/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/team-mode/tools/messaging-fallback-wake.d.ts +15 -0
- 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/index.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 +12573 -6957
- package/dist/oh-my-opencode.schema.json +15 -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/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/tool-description.d.ts +3 -1
- package/dist/tools/delegate-task/types.d.ts +3 -0
- package/dist/tui.d.ts +12 -0
- package/dist/tui.js +11480 -11512
- package/package.json +42 -36
- package/packages/git-bash-mcp/dist/cli.js +5 -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 +66 -13
- package/packages/lsp-core/src/lsp/client-wrapper.ts +95 -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 +1 -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-max-clients.test.ts +151 -0
- package/packages/lsp-core/src/lsp/manager.ts +34 -1
- 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 +1 -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 +645 -296
- package/packages/lsp-daemon/dist/client.d.ts +10 -0
- package/packages/lsp-daemon/dist/client.js +605 -253
- 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 +609 -262
- 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 +564 -217
- package/packages/lsp-tools-mcp/dist/lsp/manager.js +115 -92
- package/packages/lsp-tools-mcp/dist/mcp.js +566 -219
- package/packages/lsp-tools-mcp/dist/request-context.js +12 -13
- package/packages/lsp-tools-mcp/dist/tools.js +571 -227
- 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 +293 -116
- package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +245 -84
- 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/session-start-hook-runtime.ts +1 -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 +596 -267
- 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 +16 -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/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 +24 -14
- 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/stop-resume-hook.js +3 -3
- 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/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-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/stop-resume-hook.ts +3 -3
- package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-continuation.test.ts +0 -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 +2 -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/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/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/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/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/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
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
import { argv, stderr } from "node:process";
|
|
5
5
|
|
|
6
6
|
// src/proxy.ts
|
|
7
|
-
import { existsSync as
|
|
8
|
-
import { basename as
|
|
7
|
+
import { existsSync as existsSync13, realpathSync as realpathSync6 } from "node:fs";
|
|
8
|
+
import { basename as basename4, delimiter as delimiter4, dirname as dirname11, isAbsolute as isAbsolute6 } from "node:path";
|
|
9
9
|
|
|
10
10
|
// ../mcp-stdio-core/src/record.ts
|
|
11
11
|
function isPlainRecord(value) {
|
|
@@ -280,7 +280,11 @@ function createParentWatchdog(config, onDeadParent) {
|
|
|
280
280
|
const probeAlive = config.probeAlive ?? isProcessAlive;
|
|
281
281
|
let fired = false;
|
|
282
282
|
const timer = setInterval(() => {
|
|
283
|
-
if (fired
|
|
283
|
+
if (fired)
|
|
284
|
+
return;
|
|
285
|
+
const alive = probeAlive(parentPid);
|
|
286
|
+
config.onPoll?.(alive);
|
|
287
|
+
if (alive)
|
|
284
288
|
return;
|
|
285
289
|
fired = true;
|
|
286
290
|
onDeadParent(parentPid, pollIntervalMs);
|
|
@@ -315,8 +319,8 @@ function createIdleTimer(idleTimeoutMs, log, onTimeout) {
|
|
|
315
319
|
};
|
|
316
320
|
}
|
|
317
321
|
// ../lsp-core/src/lsp/client-wrapper.ts
|
|
318
|
-
import { existsSync as
|
|
319
|
-
import { dirname as
|
|
322
|
+
import { existsSync as existsSync10, realpathSync as realpathSync5, statSync as statSync3 } from "node:fs";
|
|
323
|
+
import { basename as basename3, dirname as dirname8, join as join5, resolve as resolve8 } from "node:path";
|
|
320
324
|
|
|
321
325
|
// ../lsp-core/src/request-context.ts
|
|
322
326
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
@@ -325,18 +329,17 @@ import { homedir } from "node:os";
|
|
|
325
329
|
import { basename, delimiter, dirname, isAbsolute, join, relative, resolve } from "node:path";
|
|
326
330
|
|
|
327
331
|
class LspRequestContextParseError extends Error {
|
|
328
|
-
code;
|
|
329
|
-
name = "LspRequestContextParseError";
|
|
330
332
|
constructor(code, message) {
|
|
331
333
|
super(message);
|
|
332
334
|
this.code = code;
|
|
335
|
+
this.name = "LspRequestContextParseError";
|
|
333
336
|
}
|
|
334
337
|
}
|
|
335
338
|
|
|
336
339
|
class LspRequestContextUnavailableError extends Error {
|
|
337
|
-
name = "LspRequestContextUnavailableError";
|
|
338
340
|
constructor() {
|
|
339
341
|
super("LSP request context is required. Standalone MCP startup must install one with runWithRequestContext(createStandaloneMcpRequestContext()).");
|
|
342
|
+
this.name = "LspRequestContextUnavailableError";
|
|
340
343
|
}
|
|
341
344
|
}
|
|
342
345
|
var storage = new AsyncLocalStorage;
|
|
@@ -356,7 +359,7 @@ function contextCwd() {
|
|
|
356
359
|
}
|
|
357
360
|
function createStandaloneMcpRequestContext(input = {}) {
|
|
358
361
|
const env = input.env ?? process.env;
|
|
359
|
-
const cwd = canonicalCwd(input.cwd ?? process.cwd());
|
|
362
|
+
const cwd = canonicalCwd(input.cwd ?? env["LSP_TOOLS_MCP_CWD"] ?? process.cwd());
|
|
360
363
|
const home = input.homeDir ?? homedir();
|
|
361
364
|
const projectConfigPaths = translateProjectConfigEnv(env["LSP_TOOLS_MCP_PROJECT_CONFIG"], cwd);
|
|
362
365
|
const userConfigPath = translateHomeConfigEnv(env["LSP_TOOLS_MCP_USER_CONFIG"], home, ".codex/lsp-client.json");
|
|
@@ -499,22 +502,15 @@ function effectiveExtension(filePath) {
|
|
|
499
502
|
|
|
500
503
|
// ../lsp-core/src/lsp/errors.ts
|
|
501
504
|
class LspConnectionClosedError extends Error {
|
|
502
|
-
serverId;
|
|
503
|
-
root;
|
|
504
|
-
name = "LspConnectionClosedError";
|
|
505
505
|
constructor(serverId, root, message) {
|
|
506
506
|
super(message ?? `LSP connection closed for ${serverId} at ${root}`);
|
|
507
507
|
this.serverId = serverId;
|
|
508
508
|
this.root = root;
|
|
509
|
+
this.name = "LspConnectionClosedError";
|
|
509
510
|
}
|
|
510
511
|
}
|
|
511
512
|
|
|
512
513
|
class LspProcessExitedError extends Error {
|
|
513
|
-
serverId;
|
|
514
|
-
root;
|
|
515
|
-
exitCode;
|
|
516
|
-
stderrTail;
|
|
517
|
-
name = "LspProcessExitedError";
|
|
518
514
|
constructor(serverId, root, exitCode, stderrTail) {
|
|
519
515
|
const stderrSuffix = stderrTail ? `
|
|
520
516
|
stderr tail: ${stderrTail}` : "";
|
|
@@ -523,46 +519,49 @@ stderr tail: ${stderrTail}` : "";
|
|
|
523
519
|
this.root = root;
|
|
524
520
|
this.exitCode = exitCode;
|
|
525
521
|
this.stderrTail = stderrTail;
|
|
522
|
+
this.name = "LspProcessExitedError";
|
|
526
523
|
}
|
|
527
524
|
}
|
|
528
525
|
|
|
529
526
|
class LspRequestTimeoutError extends Error {
|
|
530
|
-
method;
|
|
531
|
-
stderrTail;
|
|
532
|
-
name = "LspRequestTimeoutError";
|
|
533
527
|
constructor(method, stderrTail) {
|
|
534
528
|
const stderrSuffix = stderrTail ? `
|
|
535
529
|
recent stderr: ${stderrTail}` : "";
|
|
536
530
|
super(`LSP request timeout (method: ${method})${stderrSuffix}`);
|
|
537
531
|
this.method = method;
|
|
538
532
|
this.stderrTail = stderrTail;
|
|
533
|
+
this.name = "LspRequestTimeoutError";
|
|
539
534
|
}
|
|
540
535
|
}
|
|
541
536
|
|
|
542
537
|
class LspInvalidPathError extends Error {
|
|
543
|
-
|
|
538
|
+
constructor() {
|
|
539
|
+
super(...arguments);
|
|
540
|
+
this.name = "LspInvalidPathError";
|
|
541
|
+
}
|
|
544
542
|
}
|
|
545
543
|
|
|
546
544
|
class LspServerLookupError extends Error {
|
|
547
|
-
lookup;
|
|
548
|
-
name = "LspServerLookupError";
|
|
549
545
|
constructor(message, lookup) {
|
|
550
546
|
super(message);
|
|
551
547
|
this.lookup = lookup;
|
|
548
|
+
this.name = "LspServerLookupError";
|
|
552
549
|
}
|
|
553
550
|
}
|
|
554
551
|
|
|
555
552
|
class LspServerInitializingError extends Error {
|
|
556
|
-
originalError;
|
|
557
|
-
name = "LspServerInitializingError";
|
|
558
553
|
constructor(originalError) {
|
|
559
554
|
super(`LSP server is still initializing. Please retry in a few seconds. Original error: ${originalError.message}`);
|
|
560
555
|
this.originalError = originalError;
|
|
556
|
+
this.name = "LspServerInitializingError";
|
|
561
557
|
}
|
|
562
558
|
}
|
|
563
559
|
|
|
564
560
|
class LspProcessSpawnError extends Error {
|
|
565
|
-
|
|
561
|
+
constructor() {
|
|
562
|
+
super(...arguments);
|
|
563
|
+
this.name = "LspProcessSpawnError";
|
|
564
|
+
}
|
|
566
565
|
}
|
|
567
566
|
function isLspDeadConnectionError(err) {
|
|
568
567
|
return err instanceof LspConnectionClosedError || err instanceof LspProcessExitedError;
|
|
@@ -593,6 +592,7 @@ var DEFAULT_MAX_DIRECTORY_FILES = 50;
|
|
|
593
592
|
var REQUEST_TIMEOUT_MS = 15000;
|
|
594
593
|
var INIT_TIMEOUT_MS = 60000;
|
|
595
594
|
var IDLE_TIMEOUT_MS = 5 * 60000;
|
|
595
|
+
var MAX_RESIDENT_CLIENTS = 6;
|
|
596
596
|
var REAPER_INTERVAL_MS = 60000;
|
|
597
597
|
var STOP_HARD_KILL_TIMEOUT_MS = 5000;
|
|
598
598
|
var STOP_SIGKILL_GRACE_MS = 1000;
|
|
@@ -607,20 +607,31 @@ var METHOD_NOT_FOUND = -32601;
|
|
|
607
607
|
var INTERNAL_ERROR = -32603;
|
|
608
608
|
|
|
609
609
|
class JsonRpcConnection {
|
|
610
|
-
reader;
|
|
611
|
-
writer;
|
|
612
|
-
pendingRequests = new Map;
|
|
613
|
-
notificationHandlers = new Map;
|
|
614
|
-
requestHandlers = new Map;
|
|
615
|
-
closeHandlers = [];
|
|
616
|
-
errorHandlers = [];
|
|
617
|
-
inputBuffer = Buffer.alloc(0);
|
|
618
|
-
nextRequestId = 1;
|
|
619
|
-
listening = false;
|
|
620
|
-
disposed = false;
|
|
621
610
|
constructor(reader, writer) {
|
|
622
611
|
this.reader = reader;
|
|
623
612
|
this.writer = writer;
|
|
613
|
+
this.pendingRequests = new Map;
|
|
614
|
+
this.notificationHandlers = new Map;
|
|
615
|
+
this.requestHandlers = new Map;
|
|
616
|
+
this.closeHandlers = [];
|
|
617
|
+
this.errorHandlers = [];
|
|
618
|
+
this.inputBuffer = Buffer.alloc(0);
|
|
619
|
+
this.nextRequestId = 1;
|
|
620
|
+
this.listening = false;
|
|
621
|
+
this.disposed = false;
|
|
622
|
+
this.handleData = (chunk) => {
|
|
623
|
+
const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
|
|
624
|
+
this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
|
|
625
|
+
this.drainInputBuffer();
|
|
626
|
+
};
|
|
627
|
+
this.handleClose = () => {
|
|
628
|
+
for (const handler of this.closeHandlers) {
|
|
629
|
+
handler();
|
|
630
|
+
}
|
|
631
|
+
};
|
|
632
|
+
this.handleStreamError = (error) => {
|
|
633
|
+
this.emitError(error);
|
|
634
|
+
};
|
|
624
635
|
}
|
|
625
636
|
listen() {
|
|
626
637
|
if (this.listening)
|
|
@@ -741,19 +752,6 @@ class JsonRpcConnection {
|
|
|
741
752
|
this.notificationHandlers.clear();
|
|
742
753
|
this.requestHandlers.clear();
|
|
743
754
|
}
|
|
744
|
-
handleData = (chunk) => {
|
|
745
|
-
const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
|
|
746
|
-
this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
|
|
747
|
-
this.drainInputBuffer();
|
|
748
|
-
};
|
|
749
|
-
handleClose = () => {
|
|
750
|
-
for (const handler of this.closeHandlers) {
|
|
751
|
-
handler();
|
|
752
|
-
}
|
|
753
|
-
};
|
|
754
|
-
handleStreamError = (error) => {
|
|
755
|
-
this.emitError(error);
|
|
756
|
-
};
|
|
757
755
|
drainInputBuffer() {
|
|
758
756
|
while (true) {
|
|
759
757
|
const headerEnd = this.inputBuffer.indexOf(HEADER_SEPARATOR2);
|
|
@@ -1101,31 +1099,26 @@ function isPosition(value) {
|
|
|
1101
1099
|
|
|
1102
1100
|
// ../lsp-core/src/lsp/transport.ts
|
|
1103
1101
|
class LspClientNotStartedError extends Error {
|
|
1104
|
-
serverId;
|
|
1105
|
-
root;
|
|
1106
|
-
name = "LspClientNotStartedError";
|
|
1107
1102
|
constructor(serverId, root) {
|
|
1108
1103
|
super("LSP client not started");
|
|
1109
1104
|
this.serverId = serverId;
|
|
1110
1105
|
this.root = root;
|
|
1106
|
+
this.name = "LspClientNotStartedError";
|
|
1111
1107
|
}
|
|
1112
1108
|
}
|
|
1113
1109
|
|
|
1114
1110
|
class LspClientTransport {
|
|
1115
|
-
root;
|
|
1116
|
-
server;
|
|
1117
|
-
proc = null;
|
|
1118
|
-
connection = null;
|
|
1119
|
-
stderrBuffer = [];
|
|
1120
|
-
processExited = false;
|
|
1121
|
-
diagnosticsStore = new Map;
|
|
1122
|
-
requestTimeoutMs;
|
|
1123
|
-
initializeTimeoutMs;
|
|
1124
|
-
workspaceApplyEditHandler = null;
|
|
1125
|
-
diagnosticPullSupported = false;
|
|
1126
1111
|
constructor(root, server2, timeouts = {}) {
|
|
1127
1112
|
this.root = root;
|
|
1128
1113
|
this.server = server2;
|
|
1114
|
+
this.proc = null;
|
|
1115
|
+
this.connection = null;
|
|
1116
|
+
this.stderrBuffer = [];
|
|
1117
|
+
this.processExited = false;
|
|
1118
|
+
this.diagnosticsStore = new Map;
|
|
1119
|
+
this.workspaceApplyEditHandler = null;
|
|
1120
|
+
this.diagnosticPullSupported = false;
|
|
1121
|
+
this.documentFormattingSupported = false;
|
|
1129
1122
|
this.requestTimeoutMs = timeouts.requestTimeoutMs ?? REQUEST_TIMEOUT_MS;
|
|
1130
1123
|
this.initializeTimeoutMs = timeouts.initializeTimeoutMs ?? INIT_TIMEOUT_MS;
|
|
1131
1124
|
}
|
|
@@ -1147,6 +1140,12 @@ class LspClientTransport {
|
|
|
1147
1140
|
isDiagnosticPullSupported() {
|
|
1148
1141
|
return this.diagnosticPullSupported;
|
|
1149
1142
|
}
|
|
1143
|
+
setDocumentFormattingSupported(supported) {
|
|
1144
|
+
this.documentFormattingSupported = supported;
|
|
1145
|
+
}
|
|
1146
|
+
isDocumentFormattingSupported() {
|
|
1147
|
+
return this.documentFormattingSupported;
|
|
1148
|
+
}
|
|
1150
1149
|
handlePublishDiagnostics(params) {
|
|
1151
1150
|
this.diagnosticsStore.set(params.uri, [...params.diagnostics]);
|
|
1152
1151
|
}
|
|
@@ -1360,6 +1359,14 @@ function supportsDiagnosticPull(capabilities) {
|
|
|
1360
1359
|
return false;
|
|
1361
1360
|
return Object.hasOwn(capabilities, "diagnosticProvider");
|
|
1362
1361
|
}
|
|
1362
|
+
function supportsDocumentFormatting(capabilities) {
|
|
1363
|
+
if (capabilities === undefined)
|
|
1364
|
+
return false;
|
|
1365
|
+
const provider = capabilities.documentFormattingProvider;
|
|
1366
|
+
if (provider === undefined || provider === null || provider === false)
|
|
1367
|
+
return false;
|
|
1368
|
+
return provider === true || typeof provider === "object";
|
|
1369
|
+
}
|
|
1363
1370
|
|
|
1364
1371
|
class LspClientConnection extends LspClientTransport {
|
|
1365
1372
|
async initialize() {
|
|
@@ -1376,6 +1383,7 @@ class LspClientConnection extends LspClientTransport {
|
|
|
1376
1383
|
references: {},
|
|
1377
1384
|
documentSymbol: { hierarchicalDocumentSymbolSupport: true },
|
|
1378
1385
|
publishDiagnostics: {},
|
|
1386
|
+
formatting: { dynamicRegistration: false },
|
|
1379
1387
|
rename: {
|
|
1380
1388
|
prepareSupport: true,
|
|
1381
1389
|
prepareSupportDefaultBehavior: 1
|
|
@@ -1417,6 +1425,7 @@ class LspClientConnection extends LspClientTransport {
|
|
|
1417
1425
|
initializationOptions: this.server.initialization
|
|
1418
1426
|
}, { timeoutMs: this.initializeTimeoutMs });
|
|
1419
1427
|
this.setDiagnosticPullSupported(supportsDiagnosticPull(result?.capabilities));
|
|
1428
|
+
this.setDocumentFormattingSupported(supportsDocumentFormatting(result?.capabilities));
|
|
1420
1429
|
await this.sendNotification("initialized", {});
|
|
1421
1430
|
await this.sendNotification("workspace/didChangeConfiguration", {
|
|
1422
1431
|
settings: { json: { validate: { enable: true } } }
|
|
@@ -1622,16 +1631,12 @@ function movedPath(candidate, oldPath, newPath) {
|
|
|
1622
1631
|
}
|
|
1623
1632
|
|
|
1624
1633
|
class WorkspaceDocumentState {
|
|
1625
|
-
sendNotification;
|
|
1626
|
-
clearDiagnostics;
|
|
1627
|
-
openDocuments = new Map;
|
|
1628
|
-
openByUri = new Map;
|
|
1629
|
-
openPromises = new Map;
|
|
1630
|
-
now;
|
|
1631
|
-
versionlessPublishQuiescenceMs;
|
|
1632
1634
|
constructor(sendNotification, clearDiagnostics, options = {}) {
|
|
1633
1635
|
this.sendNotification = sendNotification;
|
|
1634
1636
|
this.clearDiagnostics = clearDiagnostics;
|
|
1637
|
+
this.openDocuments = new Map;
|
|
1638
|
+
this.openByUri = new Map;
|
|
1639
|
+
this.openPromises = new Map;
|
|
1635
1640
|
this.now = options.now ?? (() => Date.now());
|
|
1636
1641
|
this.versionlessPublishQuiescenceMs = options.versionlessPublishQuiescenceMs ?? DEFAULT_VERSIONLESS_PUBLISH_QUIESCENCE_MS;
|
|
1637
1642
|
}
|
|
@@ -1895,13 +1900,11 @@ import { dirname as dirname2, isAbsolute as isAbsolute2, relative as relative3,
|
|
|
1895
1900
|
import { fileURLToPath } from "node:url";
|
|
1896
1901
|
|
|
1897
1902
|
class WorkspaceEditPathError extends Error {
|
|
1898
|
-
path;
|
|
1899
|
-
detail;
|
|
1900
|
-
name = "WorkspaceEditPathError";
|
|
1901
1903
|
constructor(path, detail) {
|
|
1902
1904
|
super(`${detail}: ${path}`);
|
|
1903
1905
|
this.path = path;
|
|
1904
1906
|
this.detail = detail;
|
|
1907
|
+
this.name = "WorkspaceEditPathError";
|
|
1905
1908
|
}
|
|
1906
1909
|
}
|
|
1907
1910
|
function isPathInsideWorkspace(filePath, workspaceRoot) {
|
|
@@ -2193,13 +2196,11 @@ function canonicalFingerprint(operations) {
|
|
|
2193
2196
|
|
|
2194
2197
|
// ../lsp-core/src/lsp/workspace-edit-types.ts
|
|
2195
2198
|
class WorkspaceEditValidationError extends Error {
|
|
2196
|
-
changeIndex;
|
|
2197
|
-
detail;
|
|
2198
|
-
name = "WorkspaceEditValidationError";
|
|
2199
2199
|
constructor(changeIndex, detail) {
|
|
2200
2200
|
super(`change ${changeIndex}: ${detail}`);
|
|
2201
2201
|
this.changeIndex = changeIndex;
|
|
2202
2202
|
this.detail = detail;
|
|
2203
|
+
this.name = "WorkspaceEditValidationError";
|
|
2203
2204
|
}
|
|
2204
2205
|
}
|
|
2205
2206
|
|
|
@@ -2697,10 +2698,9 @@ function simulateDelete(operation, virtual) {
|
|
|
2697
2698
|
import { existsSync as existsSync5, lstatSync as lstatSync3, readdirSync as readdirSync2 } from "node:fs";
|
|
2698
2699
|
import { dirname as dirname4, resolve as resolve5 } from "node:path";
|
|
2699
2700
|
class WorkspaceSnapshotBuilder {
|
|
2700
|
-
workspaceRoot;
|
|
2701
|
-
snapshots = new Map;
|
|
2702
2701
|
constructor(workspaceRoot) {
|
|
2703
2702
|
this.workspaceRoot = workspaceRoot;
|
|
2703
|
+
this.snapshots = new Map;
|
|
2704
2704
|
}
|
|
2705
2705
|
build(operations) {
|
|
2706
2706
|
this.add(this.workspaceRoot, false);
|
|
@@ -2744,8 +2744,10 @@ function snapshotOperations(operations, workspaceRoot) {
|
|
|
2744
2744
|
|
|
2745
2745
|
// ../lsp-core/src/lsp/workspace-edit-plan.ts
|
|
2746
2746
|
class PlanPathIndex {
|
|
2747
|
-
|
|
2748
|
-
|
|
2747
|
+
constructor() {
|
|
2748
|
+
this.firstChangeByPath = new Map;
|
|
2749
|
+
this.reportedPathByCanonical = new Map;
|
|
2750
|
+
}
|
|
2749
2751
|
build(operations) {
|
|
2750
2752
|
for (const operation of operations) {
|
|
2751
2753
|
switch (operation.kind) {
|
|
@@ -2834,14 +2836,11 @@ function isRecord4(value) {
|
|
|
2834
2836
|
}
|
|
2835
2837
|
|
|
2836
2838
|
class WorkspaceMutationController {
|
|
2837
|
-
workspaceRoot;
|
|
2838
|
-
documents;
|
|
2839
|
-
activeLease = null;
|
|
2840
|
-
nextLeaseId = 1;
|
|
2841
|
-
io;
|
|
2842
2839
|
constructor(workspaceRoot, documents) {
|
|
2843
2840
|
this.workspaceRoot = workspaceRoot;
|
|
2844
2841
|
this.documents = documents;
|
|
2842
|
+
this.activeLease = null;
|
|
2843
|
+
this.nextLeaseId = 1;
|
|
2845
2844
|
}
|
|
2846
2845
|
setIo(io) {
|
|
2847
2846
|
this.io = io;
|
|
@@ -2954,12 +2953,9 @@ var DIAGNOSTICS_FRESHNESS_TIMEOUT_MS = 3000;
|
|
|
2954
2953
|
var VERSIONLESS_PUBLISH_QUIESCENCE_MS = 250;
|
|
2955
2954
|
|
|
2956
2955
|
class LspClient extends LspClientConnection {
|
|
2957
|
-
diagnosticPullErrors = [];
|
|
2958
|
-
documents;
|
|
2959
|
-
workspaceMutations;
|
|
2960
|
-
diagnosticsFreshnessTimeoutMs;
|
|
2961
2956
|
constructor(root, server2, options = {}) {
|
|
2962
2957
|
super(root, server2, options);
|
|
2958
|
+
this.diagnosticPullErrors = [];
|
|
2963
2959
|
this.diagnosticsFreshnessTimeoutMs = options.diagnosticsFreshnessTimeoutMs ?? DIAGNOSTICS_FRESHNESS_TIMEOUT_MS;
|
|
2964
2960
|
this.documents = new WorkspaceDocumentState((method, params) => this.sendNotification(method, params), (uri) => this.diagnosticsStore.delete(uri), {
|
|
2965
2961
|
versionlessPublishQuiescenceMs: options.versionlessPublishQuiescenceMs ?? VERSIONLESS_PUBLISH_QUIESCENCE_MS
|
|
@@ -3014,6 +3010,18 @@ class LspClient extends LspClientConnection {
|
|
|
3014
3010
|
textDocument: { uri: pathToFileURL3(absPath).href }
|
|
3015
3011
|
}, options);
|
|
3016
3012
|
}
|
|
3013
|
+
async formatDocument(filePath, options, signal) {
|
|
3014
|
+
if (!this.isDocumentFormattingSupported())
|
|
3015
|
+
return null;
|
|
3016
|
+
const absPath = this.resolveWorkspacePath(filePath);
|
|
3017
|
+
await this.openFile(absPath);
|
|
3018
|
+
const requestOptions = signal === undefined ? {} : { signal };
|
|
3019
|
+
const edits = await this.sendRequest("textDocument/formatting", {
|
|
3020
|
+
textDocument: { uri: pathToFileURL3(absPath).href },
|
|
3021
|
+
options
|
|
3022
|
+
}, requestOptions);
|
|
3023
|
+
return edits ?? [];
|
|
3024
|
+
}
|
|
3017
3025
|
async workspaceSymbols(query, signal) {
|
|
3018
3026
|
const options = signal === undefined ? {} : { signal };
|
|
3019
3027
|
return this.sendRequest("workspace/symbol", { query }, options);
|
|
@@ -3259,18 +3267,14 @@ function awaitWithSignal(promise, signal) {
|
|
|
3259
3267
|
}
|
|
3260
3268
|
|
|
3261
3269
|
class LspManager {
|
|
3262
|
-
clients = new Map;
|
|
3263
|
-
reaperHandle = null;
|
|
3264
|
-
signalDisposer = null;
|
|
3265
|
-
disposed = false;
|
|
3266
|
-
idleTimeoutMs;
|
|
3267
|
-
initTimeoutMs;
|
|
3268
|
-
reaperIntervalMs;
|
|
3269
|
-
clientFactory;
|
|
3270
|
-
now;
|
|
3271
3270
|
constructor(options = {}) {
|
|
3271
|
+
this.clients = new Map;
|
|
3272
|
+
this.reaperHandle = null;
|
|
3273
|
+
this.signalDisposer = null;
|
|
3274
|
+
this.disposed = false;
|
|
3272
3275
|
this.idleTimeoutMs = options.idleTimeoutMs ?? IDLE_TIMEOUT_MS;
|
|
3273
3276
|
this.initTimeoutMs = options.initTimeoutMs ?? INIT_TIMEOUT_MS;
|
|
3277
|
+
this.maxResidentClients = options.maxResidentClients ?? MAX_RESIDENT_CLIENTS;
|
|
3274
3278
|
this.reaperIntervalMs = options.reaperIntervalMs ?? REAPER_INTERVAL_MS;
|
|
3275
3279
|
this.clientFactory = options.clientFactory ?? ((root, server2) => new LspClient(root, server2));
|
|
3276
3280
|
this.now = options.now ?? (() => Date.now());
|
|
@@ -3304,6 +3308,26 @@ class LspManager {
|
|
|
3304
3308
|
}
|
|
3305
3309
|
}
|
|
3306
3310
|
}
|
|
3311
|
+
evictForAdmission() {
|
|
3312
|
+
while (this.clients.size >= this.maxResidentClients) {
|
|
3313
|
+
const victim = this.leastRecentlyUsedIdleClient();
|
|
3314
|
+
if (!victim)
|
|
3315
|
+
return;
|
|
3316
|
+
this.clients.delete(victim.key);
|
|
3317
|
+
stopClientBestEffort(victim.managed.client);
|
|
3318
|
+
}
|
|
3319
|
+
}
|
|
3320
|
+
leastRecentlyUsedIdleClient() {
|
|
3321
|
+
let candidate = null;
|
|
3322
|
+
for (const [key, managed] of this.clients) {
|
|
3323
|
+
if (managed.refCount > 0 || managed.pendingWaiters > 0 || managed.isInitializing)
|
|
3324
|
+
continue;
|
|
3325
|
+
if (candidate === null || managed.lastUsedAt < candidate.managed.lastUsedAt) {
|
|
3326
|
+
candidate = { key, managed };
|
|
3327
|
+
}
|
|
3328
|
+
}
|
|
3329
|
+
return candidate;
|
|
3330
|
+
}
|
|
3307
3331
|
async tryDeleteIfOrphaned(key, managed) {
|
|
3308
3332
|
if (managed.refCount === 0 && managed.pendingWaiters === 0 && !managed.isInitializing && this.clients.get(key) === managed) {
|
|
3309
3333
|
this.clients.delete(key);
|
|
@@ -3350,6 +3374,7 @@ class LspManager {
|
|
|
3350
3374
|
managed.lastUsedAt = this.now();
|
|
3351
3375
|
return managed.client;
|
|
3352
3376
|
}
|
|
3377
|
+
this.evictForAdmission();
|
|
3353
3378
|
const client = this.clientFactory(root, server2);
|
|
3354
3379
|
const initStartedAt = this.now();
|
|
3355
3380
|
const initPromise = (async () => {
|
|
@@ -3412,6 +3437,7 @@ class LspManager {
|
|
|
3412
3437
|
const key = this.getKey(root, server2.id);
|
|
3413
3438
|
if (this.clients.has(key))
|
|
3414
3439
|
return;
|
|
3440
|
+
this.evictForAdmission();
|
|
3415
3441
|
const client = this.clientFactory(root, server2);
|
|
3416
3442
|
const initStartedAt = this.now();
|
|
3417
3443
|
const initPromise = (async () => {
|
|
@@ -3500,57 +3526,43 @@ async function disposeDefaultLspManager() {
|
|
|
3500
3526
|
}
|
|
3501
3527
|
}
|
|
3502
3528
|
|
|
3503
|
-
// ../lsp-core/src/lsp/
|
|
3504
|
-
import { existsSync as existsSync6,
|
|
3505
|
-
import { dirname as dirname5 } from "node:path";
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
|
|
3512
|
-
|
|
3513
|
-
|
|
3514
|
-
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
|
|
3529
|
+
// ../lsp-core/src/lsp/outside-context-workspace.ts
|
|
3530
|
+
import { existsSync as existsSync6, realpathSync as realpathSync4 } from "node:fs";
|
|
3531
|
+
import { dirname as dirname5, join as join3 } from "node:path";
|
|
3532
|
+
|
|
3533
|
+
// ../lsp-core/src/lsp/workspace-markers.ts
|
|
3534
|
+
var WORKSPACE_MARKERS = [".git", "package.json", "pyproject.toml", "Cargo.toml", "go.mod", "pom.xml", "build.gradle"];
|
|
3535
|
+
|
|
3536
|
+
// ../lsp-core/src/lsp/outside-context-workspace.ts
|
|
3537
|
+
function findWorkspaceRootOutsideContext(directory) {
|
|
3538
|
+
const marked = nearestMarkedAncestor(directory);
|
|
3539
|
+
if (marked !== undefined)
|
|
3540
|
+
return marked;
|
|
3541
|
+
return realpathSync4(nearestExistingAncestor(directory));
|
|
3542
|
+
}
|
|
3543
|
+
function nearestMarkedAncestor(directory) {
|
|
3544
|
+
let current = directory;
|
|
3545
|
+
for (;; ) {
|
|
3546
|
+
if (existsSync6(current) && WORKSPACE_MARKERS.some((marker) => existsSync6(join3(current, marker)))) {
|
|
3547
|
+
return realpathSync4(current);
|
|
3548
|
+
}
|
|
3549
|
+
const parent = dirname5(current);
|
|
3550
|
+
if (parent === current)
|
|
3551
|
+
return;
|
|
3552
|
+
current = parent;
|
|
3518
3553
|
}
|
|
3519
3554
|
}
|
|
3520
|
-
function
|
|
3521
|
-
|
|
3522
|
-
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
|
|
3526
|
-
|
|
3527
|
-
}
|
|
3528
|
-
|
|
3529
|
-
return value === "declined" || value === "allowed";
|
|
3530
|
-
}
|
|
3531
|
-
function writeInstallDecisions(decisions) {
|
|
3532
|
-
const path = getInstallDecisionsPath();
|
|
3533
|
-
mkdirSync(dirname5(path), { recursive: true });
|
|
3534
|
-
const tmpPath = `${path}.tmp`;
|
|
3535
|
-
writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
|
|
3536
|
-
`, "utf8");
|
|
3537
|
-
renameSync2(tmpPath, path);
|
|
3538
|
-
}
|
|
3539
|
-
function isInstallDecisions(value) {
|
|
3540
|
-
return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
|
|
3541
|
-
}
|
|
3542
|
-
function isInstallDecisionRecord(value) {
|
|
3543
|
-
if (!isRecord5(value))
|
|
3544
|
-
return false;
|
|
3545
|
-
return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
|
|
3546
|
-
}
|
|
3547
|
-
function isRecord5(value) {
|
|
3548
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3555
|
+
function nearestExistingAncestor(directory) {
|
|
3556
|
+
let current = directory;
|
|
3557
|
+
while (!existsSync6(current)) {
|
|
3558
|
+
const parent = dirname5(current);
|
|
3559
|
+
if (parent === current)
|
|
3560
|
+
return current;
|
|
3561
|
+
current = parent;
|
|
3562
|
+
}
|
|
3563
|
+
return current;
|
|
3549
3564
|
}
|
|
3550
3565
|
|
|
3551
|
-
// ../lsp-core/src/lsp/config-loader.ts
|
|
3552
|
-
import { existsSync as existsSync7, readFileSync as readFileSync4 } from "node:fs";
|
|
3553
|
-
|
|
3554
3566
|
// ../lsp-core/src/lsp/server-definitions.ts
|
|
3555
3567
|
var LSP_INSTALL_HINTS = {
|
|
3556
3568
|
typescript: "npm install -g typescript-language-server typescript",
|
|
@@ -3596,6 +3608,26 @@ var LSP_INSTALL_HINTS = {
|
|
|
3596
3608
|
julials: `julia -e 'using Pkg; Pkg.add("LanguageServer")'`,
|
|
3597
3609
|
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"
|
|
3598
3610
|
};
|
|
3611
|
+
var LSP_LOCAL_INSTALL_HINTS = {
|
|
3612
|
+
typescript: "bun add -d typescript-language-server typescript",
|
|
3613
|
+
vue: "bun add -d @vue/language-server",
|
|
3614
|
+
eslint: "bun add -d vscode-langservers-extracted",
|
|
3615
|
+
oxlint: "bun add -d oxlint",
|
|
3616
|
+
biome: "bun add -d @biomejs/biome",
|
|
3617
|
+
svelte: "bun add -d svelte-language-server",
|
|
3618
|
+
astro: "bun add -d @astrojs/language-server",
|
|
3619
|
+
bash: "bun add -d bash-language-server",
|
|
3620
|
+
"bash-ls": "bun add -d bash-language-server",
|
|
3621
|
+
"yaml-ls": "bun add -d yaml-language-server",
|
|
3622
|
+
php: "bun add -d intelephense",
|
|
3623
|
+
prisma: "bun add -d prisma",
|
|
3624
|
+
dockerfile: "bun add -d dockerfile-language-server-nodejs",
|
|
3625
|
+
pyright: "uv add --dev pyright",
|
|
3626
|
+
basedpyright: "uv add --dev basedpyright",
|
|
3627
|
+
ruff: "uv add --dev ruff",
|
|
3628
|
+
ty: "uv add --dev ty",
|
|
3629
|
+
"ruby-lsp": "bundle add ruby-lsp --group development"
|
|
3630
|
+
};
|
|
3599
3631
|
var BUILTIN_SERVERS = {
|
|
3600
3632
|
typescript: {
|
|
3601
3633
|
command: ["typescript-language-server", "--stdio"],
|
|
@@ -3698,7 +3730,56 @@ var BUILTIN_SERVERS = {
|
|
|
3698
3730
|
}
|
|
3699
3731
|
};
|
|
3700
3732
|
|
|
3733
|
+
// ../lsp-core/src/lsp/server-install-state.ts
|
|
3734
|
+
import { existsSync as existsSync7, mkdirSync, readFileSync as readFileSync3, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
3735
|
+
import { dirname as dirname6 } from "node:path";
|
|
3736
|
+
function getInstallDecisionsPath() {
|
|
3737
|
+
return lspRequestContext().installDecisionsPath;
|
|
3738
|
+
}
|
|
3739
|
+
function loadInstallDecisions() {
|
|
3740
|
+
const path = getInstallDecisionsPath();
|
|
3741
|
+
if (!existsSync7(path))
|
|
3742
|
+
return {};
|
|
3743
|
+
try {
|
|
3744
|
+
const parsed = JSON.parse(readFileSync3(path, "utf8"));
|
|
3745
|
+
return isInstallDecisions(parsed) ? parsed : {};
|
|
3746
|
+
} catch {
|
|
3747
|
+
return {};
|
|
3748
|
+
}
|
|
3749
|
+
}
|
|
3750
|
+
function loadInstallDecision(serverId) {
|
|
3751
|
+
return loadInstallDecisions()[serverId];
|
|
3752
|
+
}
|
|
3753
|
+
function recordInstallDecision(serverId, decision, decidedAt = new Date().toISOString()) {
|
|
3754
|
+
const decisions = loadInstallDecisions();
|
|
3755
|
+
decisions[serverId] = { decision, decidedAt };
|
|
3756
|
+
writeInstallDecisions(decisions);
|
|
3757
|
+
}
|
|
3758
|
+
function isInstallDecision(value) {
|
|
3759
|
+
return value === "declined" || value === "allowed";
|
|
3760
|
+
}
|
|
3761
|
+
function writeInstallDecisions(decisions) {
|
|
3762
|
+
const path = getInstallDecisionsPath();
|
|
3763
|
+
mkdirSync(dirname6(path), { recursive: true });
|
|
3764
|
+
const tmpPath = `${path}.tmp`;
|
|
3765
|
+
writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
|
|
3766
|
+
`, "utf8");
|
|
3767
|
+
renameSync2(tmpPath, path);
|
|
3768
|
+
}
|
|
3769
|
+
function isInstallDecisions(value) {
|
|
3770
|
+
return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
|
|
3771
|
+
}
|
|
3772
|
+
function isInstallDecisionRecord(value) {
|
|
3773
|
+
if (!isRecord5(value))
|
|
3774
|
+
return false;
|
|
3775
|
+
return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
|
|
3776
|
+
}
|
|
3777
|
+
function isRecord5(value) {
|
|
3778
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3779
|
+
}
|
|
3780
|
+
|
|
3701
3781
|
// ../lsp-core/src/lsp/config-loader.ts
|
|
3782
|
+
import { existsSync as existsSync8, readFileSync as readFileSync4 } from "node:fs";
|
|
3702
3783
|
function getProjectConfigPaths() {
|
|
3703
3784
|
return lspRequestContext().projectConfigPaths;
|
|
3704
3785
|
}
|
|
@@ -3706,7 +3787,7 @@ function getUserConfigPath() {
|
|
|
3706
3787
|
return lspRequestContext().userConfigPath;
|
|
3707
3788
|
}
|
|
3708
3789
|
function loadJsonFile(path) {
|
|
3709
|
-
if (!
|
|
3790
|
+
if (!existsSync8(path))
|
|
3710
3791
|
return null;
|
|
3711
3792
|
try {
|
|
3712
3793
|
const parsed = JSON.parse(readFileSync4(path, "utf-8"));
|
|
@@ -3894,54 +3975,155 @@ function getDisabledServerIds() {
|
|
|
3894
3975
|
}
|
|
3895
3976
|
|
|
3896
3977
|
// ../lsp-core/src/lsp/server-installation.ts
|
|
3897
|
-
import { existsSync as
|
|
3898
|
-
import { delimiter as delimiter3, join as
|
|
3899
|
-
|
|
3900
|
-
|
|
3901
|
-
|
|
3902
|
-
|
|
3903
|
-
|
|
3904
|
-
|
|
3905
|
-
|
|
3906
|
-
|
|
3907
|
-
|
|
3978
|
+
import { existsSync as existsSync9 } from "node:fs";
|
|
3979
|
+
import { delimiter as delimiter3, dirname as dirname7, isAbsolute as isAbsolute3, join as join4, resolve as resolve7 } from "node:path";
|
|
3980
|
+
var LOCAL_BIN_RULES = [
|
|
3981
|
+
{
|
|
3982
|
+
markers: ["package.json", "bun.lock", "bun.lockb", "package-lock.json", "yarn.lock", "pnpm-lock.yaml"],
|
|
3983
|
+
binDirs: [join4("node_modules", ".bin")]
|
|
3984
|
+
},
|
|
3985
|
+
{
|
|
3986
|
+
markers: [
|
|
3987
|
+
"pyproject.toml",
|
|
3988
|
+
"ty.toml",
|
|
3989
|
+
"requirements.txt",
|
|
3990
|
+
"setup.py",
|
|
3991
|
+
"setup.cfg",
|
|
3992
|
+
"Pipfile",
|
|
3993
|
+
"pyrightconfig.json",
|
|
3994
|
+
"ruff.toml",
|
|
3995
|
+
".ruff.toml"
|
|
3996
|
+
],
|
|
3997
|
+
binDirs: [
|
|
3998
|
+
join4(".venv", "bin"),
|
|
3999
|
+
join4(".venv", "Scripts"),
|
|
4000
|
+
join4("venv", "bin"),
|
|
4001
|
+
join4("venv", "Scripts"),
|
|
4002
|
+
join4(".env", "bin"),
|
|
4003
|
+
join4(".env", "Scripts")
|
|
4004
|
+
]
|
|
4005
|
+
},
|
|
4006
|
+
{
|
|
4007
|
+
markers: ["Gemfile", "Gemfile.lock"],
|
|
4008
|
+
binDirs: [join4("vendor", "bundle", "bin"), "bin"]
|
|
4009
|
+
},
|
|
4010
|
+
{
|
|
4011
|
+
markers: ["go.mod", "go.sum", "go.work"],
|
|
4012
|
+
binDirs: ["bin"]
|
|
4013
|
+
}
|
|
4014
|
+
];
|
|
4015
|
+
var resolutionCache = new Map;
|
|
4016
|
+
var probeCount = 0;
|
|
4017
|
+
function probe(path) {
|
|
4018
|
+
probeCount += 1;
|
|
4019
|
+
return existsSync9(path);
|
|
4020
|
+
}
|
|
4021
|
+
function executableSuffixes(platform, pathExt) {
|
|
4022
|
+
if (platform !== "win32")
|
|
4023
|
+
return [""];
|
|
4024
|
+
const configured = pathExt ?? process.env["PATHEXT"] ?? "";
|
|
4025
|
+
const systemExts = configured.split(";").filter((entry) => entry.length > 0).map((entry) => entry.toLowerCase());
|
|
4026
|
+
return [...new Set(["", ...systemExts, ".exe", ".cmd", ".bat", ".ps1"])];
|
|
4027
|
+
}
|
|
4028
|
+
function probeWithSuffixes(directory, command, suffixes) {
|
|
4029
|
+
for (const suffix of suffixes) {
|
|
4030
|
+
const candidate = join4(directory, command + suffix);
|
|
4031
|
+
if (probe(candidate))
|
|
4032
|
+
return candidate;
|
|
3908
4033
|
}
|
|
3909
|
-
|
|
3910
|
-
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
|
|
3915
|
-
|
|
3916
|
-
|
|
3917
|
-
|
|
4034
|
+
return null;
|
|
4035
|
+
}
|
|
4036
|
+
function resolveLocal(command, workingDirectory, suffixes, stopAt) {
|
|
4037
|
+
const boundary = stopAt === undefined ? undefined : resolve7(stopAt);
|
|
4038
|
+
let current = resolve7(workingDirectory);
|
|
4039
|
+
while (true) {
|
|
4040
|
+
for (const rule of LOCAL_BIN_RULES) {
|
|
4041
|
+
if (!rule.markers.some((marker) => probe(join4(current, marker))))
|
|
4042
|
+
continue;
|
|
4043
|
+
for (const binDir of rule.binDirs) {
|
|
4044
|
+
const found = probeWithSuffixes(join4(current, binDir), command, suffixes);
|
|
4045
|
+
if (found !== null)
|
|
4046
|
+
return found;
|
|
4047
|
+
}
|
|
3918
4048
|
}
|
|
4049
|
+
if (probe(join4(current, ".git")))
|
|
4050
|
+
return null;
|
|
4051
|
+
if (boundary !== undefined && current === boundary)
|
|
4052
|
+
return null;
|
|
4053
|
+
const parent = dirname7(current);
|
|
4054
|
+
if (parent === current)
|
|
4055
|
+
return null;
|
|
4056
|
+
current = parent;
|
|
3919
4057
|
}
|
|
3920
|
-
|
|
3921
|
-
|
|
4058
|
+
}
|
|
4059
|
+
function resolveFromPath(command, suffixes, platform, pathEnvOverride) {
|
|
4060
|
+
let pathEnv = pathEnvOverride ?? process.env["PATH"] ?? "";
|
|
4061
|
+
if (platform === "win32" && !pathEnv) {
|
|
3922
4062
|
pathEnv = process.env["Path"] ?? "";
|
|
3923
4063
|
}
|
|
3924
|
-
const
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
}
|
|
4064
|
+
for (const entry of pathEnv.split(delimiter3)) {
|
|
4065
|
+
if (entry.length === 0)
|
|
4066
|
+
continue;
|
|
4067
|
+
const found = probeWithSuffixes(entry, command, suffixes);
|
|
4068
|
+
if (found !== null)
|
|
4069
|
+
return found;
|
|
3931
4070
|
}
|
|
3932
|
-
|
|
3933
|
-
|
|
3934
|
-
|
|
4071
|
+
return null;
|
|
4072
|
+
}
|
|
4073
|
+
function resolveServerBinary(command, workingDirectory, options = {}) {
|
|
4074
|
+
if (command.length === 0)
|
|
4075
|
+
return null;
|
|
4076
|
+
const [cmd] = command;
|
|
4077
|
+
if (cmd === undefined || cmd.length === 0)
|
|
4078
|
+
return null;
|
|
4079
|
+
const platform = options.platform ?? process.platform;
|
|
4080
|
+
const suffixes = executableSuffixes(platform, options.pathExt);
|
|
4081
|
+
if (cmd.includes("/") || cmd.includes("\\")) {
|
|
4082
|
+
const explicit = isAbsolute3(cmd) ? cmd : resolve7(workingDirectory ?? process.cwd(), cmd);
|
|
4083
|
+
return probe(explicit) ? explicit : null;
|
|
4084
|
+
}
|
|
4085
|
+
const cacheKey = JSON.stringify([
|
|
4086
|
+
workingDirectory ?? "",
|
|
4087
|
+
cmd,
|
|
4088
|
+
platform,
|
|
4089
|
+
options.stopAt ?? "",
|
|
4090
|
+
options.pathExt ?? "",
|
|
4091
|
+
options.pathEnv ?? process.env["PATH"] ?? ""
|
|
4092
|
+
]);
|
|
4093
|
+
const cached = resolutionCache.get(cacheKey);
|
|
4094
|
+
if (cached !== undefined)
|
|
4095
|
+
return cached;
|
|
4096
|
+
let resolved = null;
|
|
4097
|
+
if (workingDirectory !== undefined && workingDirectory.length > 0) {
|
|
4098
|
+
resolved = resolveLocal(cmd, workingDirectory, suffixes, options.stopAt);
|
|
4099
|
+
}
|
|
4100
|
+
resolved ??= resolveFromPath(cmd, suffixes, platform, options.pathEnv);
|
|
4101
|
+
if (resolved === null && cmd === "node")
|
|
4102
|
+
resolved = cmd;
|
|
4103
|
+
resolutionCache.set(cacheKey, resolved);
|
|
4104
|
+
return resolved;
|
|
4105
|
+
}
|
|
4106
|
+
function isServerInstalled(command, workingDirectory, options = {}) {
|
|
4107
|
+
if (command.length === 0)
|
|
4108
|
+
return false;
|
|
4109
|
+
return resolveServerBinary(command, workingDirectory, options) !== null;
|
|
3935
4110
|
}
|
|
3936
4111
|
|
|
3937
4112
|
// ../lsp-core/src/lsp/server-resolution.ts
|
|
4113
|
+
function withResolvedCommand(command, binaryPath) {
|
|
4114
|
+
return [binaryPath, ...command.slice(1)];
|
|
4115
|
+
}
|
|
3938
4116
|
function findServerForExtension(ext) {
|
|
3939
4117
|
const servers = getMergedServers();
|
|
4118
|
+
const workingDirectory = contextCwd();
|
|
3940
4119
|
for (const server2 of servers) {
|
|
3941
|
-
if (server2.extensions.includes(ext)
|
|
4120
|
+
if (!server2.extensions.includes(ext))
|
|
4121
|
+
continue;
|
|
4122
|
+
const binaryPath = resolveServerBinary(server2.command, workingDirectory);
|
|
4123
|
+
if (binaryPath !== null) {
|
|
3942
4124
|
const resolvedServer = {
|
|
3943
4125
|
id: server2.id,
|
|
3944
|
-
command: server2.command,
|
|
4126
|
+
command: withResolvedCommand(server2.command, binaryPath),
|
|
3945
4127
|
extensions: server2.extensions,
|
|
3946
4128
|
priority: server2.priority
|
|
3947
4129
|
};
|
|
@@ -3988,6 +4170,7 @@ function findServerForExtension(ext) {
|
|
|
3988
4170
|
function getAllServers() {
|
|
3989
4171
|
const servers = getMergedServers();
|
|
3990
4172
|
const disabled = getDisabledServerIds();
|
|
4173
|
+
const workingDirectory = contextCwd();
|
|
3991
4174
|
const result = [];
|
|
3992
4175
|
const seen = new Set;
|
|
3993
4176
|
for (const server2 of servers) {
|
|
@@ -3995,7 +4178,7 @@ function getAllServers() {
|
|
|
3995
4178
|
continue;
|
|
3996
4179
|
result.push({
|
|
3997
4180
|
id: server2.id,
|
|
3998
|
-
installed: isServerInstalled(server2.command),
|
|
4181
|
+
installed: isServerInstalled(server2.command, workingDirectory),
|
|
3999
4182
|
extensions: server2.extensions,
|
|
4000
4183
|
disabled: false,
|
|
4001
4184
|
source: server2.source,
|
|
@@ -4009,7 +4192,7 @@ function getAllServers() {
|
|
|
4009
4192
|
const builtin = BUILTIN_SERVERS[id];
|
|
4010
4193
|
result.push({
|
|
4011
4194
|
id,
|
|
4012
|
-
installed: builtin ? isServerInstalled(builtin.command) : false,
|
|
4195
|
+
installed: builtin ? isServerInstalled(builtin.command, workingDirectory) : false,
|
|
4013
4196
|
extensions: builtin?.extensions ?? [],
|
|
4014
4197
|
disabled: true,
|
|
4015
4198
|
source: "disabled",
|
|
@@ -4020,7 +4203,6 @@ function getAllServers() {
|
|
|
4020
4203
|
}
|
|
4021
4204
|
|
|
4022
4205
|
// ../lsp-core/src/lsp/client-wrapper.ts
|
|
4023
|
-
var WORKSPACE_MARKERS = [".git", "package.json", "pyproject.toml", "Cargo.toml", "go.mod", "pom.xml", "build.gradle"];
|
|
4024
4206
|
function isDirectoryPath(filePath) {
|
|
4025
4207
|
try {
|
|
4026
4208
|
return statSync3(filePath).isDirectory();
|
|
@@ -4029,32 +4211,85 @@ function isDirectoryPath(filePath) {
|
|
|
4029
4211
|
}
|
|
4030
4212
|
}
|
|
4031
4213
|
function findWorkspaceRoot(filePath) {
|
|
4032
|
-
const
|
|
4214
|
+
const cwd = contextCwd();
|
|
4215
|
+
const abs = resolveReadablePathInsideContext(filePath);
|
|
4033
4216
|
let dir = abs;
|
|
4034
4217
|
if (!isDirectoryPath(dir)) {
|
|
4035
|
-
dir =
|
|
4036
|
-
}
|
|
4037
|
-
|
|
4038
|
-
|
|
4039
|
-
|
|
4040
|
-
|
|
4041
|
-
|
|
4218
|
+
dir = dirname8(dir);
|
|
4219
|
+
}
|
|
4220
|
+
if (!isPathInside(cwd, abs))
|
|
4221
|
+
return findWorkspaceRootOutsideContext(dir);
|
|
4222
|
+
const fallbackRoot = nearestExistingDirectoryInsideContext(dir, cwd) ?? cwd;
|
|
4223
|
+
while (isPathInside(cwd, dir)) {
|
|
4224
|
+
const canonicalDir = existingDirectoryInsideContext(dir, cwd);
|
|
4225
|
+
if (canonicalDir !== undefined) {
|
|
4226
|
+
for (const marker of WORKSPACE_MARKERS) {
|
|
4227
|
+
if (existsSync10(join5(dir, marker))) {
|
|
4228
|
+
return canonicalDir;
|
|
4229
|
+
}
|
|
4042
4230
|
}
|
|
4043
4231
|
}
|
|
4044
|
-
|
|
4045
|
-
|
|
4232
|
+
if (dir === cwd)
|
|
4233
|
+
break;
|
|
4234
|
+
dir = dirname8(dir);
|
|
4046
4235
|
}
|
|
4047
|
-
return
|
|
4236
|
+
return fallbackRoot;
|
|
4237
|
+
}
|
|
4238
|
+
function resolveReadablePathInsideContext(filePath) {
|
|
4239
|
+
const cwd = contextCwd();
|
|
4240
|
+
const abs = resolve8(cwd, filePath);
|
|
4241
|
+
if (isPathInside(cwd, abs))
|
|
4242
|
+
return abs;
|
|
4243
|
+
const rebased = rebaseThroughCanonicalAncestor(abs, cwd);
|
|
4244
|
+
if (rebased !== undefined)
|
|
4245
|
+
return rebased;
|
|
4246
|
+
return canonicalizeExistingOrNearestAncestor(abs);
|
|
4048
4247
|
}
|
|
4049
4248
|
function resolvePathInsideContext(filePath) {
|
|
4050
4249
|
const cwd = contextCwd();
|
|
4051
|
-
const abs =
|
|
4250
|
+
const abs = resolveReadablePathInsideContext(filePath);
|
|
4052
4251
|
const canonical = canonicalizeExistingOrNearestAncestor(abs);
|
|
4053
4252
|
if (!isPathInside(cwd, canonical)) {
|
|
4054
4253
|
throw new LspInvalidPathError(`LSP file path must be inside request cwd: ${filePath}`);
|
|
4055
4254
|
}
|
|
4056
4255
|
return canonical;
|
|
4057
4256
|
}
|
|
4257
|
+
function rebaseThroughCanonicalAncestor(path, cwd) {
|
|
4258
|
+
let current = path;
|
|
4259
|
+
const suffix = [];
|
|
4260
|
+
while (true) {
|
|
4261
|
+
if (existsSync10(current)) {
|
|
4262
|
+
const canonical = realpathSync5(current);
|
|
4263
|
+
if (isPathInside(cwd, canonical))
|
|
4264
|
+
return suffix.length === 0 ? canonical : join5(canonical, ...suffix);
|
|
4265
|
+
}
|
|
4266
|
+
const parent = dirname8(current);
|
|
4267
|
+
if (parent === current)
|
|
4268
|
+
return;
|
|
4269
|
+
suffix.unshift(basename3(current));
|
|
4270
|
+
current = parent;
|
|
4271
|
+
}
|
|
4272
|
+
}
|
|
4273
|
+
function existingDirectoryInsideContext(directory, cwd) {
|
|
4274
|
+
if (!existsSync10(directory))
|
|
4275
|
+
return;
|
|
4276
|
+
const canonical = realpathSync5(directory);
|
|
4277
|
+
if (!statSync3(canonical).isDirectory())
|
|
4278
|
+
return;
|
|
4279
|
+
return isPathInside(cwd, canonical) ? canonical : undefined;
|
|
4280
|
+
}
|
|
4281
|
+
function nearestExistingDirectoryInsideContext(directory, cwd) {
|
|
4282
|
+
let current = directory;
|
|
4283
|
+
while (isPathInside(cwd, current)) {
|
|
4284
|
+
const canonical = existingDirectoryInsideContext(current, cwd);
|
|
4285
|
+
if (canonical !== undefined)
|
|
4286
|
+
return canonical;
|
|
4287
|
+
if (current === cwd)
|
|
4288
|
+
return;
|
|
4289
|
+
current = dirname8(current);
|
|
4290
|
+
}
|
|
4291
|
+
return;
|
|
4292
|
+
}
|
|
4058
4293
|
function formatServerLookupError(result) {
|
|
4059
4294
|
if (result.status === "not_installed") {
|
|
4060
4295
|
return formatNotInstalled(result);
|
|
@@ -4078,6 +4313,19 @@ function formatServerLookupError(result) {
|
|
|
4078
4313
|
].join(`
|
|
4079
4314
|
`);
|
|
4080
4315
|
}
|
|
4316
|
+
function formatInstallOptions(serverId, installHint) {
|
|
4317
|
+
const localHint = LSP_LOCAL_INSTALL_HINTS[serverId];
|
|
4318
|
+
if (localHint === undefined) {
|
|
4319
|
+
return ["To install, run:", ` ${installHint}`];
|
|
4320
|
+
}
|
|
4321
|
+
return [
|
|
4322
|
+
"To install in THIS repository (preferred — no global install needed):",
|
|
4323
|
+
` ${localHint}`,
|
|
4324
|
+
"",
|
|
4325
|
+
"Or install it globally:",
|
|
4326
|
+
` ${installHint}`
|
|
4327
|
+
];
|
|
4328
|
+
}
|
|
4081
4329
|
function formatNotInstalled(result) {
|
|
4082
4330
|
const { server: server2, installHint } = result;
|
|
4083
4331
|
const extensions = server2.extensions.join(", ");
|
|
@@ -4092,19 +4340,19 @@ function formatNotInstalled(result) {
|
|
|
4092
4340
|
`Command not found: ${server2.command[0]}`,
|
|
4093
4341
|
""
|
|
4094
4342
|
];
|
|
4343
|
+
const installOptions = formatInstallOptions(server2.id, installHint);
|
|
4095
4344
|
if (decision === "allowed") {
|
|
4096
4345
|
return [
|
|
4097
4346
|
...header,
|
|
4098
4347
|
"The user has pre-authorized LSP installation. Run the install command, then retry this tool:",
|
|
4099
|
-
|
|
4348
|
+
...installOptions.slice(1)
|
|
4100
4349
|
].join(`
|
|
4101
4350
|
`);
|
|
4102
4351
|
}
|
|
4103
4352
|
if (!context.capabilities.installDecisionTool) {
|
|
4104
4353
|
return [
|
|
4105
4354
|
...header,
|
|
4106
|
-
|
|
4107
|
-
` ${installHint}`,
|
|
4355
|
+
...installOptions,
|
|
4108
4356
|
"",
|
|
4109
4357
|
"ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
|
|
4110
4358
|
"Install-decision recording is unavailable in this harness; proceed without LSP if the user declines."
|
|
@@ -4113,8 +4361,7 @@ function formatNotInstalled(result) {
|
|
|
4113
4361
|
}
|
|
4114
4362
|
return [
|
|
4115
4363
|
...header,
|
|
4116
|
-
|
|
4117
|
-
` ${installHint}`,
|
|
4364
|
+
...installOptions,
|
|
4118
4365
|
"",
|
|
4119
4366
|
"ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
|
|
4120
4367
|
"- If the user agrees: run the install command above, then retry this tool.",
|
|
@@ -4125,7 +4372,7 @@ function formatNotInstalled(result) {
|
|
|
4125
4372
|
].join(`
|
|
4126
4373
|
`);
|
|
4127
4374
|
}
|
|
4128
|
-
var
|
|
4375
|
+
var READ_ONLY_TOOLS = new Set([
|
|
4129
4376
|
"diagnostics",
|
|
4130
4377
|
"definition",
|
|
4131
4378
|
"references",
|
|
@@ -4134,7 +4381,7 @@ var READ_ONLY_RETRY_TOOLS = new Set([
|
|
|
4134
4381
|
"prepareRename"
|
|
4135
4382
|
]);
|
|
4136
4383
|
async function withLspClient(filePath, fn, toolName, options = {}) {
|
|
4137
|
-
const absPath = resolvePathInsideContext(filePath);
|
|
4384
|
+
const absPath = READ_ONLY_TOOLS.has(toolName) ? resolveReadablePathInsideContext(filePath) : resolvePathInsideContext(filePath);
|
|
4138
4385
|
if (isDirectoryPath(absPath)) {
|
|
4139
4386
|
throw new LspInvalidPathError("Directory paths are not supported by this LSP tool. " + "Use lsp.diagnostics with a directory path for directory diagnostics.");
|
|
4140
4387
|
}
|
|
@@ -4149,9 +4396,9 @@ async function withLspClient(filePath, fn, toolName, options = {}) {
|
|
|
4149
4396
|
const acquireAndCall = async (allowRetry) => {
|
|
4150
4397
|
const client = await manager.getClient(root, server2, options.signal);
|
|
4151
4398
|
try {
|
|
4152
|
-
return await fn(client, root);
|
|
4399
|
+
return await fn(client, root, absPath);
|
|
4153
4400
|
} catch (err) {
|
|
4154
|
-
if (allowRetry &&
|
|
4401
|
+
if (allowRetry && READ_ONLY_TOOLS.has(toolName) && isLspDeadConnectionError(err)) {
|
|
4155
4402
|
manager.invalidateClient(root, server2.id, client);
|
|
4156
4403
|
return acquireAndCall(false);
|
|
4157
4404
|
}
|
|
@@ -4169,8 +4416,8 @@ async function withLspClient(filePath, fn, toolName, options = {}) {
|
|
|
4169
4416
|
}
|
|
4170
4417
|
|
|
4171
4418
|
// ../lsp-core/src/lsp/directory-diagnostics.ts
|
|
4172
|
-
import { existsSync as
|
|
4173
|
-
import { join as
|
|
4419
|
+
import { existsSync as existsSync11, lstatSync as lstatSync4, readdirSync as readdirSync3 } from "node:fs";
|
|
4420
|
+
import { join as join6, resolve as resolve9 } from "node:path";
|
|
4174
4421
|
|
|
4175
4422
|
// ../lsp-core/src/lsp/formatters.ts
|
|
4176
4423
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
@@ -4300,7 +4547,7 @@ function collectFilesWithExtension(dir, extension, maxFiles) {
|
|
|
4300
4547
|
for (const entry of entries) {
|
|
4301
4548
|
if (files.length >= maxFiles)
|
|
4302
4549
|
return;
|
|
4303
|
-
const fullPath =
|
|
4550
|
+
const fullPath = join6(currentDir, entry);
|
|
4304
4551
|
let stat;
|
|
4305
4552
|
try {
|
|
4306
4553
|
stat = lstatSync4(fullPath);
|
|
@@ -4325,8 +4572,8 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
|
|
|
4325
4572
|
if (!extension.startsWith(".")) {
|
|
4326
4573
|
throw new LspInvalidPathError(`Extension must start with a dot (e.g., ".ts", not "${extension}"). Use ".${extension}" instead.`);
|
|
4327
4574
|
}
|
|
4328
|
-
const absDir =
|
|
4329
|
-
if (!
|
|
4575
|
+
const absDir = resolve9(options.workspaceRoot ?? contextCwd(), directory);
|
|
4576
|
+
if (!existsSync11(absDir)) {
|
|
4330
4577
|
throw new LspInvalidPathError(`Directory does not exist: ${absDir}`);
|
|
4331
4578
|
}
|
|
4332
4579
|
const serverResult = options.server === undefined ? findServerForExtension(extension) : { status: "found", server: options.server };
|
|
@@ -4413,7 +4660,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
|
|
|
4413
4660
|
|
|
4414
4661
|
// ../lsp-core/src/lsp/infer-extension.ts
|
|
4415
4662
|
import { lstatSync as lstatSync5, readdirSync as readdirSync4 } from "node:fs";
|
|
4416
|
-
import { join as
|
|
4663
|
+
import { join as join7 } from "node:path";
|
|
4417
4664
|
var SKIP_DIRECTORIES2 = new Set(["node_modules", ".git", "dist", "build", ".next", "out"]);
|
|
4418
4665
|
var MAX_SCAN_ENTRIES = 500;
|
|
4419
4666
|
function inferExtensionFromDirectory(directory) {
|
|
@@ -4431,7 +4678,7 @@ function inferExtensionFromDirectory(directory) {
|
|
|
4431
4678
|
for (const entry of entries) {
|
|
4432
4679
|
if (scanned >= MAX_SCAN_ENTRIES)
|
|
4433
4680
|
return;
|
|
4434
|
-
const fullPath =
|
|
4681
|
+
const fullPath = join7(dir, entry);
|
|
4435
4682
|
let stat;
|
|
4436
4683
|
try {
|
|
4437
4684
|
stat = lstatSync5(fullPath);
|
|
@@ -4606,7 +4853,7 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
4606
4853
|
const filePath = requireString(params, "filePath");
|
|
4607
4854
|
const severity = severityFilter(params);
|
|
4608
4855
|
try {
|
|
4609
|
-
const absPath =
|
|
4856
|
+
const absPath = resolveReadablePathInsideContext(filePath);
|
|
4610
4857
|
if (isDirectoryPath(absPath)) {
|
|
4611
4858
|
const extension = inferExtensionFromDirectory(absPath);
|
|
4612
4859
|
if (!extension) {
|
|
@@ -4635,7 +4882,7 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
4635
4882
|
};
|
|
4636
4883
|
return text(output2.output, details2);
|
|
4637
4884
|
}
|
|
4638
|
-
const result = await withLspClient(filePath, async (client) => client.diagnostics(
|
|
4885
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.diagnostics(resolvedFilePath, signal), "diagnostics", clientOptions(signal));
|
|
4639
4886
|
if (result.transientError) {
|
|
4640
4887
|
const message = result.transientError.message;
|
|
4641
4888
|
const details2 = {
|
|
@@ -4682,6 +4929,96 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
4682
4929
|
throw error;
|
|
4683
4930
|
}
|
|
4684
4931
|
}
|
|
4932
|
+
// ../lsp-core/src/lsp/format-document.ts
|
|
4933
|
+
import { readFileSync as readFileSync5, renameSync as renameSync3, unlinkSync, writeFileSync as writeFileSync3 } from "node:fs";
|
|
4934
|
+
var DEFAULT_FORMATTING_OPTIONS = {
|
|
4935
|
+
tabSize: 4,
|
|
4936
|
+
insertSpaces: false,
|
|
4937
|
+
trimTrailingWhitespace: true,
|
|
4938
|
+
insertFinalNewline: true,
|
|
4939
|
+
trimFinalNewlines: true
|
|
4940
|
+
};
|
|
4941
|
+
var UNCHANGED = { status: "unchanged", linesAdded: 0, linesRemoved: 0 };
|
|
4942
|
+
async function formatDocumentWithClient(client, filePath, options = {}) {
|
|
4943
|
+
const edits = await client.formatDocument(filePath, options.formattingOptions ?? DEFAULT_FORMATTING_OPTIONS, options.signal);
|
|
4944
|
+
if (edits === null)
|
|
4945
|
+
return { status: "unavailable", reason: "capability_not_advertised" };
|
|
4946
|
+
if (edits.length === 0)
|
|
4947
|
+
return UNCHANGED;
|
|
4948
|
+
const before = readFileSync5(filePath, "utf-8");
|
|
4949
|
+
const normalized = normalizeTextEdits(before, edits, 0);
|
|
4950
|
+
if (normalized.text === before)
|
|
4951
|
+
return UNCHANGED;
|
|
4952
|
+
writeAtomically(filePath, normalized.text);
|
|
4953
|
+
await client.openFile(filePath);
|
|
4954
|
+
return {
|
|
4955
|
+
status: "formatted",
|
|
4956
|
+
...lineDelta(normalized.edits)
|
|
4957
|
+
};
|
|
4958
|
+
}
|
|
4959
|
+
function lineDelta(edits) {
|
|
4960
|
+
let linesAdded = 0;
|
|
4961
|
+
let linesRemoved = 0;
|
|
4962
|
+
for (const edit of edits) {
|
|
4963
|
+
linesRemoved += edit.range.end.line - edit.range.start.line + 1;
|
|
4964
|
+
linesAdded += edit.newText.split(`
|
|
4965
|
+
`).length;
|
|
4966
|
+
}
|
|
4967
|
+
return { linesAdded, linesRemoved };
|
|
4968
|
+
}
|
|
4969
|
+
function writeAtomically(filePath, content) {
|
|
4970
|
+
const tempPath = `${filePath}.omo-format.tmp`;
|
|
4971
|
+
writeFileSync3(tempPath, content, "utf-8");
|
|
4972
|
+
try {
|
|
4973
|
+
renameSync3(tempPath, filePath);
|
|
4974
|
+
} catch (error) {
|
|
4975
|
+
try {
|
|
4976
|
+
unlinkSync(tempPath);
|
|
4977
|
+
} catch {}
|
|
4978
|
+
throw error;
|
|
4979
|
+
}
|
|
4980
|
+
}
|
|
4981
|
+
|
|
4982
|
+
// ../lsp-core/src/tools/format.ts
|
|
4983
|
+
async function executeLspFormat(params, signal) {
|
|
4984
|
+
const filePath = requireString(params, "filePath");
|
|
4985
|
+
try {
|
|
4986
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => formatDocumentWithClient(client, resolvedFilePath, signal === undefined ? {} : { signal }), "format", clientOptions(signal));
|
|
4987
|
+
return text(describeResult(filePath, result), formatDetails(filePath, result));
|
|
4988
|
+
} catch (error) {
|
|
4989
|
+
const missingDependency = missingDependencyResult(error, {
|
|
4990
|
+
filePath,
|
|
4991
|
+
status: "unavailable",
|
|
4992
|
+
reason: "server_unavailable",
|
|
4993
|
+
linesAdded: 0,
|
|
4994
|
+
linesRemoved: 0
|
|
4995
|
+
});
|
|
4996
|
+
if (missingDependency)
|
|
4997
|
+
return missingDependency;
|
|
4998
|
+
throw error;
|
|
4999
|
+
}
|
|
5000
|
+
}
|
|
5001
|
+
function formatDetails(filePath, result) {
|
|
5002
|
+
if (result.status === "unavailable") {
|
|
5003
|
+
return { filePath, status: "unavailable", reason: result.reason, linesAdded: 0, linesRemoved: 0 };
|
|
5004
|
+
}
|
|
5005
|
+
return {
|
|
5006
|
+
filePath,
|
|
5007
|
+
status: result.status,
|
|
5008
|
+
linesAdded: result.linesAdded,
|
|
5009
|
+
linesRemoved: result.linesRemoved
|
|
5010
|
+
};
|
|
5011
|
+
}
|
|
5012
|
+
function describeResult(filePath, result) {
|
|
5013
|
+
if (result.status === "unavailable") {
|
|
5014
|
+
return `Formatting unavailable for ${filePath}: the language server does not advertise documentFormattingProvider.`;
|
|
5015
|
+
}
|
|
5016
|
+
if (result.status === "unchanged") {
|
|
5017
|
+
return `Already formatted: ${filePath}`;
|
|
5018
|
+
}
|
|
5019
|
+
return `Formatted ${filePath} (+${result.linesAdded}/-${result.linesRemoved} lines)`;
|
|
5020
|
+
}
|
|
5021
|
+
|
|
4685
5022
|
// ../lsp-core/src/tools/install-decision.ts
|
|
4686
5023
|
async function executeLspInstallDecision(params) {
|
|
4687
5024
|
const serverId = requireString(params, "server_id");
|
|
@@ -4710,7 +5047,7 @@ async function executeLspGotoDefinition(params, signal) {
|
|
|
4710
5047
|
const line = requireNumber(params, "line");
|
|
4711
5048
|
const character = requireNumber(params, "character");
|
|
4712
5049
|
try {
|
|
4713
|
-
const result = await withLspClient(filePath, async (client) => client.definition(
|
|
5050
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.definition(resolvedFilePath, line, character, signal), "definition", clientOptions(signal));
|
|
4714
5051
|
const locations = !result ? [] : Array.isArray(result) ? result : [result];
|
|
4715
5052
|
const details = { filePath, line, character, locations };
|
|
4716
5053
|
if (locations.length === 0)
|
|
@@ -4735,7 +5072,7 @@ async function executeLspFindReferences(params, signal) {
|
|
|
4735
5072
|
const character = requireNumber(params, "character");
|
|
4736
5073
|
const includeDeclaration = optionalBoolean(params, "includeDeclaration") ?? true;
|
|
4737
5074
|
try {
|
|
4738
|
-
const result = await withLspClient(filePath, async (client) => client.references(
|
|
5075
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.references(resolvedFilePath, line, character, includeDeclaration, signal), "references", clientOptions(signal));
|
|
4739
5076
|
const references = Array.isArray(result) ? result : [];
|
|
4740
5077
|
const total = references.length;
|
|
4741
5078
|
const truncated = total > DEFAULT_MAX_REFERENCES;
|
|
@@ -4777,7 +5114,7 @@ async function executeLspPrepareRename(params, signal) {
|
|
|
4777
5114
|
const line = requireNumber(params, "line");
|
|
4778
5115
|
const character = requireNumber(params, "character");
|
|
4779
5116
|
try {
|
|
4780
|
-
const result = await withLspClient(filePath, async (client) => client.prepareRename(
|
|
5117
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.prepareRename(resolvedFilePath, line, character, signal), "prepareRename", clientOptions(signal));
|
|
4781
5118
|
const details = { filePath, line, character, result };
|
|
4782
5119
|
return text(formatPrepareRenameResult(result), details);
|
|
4783
5120
|
} catch (error) {
|
|
@@ -4798,7 +5135,7 @@ async function executeLspRename(params, signal) {
|
|
|
4798
5135
|
const character = requireNumber(params, "character");
|
|
4799
5136
|
const newName = requireString(params, "newName");
|
|
4800
5137
|
try {
|
|
4801
|
-
const result = await withLspClient(filePath, async (client) => client.rename(
|
|
5138
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.rename(resolvedFilePath, line, character, newName, signal), "rename", clientOptions(signal));
|
|
4802
5139
|
const details = { filePath, line, character, newName, apply: result.apply, edit: result.edit };
|
|
4803
5140
|
return text(formatApplyResult(result.apply), details, !result.apply.success);
|
|
4804
5141
|
} catch (error) {
|
|
@@ -4878,7 +5215,7 @@ async function executeLspSymbols(params, signal) {
|
|
|
4878
5215
|
const symbols2 = await withLspClient(filePath, async (client) => client.workspaceSymbols(query, signal), "workspaceSymbols", clientOptions(signal));
|
|
4879
5216
|
return formatSymbolsResult(filePath, scope, symbols2, limit, query);
|
|
4880
5217
|
}
|
|
4881
|
-
const symbols = await withLspClient(filePath, async (client) => client.documentSymbols(
|
|
5218
|
+
const symbols = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.documentSymbols(resolvedFilePath, signal), "documentSymbols", clientOptions(signal));
|
|
4882
5219
|
return formatSymbolsResult(filePath, scope, symbols, limit);
|
|
4883
5220
|
} catch (error) {
|
|
4884
5221
|
const query = optionalString(params, "query");
|
|
@@ -5014,6 +5351,16 @@ var LSP_MCP_TOOLS = [
|
|
|
5014
5351
|
}, ["filePath", "line", "character", "newName"]),
|
|
5015
5352
|
execute: executeLspRename
|
|
5016
5353
|
},
|
|
5354
|
+
{
|
|
5355
|
+
name: "format",
|
|
5356
|
+
aliases: ["lsp_format"],
|
|
5357
|
+
title: "LSP Format",
|
|
5358
|
+
description: "Format a source file with its language server and write the returned edits to disk.",
|
|
5359
|
+
inputSchema: objectSchema({
|
|
5360
|
+
filePath: { type: "string", description: "Source file path to format." }
|
|
5361
|
+
}, ["filePath"]),
|
|
5362
|
+
execute: executeLspFormat
|
|
5363
|
+
},
|
|
5017
5364
|
{
|
|
5018
5365
|
name: "install_decision",
|
|
5019
5366
|
aliases: ["lsp_install_decision"],
|
|
@@ -5113,11 +5460,10 @@ function requestedProtocolVersion(params) {
|
|
|
5113
5460
|
// src/daemon-client.ts
|
|
5114
5461
|
import { connect } from "node:net";
|
|
5115
5462
|
import { homedir as homedir3 } from "node:os";
|
|
5116
|
-
import { join as
|
|
5463
|
+
import { join as join8 } from "node:path";
|
|
5117
5464
|
|
|
5118
5465
|
// src/daemon-request-error.ts
|
|
5119
5466
|
class DaemonRequestError extends Error {
|
|
5120
|
-
requestWritten;
|
|
5121
5467
|
constructor(message, requestWritten) {
|
|
5122
5468
|
super(message);
|
|
5123
5469
|
this.name = "DaemonRequestError";
|
|
@@ -5140,7 +5486,6 @@ class DaemonRequestCancelledError extends DaemonRequestError {
|
|
|
5140
5486
|
}
|
|
5141
5487
|
|
|
5142
5488
|
class DaemonRequestTimedOutError extends DaemonRequestError {
|
|
5143
|
-
timeoutMs;
|
|
5144
5489
|
constructor(requestWritten, timeoutMs) {
|
|
5145
5490
|
super("daemon request timed out", requestWritten);
|
|
5146
5491
|
this.name = "DaemonRequestTimedOutError";
|
|
@@ -5192,9 +5537,9 @@ function errorText(error) {
|
|
|
5192
5537
|
|
|
5193
5538
|
// src/ensure-daemon.ts
|
|
5194
5539
|
import { spawn as spawn2 } from "node:child_process";
|
|
5195
|
-
import { closeSync as closeSync2, existsSync as
|
|
5540
|
+
import { closeSync as closeSync2, existsSync as existsSync12, mkdirSync as mkdirSync3, openSync as openSync2, writeSync as writeSync2 } from "node:fs";
|
|
5196
5541
|
import { Socket } from "node:net";
|
|
5197
|
-
import { dirname as
|
|
5542
|
+
import { dirname as dirname10, isAbsolute as isAbsolute5 } from "node:path";
|
|
5198
5543
|
import { argv0, execPath } from "node:process";
|
|
5199
5544
|
|
|
5200
5545
|
// src/ipc-protocol.ts
|
|
@@ -5208,25 +5553,23 @@ import {
|
|
|
5208
5553
|
lstatSync as lstatSync6,
|
|
5209
5554
|
mkdirSync as mkdirSync2,
|
|
5210
5555
|
openSync,
|
|
5211
|
-
readFileSync as
|
|
5212
|
-
unlinkSync,
|
|
5556
|
+
readFileSync as readFileSync6,
|
|
5557
|
+
unlinkSync as unlinkSync2,
|
|
5213
5558
|
writeSync
|
|
5214
5559
|
} from "node:fs";
|
|
5215
|
-
import { dirname as
|
|
5560
|
+
import { dirname as dirname9 } from "node:path";
|
|
5216
5561
|
var OMO_DAEMON_PROTOCOL_VERSION = 1;
|
|
5217
5562
|
var AUTH_ERROR_CODE = -32001;
|
|
5218
5563
|
var PROTOCOL_ERROR_CODE = -32002;
|
|
5219
5564
|
var AUTH_TOKEN_BYTES = 32;
|
|
5220
5565
|
|
|
5221
5566
|
class UnsafePrivateDirectoryError extends Error {
|
|
5222
|
-
path;
|
|
5223
|
-
reason;
|
|
5224
|
-
name = "UnsafePrivateDirectoryError";
|
|
5225
|
-
code = "unsafe_private_directory";
|
|
5226
5567
|
constructor(path, reason) {
|
|
5227
5568
|
super(`unsafe private directory ${path}: ${reason}`);
|
|
5228
5569
|
this.path = path;
|
|
5229
5570
|
this.reason = reason;
|
|
5571
|
+
this.name = "UnsafePrivateDirectoryError";
|
|
5572
|
+
this.code = "unsafe_private_directory";
|
|
5230
5573
|
}
|
|
5231
5574
|
}
|
|
5232
5575
|
function authEnvelope(token) {
|
|
@@ -5234,7 +5577,7 @@ function authEnvelope(token) {
|
|
|
5234
5577
|
}
|
|
5235
5578
|
function readAuthToken(paths) {
|
|
5236
5579
|
try {
|
|
5237
|
-
const token =
|
|
5580
|
+
const token = readFileSync6(paths.auth, "utf8").trim();
|
|
5238
5581
|
return token.length > 0 ? token : null;
|
|
5239
5582
|
} catch (error) {
|
|
5240
5583
|
if (error instanceof Error)
|
|
@@ -5250,7 +5593,7 @@ function readOrCreateAuthToken(paths) {
|
|
|
5250
5593
|
}
|
|
5251
5594
|
function rotateAuthToken(paths) {
|
|
5252
5595
|
try {
|
|
5253
|
-
|
|
5596
|
+
unlinkSync2(paths.auth);
|
|
5254
5597
|
} catch (error) {
|
|
5255
5598
|
if (!(error instanceof Error))
|
|
5256
5599
|
throw error;
|
|
@@ -5322,7 +5665,7 @@ function setPrivateFileMode(path) {
|
|
|
5322
5665
|
chmodSync(path, 384);
|
|
5323
5666
|
}
|
|
5324
5667
|
function createAuthToken(paths) {
|
|
5325
|
-
ensurePrivateDirectory(
|
|
5668
|
+
ensurePrivateDirectory(dirname9(paths.auth));
|
|
5326
5669
|
const token = randomBytes(AUTH_TOKEN_BYTES).toString("base64url");
|
|
5327
5670
|
let fd;
|
|
5328
5671
|
try {
|
|
@@ -5403,27 +5746,25 @@ import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
|
5403
5746
|
|
|
5404
5747
|
// src/runtime-contract.ts
|
|
5405
5748
|
import { statSync as statSync4 } from "node:fs";
|
|
5406
|
-
import { isAbsolute as
|
|
5749
|
+
import { isAbsolute as isAbsolute4 } from "node:path";
|
|
5407
5750
|
var OMO_LSP_DAEMON_DIR = "OMO_LSP_DAEMON_DIR";
|
|
5408
5751
|
var OMO_LSP_DAEMON_CLI = "OMO_LSP_DAEMON_CLI";
|
|
5409
5752
|
var OMO_LSP_DAEMON_VERSION = "OMO_LSP_DAEMON_VERSION";
|
|
5410
5753
|
var DAEMON_VERSION_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._+-]{0,127}$/;
|
|
5411
5754
|
|
|
5412
5755
|
class InvalidRuntimeOverrideError extends Error {
|
|
5413
|
-
code = "invalid_runtime_override";
|
|
5414
|
-
reason;
|
|
5415
5756
|
constructor(reason, message) {
|
|
5416
5757
|
super(message);
|
|
5758
|
+
this.code = "invalid_runtime_override";
|
|
5417
5759
|
this.name = "InvalidRuntimeOverrideError";
|
|
5418
5760
|
this.reason = reason;
|
|
5419
5761
|
}
|
|
5420
5762
|
}
|
|
5421
5763
|
|
|
5422
5764
|
class InvalidDaemonVersionError extends Error {
|
|
5423
|
-
code = "invalid_daemon_version";
|
|
5424
|
-
version;
|
|
5425
5765
|
constructor(version) {
|
|
5426
5766
|
super("LSP daemon version must match [A-Za-z0-9][A-Za-z0-9._+-]{0,127}");
|
|
5767
|
+
this.code = "invalid_daemon_version";
|
|
5427
5768
|
this.name = "InvalidDaemonVersionError";
|
|
5428
5769
|
this.version = version;
|
|
5429
5770
|
}
|
|
@@ -5442,12 +5783,12 @@ function resolveDaemonRuntime(env, defaults) {
|
|
|
5442
5783
|
throw new InvalidRuntimeOverrideError("paired_values_required", `${OMO_LSP_DAEMON_CLI} and ${OMO_LSP_DAEMON_VERSION} must be set together`);
|
|
5443
5784
|
}
|
|
5444
5785
|
if (!hasCliOverride || !hasVersionOverride) {
|
|
5445
|
-
if (!
|
|
5786
|
+
if (!isAbsolute4(defaults.cliPath)) {
|
|
5446
5787
|
throw new InvalidRuntimeOverrideError("packaged_cli_must_be_absolute", "Packaged LSP daemon CLI path must be absolute");
|
|
5447
5788
|
}
|
|
5448
5789
|
return { cliPath: defaults.cliPath, version: validateDaemonVersion(defaults.version) };
|
|
5449
5790
|
}
|
|
5450
|
-
if (!
|
|
5791
|
+
if (!isAbsolute4(cliOverride)) {
|
|
5451
5792
|
throw new InvalidRuntimeOverrideError("cli_must_be_absolute", `${OMO_LSP_DAEMON_CLI} must be an absolute path to an existing regular file`);
|
|
5452
5793
|
}
|
|
5453
5794
|
let cliStats;
|
|
@@ -5469,10 +5810,9 @@ var requireFromHere = createRequire(import.meta.url);
|
|
|
5469
5810
|
var MAX_SOCKET_PATH_LENGTH = 100;
|
|
5470
5811
|
|
|
5471
5812
|
class InvalidDaemonDirectoryError extends Error {
|
|
5472
|
-
code = "invalid_daemon_directory";
|
|
5473
|
-
directory;
|
|
5474
5813
|
constructor(directory) {
|
|
5475
5814
|
super(`${OMO_LSP_DAEMON_DIR} must be an absolute path`);
|
|
5815
|
+
this.code = "invalid_daemon_directory";
|
|
5476
5816
|
this.name = "InvalidDaemonDirectoryError";
|
|
5477
5817
|
this.directory = directory;
|
|
5478
5818
|
}
|
|
@@ -5626,7 +5966,7 @@ async function probeDaemon(paths, timeoutMs = PROBE_TIMEOUT_MS, signal) {
|
|
|
5626
5966
|
return await pingDaemon(paths, token, timeoutMs, signal) !== null;
|
|
5627
5967
|
}
|
|
5628
5968
|
function pingDaemon(paths, token, timeoutMs = PROBE_TIMEOUT_MS, signal) {
|
|
5629
|
-
return new Promise((
|
|
5969
|
+
return new Promise((resolve10) => {
|
|
5630
5970
|
const socket = new Socket;
|
|
5631
5971
|
let settled = false;
|
|
5632
5972
|
let timer;
|
|
@@ -5638,7 +5978,7 @@ function pingDaemon(paths, token, timeoutMs = PROBE_TIMEOUT_MS, signal) {
|
|
|
5638
5978
|
clearTimeout(timer);
|
|
5639
5979
|
signal?.removeEventListener("abort", onAbort);
|
|
5640
5980
|
socket.destroy();
|
|
5641
|
-
|
|
5981
|
+
resolve10(value);
|
|
5642
5982
|
};
|
|
5643
5983
|
const onAbort = () => finish(null);
|
|
5644
5984
|
const decoder = createLineDecoder((message) => {
|
|
@@ -5662,12 +6002,13 @@ function pingDaemon(paths, token, timeoutMs = PROBE_TIMEOUT_MS, signal) {
|
|
|
5662
6002
|
});
|
|
5663
6003
|
}
|
|
5664
6004
|
function spawnDaemonProcess(paths) {
|
|
5665
|
-
mkdirSync3(
|
|
6005
|
+
mkdirSync3(dirname10(paths.log), { recursive: true });
|
|
5666
6006
|
const logFd = openSync2(paths.log, "a");
|
|
5667
6007
|
try {
|
|
5668
6008
|
const child = spawn2(resolveDaemonNodeExecutable(), [paths.cliPath, "daemon"], {
|
|
5669
6009
|
detached: true,
|
|
5670
|
-
stdio: ["ignore", logFd, logFd]
|
|
6010
|
+
stdio: ["ignore", logFd, logFd],
|
|
6011
|
+
windowsHide: true
|
|
5671
6012
|
});
|
|
5672
6013
|
child.once("spawn", () => closeSync2(logFd));
|
|
5673
6014
|
child.once("error", (error) => {
|
|
@@ -5681,10 +6022,10 @@ function spawnDaemonProcess(paths) {
|
|
|
5681
6022
|
throw error;
|
|
5682
6023
|
}
|
|
5683
6024
|
}
|
|
5684
|
-
function resolveDaemonNodeExecutable(cachedExecPath = execPath, originalArgv0 = argv0, pathExists =
|
|
6025
|
+
function resolveDaemonNodeExecutable(cachedExecPath = execPath, originalArgv0 = argv0, pathExists = existsSync12) {
|
|
5685
6026
|
if (pathExists(cachedExecPath))
|
|
5686
6027
|
return cachedExecPath;
|
|
5687
|
-
if (
|
|
6028
|
+
if (isAbsolute5(originalArgv0) && pathExists(originalArgv0))
|
|
5688
6029
|
return originalArgv0;
|
|
5689
6030
|
return "node";
|
|
5690
6031
|
}
|
|
@@ -5697,7 +6038,7 @@ function defaultEnsureDaemonDeps() {
|
|
|
5697
6038
|
};
|
|
5698
6039
|
}
|
|
5699
6040
|
function sleepWithSignal(ms, signal) {
|
|
5700
|
-
return new Promise((
|
|
6041
|
+
return new Promise((resolve10) => {
|
|
5701
6042
|
let settled = false;
|
|
5702
6043
|
const finish = () => {
|
|
5703
6044
|
if (settled)
|
|
@@ -5705,7 +6046,7 @@ function sleepWithSignal(ms, signal) {
|
|
|
5705
6046
|
settled = true;
|
|
5706
6047
|
clearTimeout(timer);
|
|
5707
6048
|
signal?.removeEventListener("abort", finish);
|
|
5708
|
-
|
|
6049
|
+
resolve10();
|
|
5709
6050
|
};
|
|
5710
6051
|
const timer = setTimeout(finish, ms);
|
|
5711
6052
|
if (signal?.aborted) {
|
|
@@ -5720,7 +6061,7 @@ function awaitWithSignal2(promise, signal) {
|
|
|
5720
6061
|
return promise;
|
|
5721
6062
|
if (signal.aborted)
|
|
5722
6063
|
return Promise.reject(abortError3(signal));
|
|
5723
|
-
return new Promise((
|
|
6064
|
+
return new Promise((resolve10, reject) => {
|
|
5724
6065
|
let settled = false;
|
|
5725
6066
|
const finish = (run) => {
|
|
5726
6067
|
if (settled)
|
|
@@ -5731,7 +6072,7 @@ function awaitWithSignal2(promise, signal) {
|
|
|
5731
6072
|
};
|
|
5732
6073
|
const onAbort = () => finish(() => reject(abortError3(signal)));
|
|
5733
6074
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
5734
|
-
promise.then((value) => finish(() =>
|
|
6075
|
+
promise.then((value) => finish(() => resolve10(value)), (error) => finish(() => reject(error)));
|
|
5735
6076
|
});
|
|
5736
6077
|
}
|
|
5737
6078
|
function throwIfAborted(signal) {
|
|
@@ -5780,7 +6121,10 @@ function parsePingResponse(message) {
|
|
|
5780
6121
|
var CONTEXT_KEY = "_context";
|
|
5781
6122
|
|
|
5782
6123
|
class InvalidDaemonRequestError extends Error {
|
|
5783
|
-
|
|
6124
|
+
constructor() {
|
|
6125
|
+
super(...arguments);
|
|
6126
|
+
this.name = "InvalidDaemonRequestError";
|
|
6127
|
+
}
|
|
5784
6128
|
}
|
|
5785
6129
|
function extractRequestContext(raw) {
|
|
5786
6130
|
if (!isPlainRecord(raw) || raw["method"] !== "tools/call")
|
|
@@ -5896,14 +6240,17 @@ async function callToolViaDaemon(name, args, options) {
|
|
|
5896
6240
|
function callDiagnosticsViaDaemon(filePath, options) {
|
|
5897
6241
|
return callToolViaDaemon("diagnostics", { filePath, severity: "error" }, options);
|
|
5898
6242
|
}
|
|
6243
|
+
function callFormatViaDaemon(filePath, options) {
|
|
6244
|
+
return callToolViaDaemon("format", { filePath }, options);
|
|
6245
|
+
}
|
|
5899
6246
|
function currentRequestContext(env = process.env) {
|
|
5900
6247
|
const cwd = process.cwd();
|
|
5901
6248
|
const home = env["HOME"] ?? homedir3();
|
|
5902
6249
|
return parseLspRequestContext({
|
|
5903
6250
|
cwd,
|
|
5904
|
-
projectConfigPaths: [
|
|
5905
|
-
userConfigPath:
|
|
5906
|
-
installDecisionsPath:
|
|
6251
|
+
projectConfigPaths: [join8(cwd, ".codex", "lsp-client.json")],
|
|
6252
|
+
userConfigPath: join8(home, ".codex", "lsp-client.json"),
|
|
6253
|
+
installDecisionsPath: join8(home, ".codex", "lsp-install-decisions.json"),
|
|
5907
6254
|
capabilities: { installDecisionTool: true }
|
|
5908
6255
|
});
|
|
5909
6256
|
}
|
|
@@ -5918,7 +6265,7 @@ function withContext(args, context) {
|
|
|
5918
6265
|
function ensureDaemonAvailable(paths, ensure, signal) {
|
|
5919
6266
|
if (!signal)
|
|
5920
6267
|
return ensure(paths);
|
|
5921
|
-
return new Promise((
|
|
6268
|
+
return new Promise((resolve10, reject) => {
|
|
5922
6269
|
let settled = false;
|
|
5923
6270
|
const finish = (run) => {
|
|
5924
6271
|
if (settled)
|
|
@@ -5933,11 +6280,11 @@ function ensureDaemonAvailable(paths, ensure, signal) {
|
|
|
5933
6280
|
return;
|
|
5934
6281
|
}
|
|
5935
6282
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
5936
|
-
Promise.resolve().then(() => ensure(paths, signal)).then(() => finish(() =>
|
|
6283
|
+
Promise.resolve().then(() => ensure(paths, signal)).then(() => finish(() => resolve10()), (error) => finish(() => reject(signal.aborted ? new DaemonRequestCancelledError(false) : error)));
|
|
5937
6284
|
});
|
|
5938
6285
|
}
|
|
5939
6286
|
function sendToolCall(paths, token, name, args, options) {
|
|
5940
|
-
return new Promise((
|
|
6287
|
+
return new Promise((resolve10, reject) => {
|
|
5941
6288
|
const socket = connect(paths.socket);
|
|
5942
6289
|
const requestId = allocateProxyRequestId();
|
|
5943
6290
|
let settled = false;
|
|
@@ -5990,7 +6337,7 @@ function sendToolCall(paths, token, name, args, options) {
|
|
|
5990
6337
|
}
|
|
5991
6338
|
const result = toToolResult(message, requestId);
|
|
5992
6339
|
if (result)
|
|
5993
|
-
finish(() =>
|
|
6340
|
+
finish(() => resolve10(result));
|
|
5994
6341
|
else
|
|
5995
6342
|
finish(() => reject(new DaemonRequestError("invalid daemon response", requestWritten)));
|
|
5996
6343
|
});
|
|
@@ -6158,18 +6505,18 @@ function canonicalizePathList(value) {
|
|
|
6158
6505
|
return value.split(delimiter4).map((entry) => canonicalizePath(entry) ?? entry).join(delimiter4);
|
|
6159
6506
|
}
|
|
6160
6507
|
function canonicalizePath(value) {
|
|
6161
|
-
if (value === undefined || !
|
|
6508
|
+
if (value === undefined || !isAbsolute6(value) || !existsSync13(value))
|
|
6162
6509
|
return value;
|
|
6163
|
-
return
|
|
6510
|
+
return realpathSync6(value);
|
|
6164
6511
|
}
|
|
6165
6512
|
function projectRootFromOpenCodeConfigPath(path2) {
|
|
6166
|
-
if (
|
|
6513
|
+
if (basename4(path2) !== "lsp.json" && basename4(path2) !== "lsp-client.json")
|
|
6167
6514
|
return;
|
|
6168
|
-
const configDir =
|
|
6169
|
-
const configDirName =
|
|
6515
|
+
const configDir = dirname11(path2);
|
|
6516
|
+
const configDirName = basename4(configDir);
|
|
6170
6517
|
if (configDirName !== ".opencode" && configDirName !== ".omo")
|
|
6171
6518
|
return;
|
|
6172
|
-
return
|
|
6519
|
+
return dirname11(configDir);
|
|
6173
6520
|
}
|
|
6174
6521
|
|
|
6175
6522
|
// src/daemon-server.ts
|
|
@@ -6178,12 +6525,12 @@ import { createServer as createServer2 } from "node:net";
|
|
|
6178
6525
|
|
|
6179
6526
|
// src/ownership.ts
|
|
6180
6527
|
import { randomUUID } from "node:crypto";
|
|
6181
|
-
import { existsSync as
|
|
6182
|
-
import { dirname as
|
|
6528
|
+
import { existsSync as existsSync14, lstatSync as lstatSync7, readFileSync as readFileSync8, statSync as statSync5, unlinkSync as unlinkSync4 } from "node:fs";
|
|
6529
|
+
import { dirname as dirname13 } from "node:path";
|
|
6183
6530
|
|
|
6184
6531
|
// src/lock.ts
|
|
6185
|
-
import { closeSync as closeSync3, mkdirSync as mkdirSync4, openSync as openSync3, readFileSync as
|
|
6186
|
-
import { dirname as
|
|
6532
|
+
import { closeSync as closeSync3, mkdirSync as mkdirSync4, openSync as openSync3, readFileSync as readFileSync7, unlinkSync as unlinkSync3, writeSync as writeSync3 } from "node:fs";
|
|
6533
|
+
import { dirname as dirname12 } from "node:path";
|
|
6187
6534
|
function isProcessAlive2(pid) {
|
|
6188
6535
|
if (!Number.isInteger(pid) || pid <= 0)
|
|
6189
6536
|
return false;
|
|
@@ -6198,14 +6545,14 @@ function isProcessAlive2(pid) {
|
|
|
6198
6545
|
}
|
|
6199
6546
|
function readLockPid(lockPath) {
|
|
6200
6547
|
try {
|
|
6201
|
-
const pid = Number.parseInt(
|
|
6548
|
+
const pid = Number.parseInt(readFileSync7(lockPath, "utf8").trim(), 10);
|
|
6202
6549
|
return Number.isInteger(pid) ? pid : null;
|
|
6203
6550
|
} catch {
|
|
6204
6551
|
return null;
|
|
6205
6552
|
}
|
|
6206
6553
|
}
|
|
6207
6554
|
function tryAcquireLock(lockPath, ownerPid = process.pid) {
|
|
6208
|
-
mkdirSync4(
|
|
6555
|
+
mkdirSync4(dirname12(lockPath), { recursive: true });
|
|
6209
6556
|
for (let attempt = 0;attempt < 2; attempt += 1) {
|
|
6210
6557
|
const handle = writeLockFile(lockPath, ownerPid);
|
|
6211
6558
|
if (handle)
|
|
@@ -6237,7 +6584,7 @@ function reapStaleLock(lockPath) {
|
|
|
6237
6584
|
}
|
|
6238
6585
|
function unlinkQuietly(path2) {
|
|
6239
6586
|
try {
|
|
6240
|
-
|
|
6587
|
+
unlinkSync3(path2);
|
|
6241
6588
|
} catch (error) {
|
|
6242
6589
|
if (error instanceof Error)
|
|
6243
6590
|
return;
|
|
@@ -6253,17 +6600,19 @@ function errorCode3(error) {
|
|
|
6253
6600
|
|
|
6254
6601
|
// src/ownership.ts
|
|
6255
6602
|
class DaemonAlreadyRunningError extends Error {
|
|
6256
|
-
|
|
6257
|
-
|
|
6603
|
+
constructor() {
|
|
6604
|
+
super(...arguments);
|
|
6605
|
+
this.name = "DaemonAlreadyRunningError";
|
|
6606
|
+
this.code = "daemon_already_running";
|
|
6607
|
+
}
|
|
6258
6608
|
}
|
|
6259
6609
|
|
|
6260
6610
|
class DaemonStartupDeferredError extends Error {
|
|
6261
|
-
reason;
|
|
6262
|
-
name = "DaemonStartupDeferredError";
|
|
6263
|
-
code = "daemon_startup_deferred";
|
|
6264
6611
|
constructor(reason) {
|
|
6265
6612
|
super(`LSP daemon startup deferred: ${reason}`);
|
|
6266
6613
|
this.reason = reason;
|
|
6614
|
+
this.name = "DaemonStartupDeferredError";
|
|
6615
|
+
this.code = "daemon_startup_deferred";
|
|
6267
6616
|
}
|
|
6268
6617
|
}
|
|
6269
6618
|
async function acquireStartupLease(paths, pingOwner) {
|
|
@@ -6286,11 +6635,11 @@ async function acquireStartupLease(paths, pingOwner) {
|
|
|
6286
6635
|
function ensureDaemonDirectories(paths) {
|
|
6287
6636
|
ensurePrivateDirectory(paths.dir);
|
|
6288
6637
|
if (process.platform !== "win32")
|
|
6289
|
-
ensurePrivateDirectory(
|
|
6638
|
+
ensurePrivateDirectory(dirname13(paths.socket));
|
|
6290
6639
|
}
|
|
6291
6640
|
function readDaemonOwner(paths) {
|
|
6292
6641
|
try {
|
|
6293
|
-
return parseOwner(JSON.parse(
|
|
6642
|
+
return parseOwner(JSON.parse(readFileSync8(paths.owner, "utf8")));
|
|
6294
6643
|
} catch (error) {
|
|
6295
6644
|
if (error instanceof Error)
|
|
6296
6645
|
return null;
|
|
@@ -6366,10 +6715,10 @@ async function validateExistingOwner(paths, pingOwner) {
|
|
|
6366
6715
|
throw new DaemonStartupDeferredError("reachable_owner_mismatch");
|
|
6367
6716
|
}
|
|
6368
6717
|
function cleanupDeadOwner(paths, owner) {
|
|
6369
|
-
if (process.platform !== "win32" &&
|
|
6718
|
+
if (process.platform !== "win32" && existsSync14(owner.endpoint.path)) {
|
|
6370
6719
|
const stat = lstatSync7(owner.endpoint.path);
|
|
6371
6720
|
if (stat.isSocket())
|
|
6372
|
-
|
|
6721
|
+
unlinkSync4(owner.endpoint.path);
|
|
6373
6722
|
}
|
|
6374
6723
|
unlinkQuietly(paths.pid);
|
|
6375
6724
|
unlinkQuietly(paths.endpoint);
|
|
@@ -6417,7 +6766,7 @@ function parseEndpoint(value) {
|
|
|
6417
6766
|
// src/version-reap.ts
|
|
6418
6767
|
import { execFile } from "node:child_process";
|
|
6419
6768
|
import { readdir, readFile, rm } from "node:fs/promises";
|
|
6420
|
-
import { basename as
|
|
6769
|
+
import { basename as basename5, dirname as dirname14, join as join9 } from "node:path";
|
|
6421
6770
|
var TERM_GRACE_MS = 5000;
|
|
6422
6771
|
var KILL_GRACE_MS = 1000;
|
|
6423
6772
|
var VERSION_ENTRY_PATTERN = /^v([A-Za-z0-9][A-Za-z0-9._+-]{0,127})$/;
|
|
@@ -6438,7 +6787,7 @@ async function attestDaemonCliProcess(pid, platform, deps = {}) {
|
|
|
6438
6787
|
return isNodeCliDaemonCommand(command.trim());
|
|
6439
6788
|
}
|
|
6440
6789
|
async function reapStaleDaemonVersions(ownPaths, deps = {}) {
|
|
6441
|
-
const baseDir =
|
|
6790
|
+
const baseDir = dirname14(ownPaths.dir);
|
|
6442
6791
|
const platform = deps.platform ?? process.platform;
|
|
6443
6792
|
const isAlive = deps.isAlive ?? isProcessAlive2;
|
|
6444
6793
|
const attest = deps.attest ?? ((pid) => attestDaemonCliProcess(pid, platform));
|
|
@@ -6457,7 +6806,7 @@ async function reapStaleDaemonVersions(ownPaths, deps = {}) {
|
|
|
6457
6806
|
const version = parseVersionEntry(entry.name);
|
|
6458
6807
|
if (version === null || !entry.isDirectory())
|
|
6459
6808
|
continue;
|
|
6460
|
-
const versionDir =
|
|
6809
|
+
const versionDir = join9(baseDir, entry.name);
|
|
6461
6810
|
const siblingPaths = daemonPaths({ [OMO_LSP_DAEMON_DIR]: baseDir }, { cliPath: ownPaths.cliPath, version });
|
|
6462
6811
|
results.push(await reapOneVersion({
|
|
6463
6812
|
version,
|
|
@@ -6481,7 +6830,7 @@ async function reapOneVersion(context) {
|
|
|
6481
6830
|
const { version, versionDir } = context;
|
|
6482
6831
|
const owner = context.readOwner(context.siblingPaths);
|
|
6483
6832
|
if (!owner) {
|
|
6484
|
-
const lockPid = readLockPid(
|
|
6833
|
+
const lockPid = readLockPid(join9(versionDir, "daemon.lock"));
|
|
6485
6834
|
if (lockPid !== null && context.isAlive(lockPid)) {
|
|
6486
6835
|
context.log(`reap: sparing v${version}: owner metadata missing but daemon.lock is held by live pid ${lockPid}`);
|
|
6487
6836
|
return { version, status: "spared", reason: `owner metadata missing but lock held by live pid ${lockPid}` };
|
|
@@ -6547,7 +6896,7 @@ function splitCmdline(buffer) {
|
|
|
6547
6896
|
function isNodeCliDaemonArgv(argv) {
|
|
6548
6897
|
if (argv.length < 2 || !argv.includes("daemon"))
|
|
6549
6898
|
return false;
|
|
6550
|
-
const executable =
|
|
6899
|
+
const executable = basename5(argv[0] ?? "");
|
|
6551
6900
|
if (!/^node(?:\.exe)?$/i.test(executable))
|
|
6552
6901
|
return false;
|
|
6553
6902
|
return argv.some((value) => value === "cli.js" || value.endsWith("/cli.js") || value.endsWith("\\cli.js"));
|
|
@@ -6559,13 +6908,13 @@ function defaultReadProcFile(path2) {
|
|
|
6559
6908
|
return readFile(path2);
|
|
6560
6909
|
}
|
|
6561
6910
|
function defaultExecuteForStdout(file, args) {
|
|
6562
|
-
return new Promise((
|
|
6563
|
-
execFile(file, [...args], { encoding: "utf8", maxBuffer: 1024 * 1024, timeout: 1000 }, (error, stdout) => {
|
|
6911
|
+
return new Promise((resolve10) => {
|
|
6912
|
+
execFile(file, [...args], { encoding: "utf8", maxBuffer: 1024 * 1024, timeout: 1000, windowsHide: true }, (error, stdout) => {
|
|
6564
6913
|
if (error !== null) {
|
|
6565
|
-
|
|
6914
|
+
resolve10(null);
|
|
6566
6915
|
return;
|
|
6567
6916
|
}
|
|
6568
|
-
|
|
6917
|
+
resolve10(stdout);
|
|
6569
6918
|
});
|
|
6570
6919
|
});
|
|
6571
6920
|
}
|
|
@@ -6584,7 +6933,7 @@ async function defaultWaitForExit(pid, timeoutMs) {
|
|
|
6584
6933
|
return true;
|
|
6585
6934
|
if (Date.now() >= deadline)
|
|
6586
6935
|
return false;
|
|
6587
|
-
await new Promise((
|
|
6936
|
+
await new Promise((resolve10) => setTimeout(resolve10, 100));
|
|
6588
6937
|
}
|
|
6589
6938
|
}
|
|
6590
6939
|
function defaultLog(message) {
|
|
@@ -6691,17 +7040,17 @@ async function assertSelfProbe(paths, token, owner) {
|
|
|
6691
7040
|
throw new DaemonStartupDeferredError("self_probe_failed");
|
|
6692
7041
|
}
|
|
6693
7042
|
function listen(server2, socketPath) {
|
|
6694
|
-
return new Promise((
|
|
7043
|
+
return new Promise((resolve10, reject) => {
|
|
6695
7044
|
const onError = (error) => reject(error);
|
|
6696
7045
|
server2.once("error", onError);
|
|
6697
7046
|
server2.listen(socketPath, () => {
|
|
6698
7047
|
server2.removeListener("error", onError);
|
|
6699
|
-
|
|
7048
|
+
resolve10();
|
|
6700
7049
|
});
|
|
6701
7050
|
});
|
|
6702
7051
|
}
|
|
6703
7052
|
function closeServer(server2) {
|
|
6704
|
-
return new Promise((
|
|
7053
|
+
return new Promise((resolve10) => server2.close(() => resolve10()));
|
|
6705
7054
|
}
|
|
6706
7055
|
function installSignalHandlers(close) {
|
|
6707
7056
|
const handler = () => {
|