lazycodex-ai 5.0.0-beta.4 → 5.0.0-beta.40
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/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/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 +66932 -64746
- 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 +66795 -64586
- package/package.json +9 -9
- package/packages/git-bash-mcp/dist/cli.js +6 -1
- package/packages/lsp-daemon/dist/cli.js +793 -323
- package/packages/lsp-daemon/dist/client.d.ts +10 -0
- package/packages/lsp-daemon/dist/client.js +753 -280
- 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 +757 -289
- package/packages/lsp-daemon/dist/proxy.js +3 -0
- package/packages/lsp-daemon/dist/version-reap.js +1 -1
- package/packages/lsp-daemon/package.json +1 -1
- package/packages/lsp-tools-mcp/dist/cli.js +712 -244
- package/packages/lsp-tools-mcp/dist/lsp/manager.js +248 -119
- package/packages/lsp-tools-mcp/dist/mcp.js +714 -246
- package/packages/lsp-tools-mcp/dist/request-context.js +12 -13
- package/packages/lsp-tools-mcp/dist/tools.js +718 -254
- package/packages/lsp-tools-mcp/package.json +1 -1
- package/packages/omo-codex/plugin/.codex-plugin/plugin.json +4 -6
- package/packages/omo-codex/plugin/.mcp.json +0 -6
- package/packages/omo-codex/plugin/AGENTS.md +47 -0
- package/packages/omo-codex/plugin/README.md +2 -2
- package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +45 -49
- 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/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/lcx/skills/lcx-doctor/SKILL.md +1 -1
- 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 +741 -294
- 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 +4 -10
- 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 +10 -4
- package/packages/omo-codex/plugin/components/ultrawork/biome.json +2 -2
- package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +489 -4
- package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/package.json +5 -6
- package/packages/omo-codex/plugin/components/ultrawork/scripts/sync-directive.mjs +30 -14
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +6 -7
- 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/src/directive-content.ts +4 -0
- package/packages/omo-codex/plugin/components/ultrawork/src/directive.ts +5 -2
- 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/directive-source.test.ts +14 -8
- package/packages/omo-codex/plugin/components/ultrawork/test/package-smoke.test.ts +12 -1
- 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 +2 -2
- 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 +19 -0
- package/packages/omo-codex/plugin/components/ulw-loop/CHANGELOG.md +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/README.md +12 -1
- package/packages/omo-codex/plugin/components/ulw-loop/biome.json +2 -2
- package/packages/omo-codex/plugin/components/ulw-loop/directive.md +15 -3
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-codex-validation.d.ts +12 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-codex-validation.js +45 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-continuation.js +9 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-reconciliation.d.ts +15 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-reconciliation.js +15 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-template.d.ts +8 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-template.js +120 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.js +40 -39
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-commands.js +7 -2
- 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 +12 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-subcommands.js +2 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +958 -342
- package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.d.ts +2 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.js +27 -6
- package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-snapshot.d.ts +13 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-snapshot.js +15 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/domain-types.d.ts +17 -9
- package/packages/omo-codex/plugin/components/ulw-loop/dist/paths.js +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.js +17 -2
- package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-missing-recovery.d.ts +13 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-missing-recovery.js +19 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-aggregate.d.ts +7 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-aggregate.js +9 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-artifacts.d.ts +12 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-artifacts.js +104 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-fields.d.ts +13 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-fields.js +65 -9
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-verdicts.js +5 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.d.ts +4 -2
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.js +69 -111
- package/packages/omo-codex/plugin/components/ulw-loop/dist/review-blockers.js +4 -2
- package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-guard.js +185 -14
- package/packages/omo-codex/plugin/components/ulw-loop/dist/status-next-actions.d.ts +6 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/status-next-actions.js +33 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/stop-resume-hook.js +3 -3
- package/packages/omo-codex/plugin/components/ulw-loop/dist/surface.d.ts +18 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/surface.js +65 -0
- package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +4 -4
- package/packages/omo-codex/plugin/components/ulw-loop/package.json +5 -5
- package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md +3 -2
- package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/define-goal.md +108 -0
- package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +22 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-codex-validation.ts +81 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-continuation.ts +7 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-reconciliation.ts +31 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-template.ts +134 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint.ts +38 -71
- package/packages/omo-codex/plugin/components/ulw-loop/src/cli-commands.ts +7 -2
- package/packages/omo-codex/plugin/components/ulw-loop/src/cli-output.ts +14 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/cli-subcommands.ts +2 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/cli.ts +3 -5
- package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-instruction.ts +34 -5
- package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-snapshot.ts +26 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/codex-hook.ts +3 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/domain-types.ts +19 -9
- package/packages/omo-codex/plugin/components/ulw-loop/src/paths.ts +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/plan-io.ts +18 -3
- package/packages/omo-codex/plugin/components/ulw-loop/src/plan-missing-recovery.ts +27 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-aggregate.ts +11 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-artifacts.ts +123 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-fields.ts +68 -15
- package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-verdicts.ts +6 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate.ts +82 -131
- package/packages/omo-codex/plugin/components/ulw-loop/src/review-blockers.ts +4 -2
- package/packages/omo-codex/plugin/components/ulw-loop/src/spawn-guard.ts +187 -12
- package/packages/omo-codex/plugin/components/ulw-loop/src/status-next-actions.ts +36 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/stop-resume-hook.ts +3 -3
- package/packages/omo-codex/plugin/components/ulw-loop/src/surface.ts +95 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-continuation.test.ts +0 -1
- package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-final.test.ts +133 -1
- package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-template.test.ts +137 -0
- 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/cli-status-next-actions.test.ts +183 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-instruction.test.ts +37 -2
- package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-snapshot.test.ts +18 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/codex-hook.test.ts +0 -3
- package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/quality-gate-builder.ts +7 -3
- package/packages/omo-codex/plugin/components/ulw-loop/test/guided-recovery.test.ts +105 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts +5 -37
- package/packages/omo-codex/plugin/components/ulw-loop/test/paths.test.ts +9 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-aggregate-basics.test.ts +258 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-cap-and-dedupe.test.ts +22 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-poisoning-cascades.test.ts +97 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-roles.test.ts +46 -2
- package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-senpi-surface.test.ts +131 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-single-report.test.ts +241 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate.test.ts +48 -3
- package/packages/omo-codex/plugin/components/ulw-loop/test/spawn-guard.test.ts +318 -1
- package/packages/omo-codex/plugin/components/ulw-loop/test/steering.test.ts +8 -5
- package/packages/omo-codex/plugin/components/ulw-loop/test/stop-resume-hook.test.ts +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/test/surface.test.ts +74 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/ultrawork-directive.test.ts +13 -8
- 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-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-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 +676 -524
- package/packages/omo-codex/plugin/package.json +2 -3
- package/packages/omo-codex/plugin/scripts/AGENTS.md +39 -0
- package/packages/omo-codex/plugin/scripts/auto-update-plan.mjs +1 -2
- package/packages/omo-codex/plugin/scripts/auto-update.mjs +0 -9
- package/packages/omo-codex/plugin/scripts/canonical-ultrawork-directive.mjs +17 -0
- package/packages/omo-codex/plugin/scripts/hook-status-message.mjs +0 -1
- package/packages/omo-codex/plugin/scripts/migrate-codex-config/catalog.mjs +3 -3
- package/packages/omo-codex/plugin/scripts/sync-skills.mjs +36 -13
- package/packages/omo-codex/plugin/shared/package.json +3 -4
- package/packages/omo-codex/plugin/shared/src/config-loader.ts +2 -102
- package/packages/omo-codex/plugin/shared/src/config-migration.ts +0 -1
- package/packages/omo-codex/plugin/shared/test/config-loader.test.ts +41 -130
- 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/init-deep/SKILL.md +13 -13
- package/packages/omo-codex/plugin/skills/lcx-doctor/SKILL.md +1 -1
- 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 +110 -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/ultimate-browsing/references/insane-search/README.md +9 -2
- package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +15 -3
- package/packages/omo-codex/plugin/skills/{start-work → ulw-execute}/SKILL.md +19 -26
- 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 +22 -1
- package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +6 -7
- 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 +9 -48
- package/packages/omo-codex/plugin/test/aggregate-manifest.test.mjs +2 -3
- package/packages/omo-codex/plugin/test/aggregate-mcp.test.mjs +2 -7
- 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 -27
- package/packages/omo-codex/plugin/test/bootstrap-setup.test.mjs +0 -31
- package/packages/omo-codex/plugin/test/canonical-ultrawork-directive.test.mjs +53 -0
- 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 -51
- 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 -5
- package/packages/omo-codex/plugin/test/lcx-contribute-bug-fix-template.test.mjs +21 -27
- package/packages/omo-codex/plugin/test/mcp-research-servers.test.mjs +1 -3
- 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 +23 -13
- package/packages/omo-codex/plugin/test/sync-skills.test.mjs +14 -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 +5 -5
- package/packages/omo-codex/plugin/test/ulw-plan-review-state-contract.test.mjs +0 -3
- package/packages/omo-codex/scripts/install-dist/install-local.mjs +2817 -913
- package/packages/{omo-codex/plugin/components/ultrawork/skills/ultrawork/SKILL.md → prompts-core/prompts/ultrawork/codex.md} +15 -10
- 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/init-deep/SKILL.md +13 -13
- 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 +110 -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/ultimate-browsing/references/insane-search/README.md +9 -2
- package/packages/shared-skills/skills/{start-work → ulw-execute}/SKILL.md +17 -16
- package/packages/shared-skills/skills/ulw-plan/SKILL.md +6 -7
- 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/packages/lsp-tools-mcp/dist/lsp/cleanup-errors.d.ts +0 -1
- package/packages/lsp-tools-mcp/dist/lsp/constants.d.ts +0 -1
- package/packages/lsp-tools-mcp/dist/lsp/language-mappings.d.ts +0 -1
- package/packages/lsp-tools-mcp/dist/lsp/process-signal-cleanup.d.ts +0 -1
- package/packages/lsp-tools-mcp/dist/missing-dependency-result.d.ts +0 -1
- package/packages/omo-codex/plugin/components/codegraph/AGENTS.md +0 -58
- package/packages/omo-codex/plugin/components/codegraph/NODE-RUNTIME-LICENSES.md +0 -2951
- package/packages/omo-codex/plugin/components/codegraph/NOTICE +0 -16
- package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +0 -12136
- package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +0 -9734
- package/packages/omo-codex/plugin/components/codegraph/package.json +0 -33
- package/packages/omo-codex/plugin/components/codegraph/src/cache-gc.ts +0 -29
- package/packages/omo-codex/plugin/components/codegraph/src/cli.ts +0 -79
- package/packages/omo-codex/plugin/components/codegraph/src/hook-input.ts +0 -33
- package/packages/omo-codex/plugin/components/codegraph/src/hook-sweep.ts +0 -25
- package/packages/omo-codex/plugin/components/codegraph/src/hook-types.ts +0 -131
- package/packages/omo-codex/plugin/components/codegraph/src/hook.ts +0 -258
- package/packages/omo-codex/plugin/components/codegraph/src/mcp-bridge.ts +0 -309
- package/packages/omo-codex/plugin/components/codegraph/src/mcp-unavailable.ts +0 -80
- package/packages/omo-codex/plugin/components/codegraph/src/post-tool-use-hook.ts +0 -34
- package/packages/omo-codex/plugin/components/codegraph/src/serve-invocation.ts +0 -29
- package/packages/omo-codex/plugin/components/codegraph/src/serve.ts +0 -263
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-command.ts +0 -106
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-cooldown.ts +0 -145
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-hook-runtime.ts +0 -21
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-lock.ts +0 -139
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-outcome.ts +0 -15
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-paths.ts +0 -32
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-project.ts +0 -109
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker-result.ts +0 -148
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker.ts +0 -175
- package/packages/omo-codex/plugin/components/codegraph/src/sweep-cli.ts +0 -81
- package/packages/omo-codex/plugin/components/codegraph/test/cache-gc.test.ts +0 -34
- package/packages/omo-codex/plugin/components/codegraph/test/hook-exclusion.test.ts +0 -112
- package/packages/omo-codex/plugin/components/codegraph/test/hook-registration.test.ts +0 -26
- package/packages/omo-codex/plugin/components/codegraph/test/hook-session-start-guard.test.ts +0 -160
- package/packages/omo-codex/plugin/components/codegraph/test/hook-store-upgrade.test.ts +0 -50
- package/packages/omo-codex/plugin/components/codegraph/test/hook-sweep.test.ts +0 -29
- package/packages/omo-codex/plugin/components/codegraph/test/hook.test.ts +0 -320
- package/packages/omo-codex/plugin/components/codegraph/test/mcp-bridge-fixtures.ts +0 -172
- package/packages/omo-codex/plugin/components/codegraph/test/package-runtime.test.ts +0 -91
- package/packages/omo-codex/plugin/components/codegraph/test/provisioned-node-guard.test.ts +0 -100
- package/packages/omo-codex/plugin/components/codegraph/test/serve-built-wrapper.test.ts +0 -76
- package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge-lifecycle.test.ts +0 -133
- package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge.test.ts +0 -245
- package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-facade.test.ts +0 -69
- package/packages/omo-codex/plugin/components/codegraph/test/serve-node-support.test.ts +0 -43
- package/packages/omo-codex/plugin/components/codegraph/test/serve-provision.test.ts +0 -147
- package/packages/omo-codex/plugin/components/codegraph/test/serve-unavailable.test.ts +0 -175
- package/packages/omo-codex/plugin/components/codegraph/test/serve.test.ts +0 -385
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-node-support.test.ts +0 -206
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-project.test.ts +0 -58
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-state.test.ts +0 -104
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-trust-boundary.test.ts +0 -65
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-availability.test.ts +0 -106
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-cooldown.test.ts +0 -116
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-flow.test.ts +0 -258
- package/packages/omo-codex/plugin/components/codegraph/test/sweep-cli.test.ts +0 -56
- package/packages/omo-codex/plugin/components/codegraph/tsconfig.build.json +0 -13
- package/packages/omo-codex/plugin/components/codegraph/tsconfig.json +0 -25
- package/packages/omo-codex/plugin/components/start-work-continuation/LICENSE +0 -21
- package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +0 -28
- package/packages/omo-codex/plugin/components/ultrawork/directive.md +0 -471
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +0 -18
- package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +0 -17
- 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/scripts/migrate-omo-sot/editor.mjs +0 -125
- package/packages/omo-codex/plugin/scripts/migrate-omo-sot/jsonc.mjs +0 -43
- package/packages/omo-codex/plugin/scripts/migrate-omo-sot/scaffold.mjs +0 -29
- package/packages/omo-codex/plugin/scripts/migrate-omo-sot.mjs +0 -121
- 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/component-codegraph-mcp-smoke.test.mjs +0 -76
- package/packages/omo-codex/plugin/test/migrate-omo-sot.test.mjs +0 -179
- 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/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/{codegraph → ulw-execute-continuation}/LICENSE +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/plan-checklist.ts +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/types.ts +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-completed.json +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-mixed-platforms.json +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-single-codex-work.json +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-all-done.md +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-scaffold.md +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-with-nested-checkboxes.md +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-with-unchecked.md +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/tsconfig.build.json +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/tsconfig.json +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/vitest.config.ts +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// ../lsp-core/src/lsp/client-wrapper.ts
|
|
2
|
-
import { existsSync as
|
|
3
|
-
import { dirname as
|
|
2
|
+
import { existsSync as existsSync10, realpathSync as realpathSync5, statSync as statSync3 } from "node:fs";
|
|
3
|
+
import { basename as basename3, dirname as dirname8, join as join5, resolve as resolve8 } from "node:path";
|
|
4
4
|
|
|
5
5
|
// ../lsp-core/src/request-context.ts
|
|
6
6
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
@@ -9,18 +9,17 @@ import { homedir } from "node:os";
|
|
|
9
9
|
import { basename, delimiter, dirname, isAbsolute, join, relative, resolve } from "node:path";
|
|
10
10
|
|
|
11
11
|
class LspRequestContextParseError extends Error {
|
|
12
|
-
code;
|
|
13
|
-
name = "LspRequestContextParseError";
|
|
14
12
|
constructor(code, message) {
|
|
15
13
|
super(message);
|
|
16
14
|
this.code = code;
|
|
15
|
+
this.name = "LspRequestContextParseError";
|
|
17
16
|
}
|
|
18
17
|
}
|
|
19
18
|
|
|
20
19
|
class LspRequestContextUnavailableError extends Error {
|
|
21
|
-
name = "LspRequestContextUnavailableError";
|
|
22
20
|
constructor() {
|
|
23
21
|
super("LSP request context is required. Standalone MCP startup must install one with runWithRequestContext(createStandaloneMcpRequestContext()).");
|
|
22
|
+
this.name = "LspRequestContextUnavailableError";
|
|
24
23
|
}
|
|
25
24
|
}
|
|
26
25
|
var storage = new AsyncLocalStorage;
|
|
@@ -50,7 +49,7 @@ function contextEnv(key) {
|
|
|
50
49
|
}
|
|
51
50
|
function createStandaloneMcpRequestContext(input = {}) {
|
|
52
51
|
const env = input.env ?? process.env;
|
|
53
|
-
const cwd = canonicalCwd(input.cwd ?? process.cwd());
|
|
52
|
+
const cwd = canonicalCwd(input.cwd ?? env["LSP_TOOLS_MCP_CWD"] ?? process.cwd());
|
|
54
53
|
const home = input.homeDir ?? homedir();
|
|
55
54
|
const projectConfigPaths = translateProjectConfigEnv(env["LSP_TOOLS_MCP_PROJECT_CONFIG"], cwd);
|
|
56
55
|
const userConfigPath = translateHomeConfigEnv(env["LSP_TOOLS_MCP_USER_CONFIG"], home, ".codex/lsp-client.json");
|
|
@@ -193,22 +192,15 @@ function effectiveExtension(filePath) {
|
|
|
193
192
|
|
|
194
193
|
// ../lsp-core/src/lsp/errors.ts
|
|
195
194
|
class LspConnectionClosedError extends Error {
|
|
196
|
-
serverId;
|
|
197
|
-
root;
|
|
198
|
-
name = "LspConnectionClosedError";
|
|
199
195
|
constructor(serverId, root, message) {
|
|
200
196
|
super(message ?? `LSP connection closed for ${serverId} at ${root}`);
|
|
201
197
|
this.serverId = serverId;
|
|
202
198
|
this.root = root;
|
|
199
|
+
this.name = "LspConnectionClosedError";
|
|
203
200
|
}
|
|
204
201
|
}
|
|
205
202
|
|
|
206
203
|
class LspProcessExitedError extends Error {
|
|
207
|
-
serverId;
|
|
208
|
-
root;
|
|
209
|
-
exitCode;
|
|
210
|
-
stderrTail;
|
|
211
|
-
name = "LspProcessExitedError";
|
|
212
204
|
constructor(serverId, root, exitCode, stderrTail) {
|
|
213
205
|
const stderrSuffix = stderrTail ? `
|
|
214
206
|
stderr tail: ${stderrTail}` : "";
|
|
@@ -217,46 +209,59 @@ stderr tail: ${stderrTail}` : "";
|
|
|
217
209
|
this.root = root;
|
|
218
210
|
this.exitCode = exitCode;
|
|
219
211
|
this.stderrTail = stderrTail;
|
|
212
|
+
this.name = "LspProcessExitedError";
|
|
220
213
|
}
|
|
221
214
|
}
|
|
222
215
|
|
|
223
216
|
class LspRequestTimeoutError extends Error {
|
|
224
|
-
method;
|
|
225
|
-
stderrTail;
|
|
226
|
-
name = "LspRequestTimeoutError";
|
|
227
217
|
constructor(method, stderrTail) {
|
|
228
218
|
const stderrSuffix = stderrTail ? `
|
|
229
219
|
recent stderr: ${stderrTail}` : "";
|
|
230
220
|
super(`LSP request timeout (method: ${method})${stderrSuffix}`);
|
|
231
221
|
this.method = method;
|
|
232
222
|
this.stderrTail = stderrTail;
|
|
223
|
+
this.name = "LspRequestTimeoutError";
|
|
233
224
|
}
|
|
234
225
|
}
|
|
235
226
|
|
|
236
227
|
class LspInvalidPathError extends Error {
|
|
237
|
-
|
|
228
|
+
constructor() {
|
|
229
|
+
super(...arguments);
|
|
230
|
+
this.name = "LspInvalidPathError";
|
|
231
|
+
}
|
|
238
232
|
}
|
|
239
233
|
|
|
240
234
|
class LspServerLookupError extends Error {
|
|
241
|
-
lookup;
|
|
242
|
-
name = "LspServerLookupError";
|
|
243
235
|
constructor(message, lookup) {
|
|
244
236
|
super(message);
|
|
245
237
|
this.lookup = lookup;
|
|
238
|
+
this.name = "LspServerLookupError";
|
|
246
239
|
}
|
|
247
240
|
}
|
|
248
241
|
|
|
249
242
|
class LspServerInitializingError extends Error {
|
|
250
|
-
originalError;
|
|
251
|
-
name = "LspServerInitializingError";
|
|
252
243
|
constructor(originalError) {
|
|
253
244
|
super(`LSP server is still initializing. Please retry in a few seconds. Original error: ${originalError.message}`);
|
|
254
245
|
this.originalError = originalError;
|
|
246
|
+
this.name = "LspServerInitializingError";
|
|
255
247
|
}
|
|
256
248
|
}
|
|
257
249
|
|
|
258
250
|
class LspProcessSpawnError extends Error {
|
|
259
|
-
|
|
251
|
+
constructor() {
|
|
252
|
+
super(...arguments);
|
|
253
|
+
this.name = "LspProcessSpawnError";
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
class LspClientRespawnBudgetExceededError extends Error {
|
|
258
|
+
constructor(serverId, root, retryLimit) {
|
|
259
|
+
super(`LSP server ${serverId} at ${root} failed to stay alive; respawn budget exhausted ` + `(${retryLimit} consecutive dead generations). Retrying after the cooldown may succeed.`);
|
|
260
|
+
this.serverId = serverId;
|
|
261
|
+
this.root = root;
|
|
262
|
+
this.retryLimit = retryLimit;
|
|
263
|
+
this.name = "LspClientRespawnBudgetExceededError";
|
|
264
|
+
}
|
|
260
265
|
}
|
|
261
266
|
function isLspDeadConnectionError(err) {
|
|
262
267
|
return err instanceof LspConnectionClosedError || err instanceof LspProcessExitedError;
|
|
@@ -279,6 +284,13 @@ import { pathToFileURL as pathToFileURL3 } from "node:url";
|
|
|
279
284
|
// ../lsp-core/src/lsp/connection.ts
|
|
280
285
|
import { pathToFileURL } from "node:url";
|
|
281
286
|
|
|
287
|
+
// ../lsp-core/src/lsp/timer-provider.ts
|
|
288
|
+
var realTimerProvider = {
|
|
289
|
+
now: () => Date.now(),
|
|
290
|
+
setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
|
|
291
|
+
clearTimeout: (handle) => clearTimeout(handle)
|
|
292
|
+
};
|
|
293
|
+
|
|
282
294
|
// ../lsp-core/src/lsp/constants.ts
|
|
283
295
|
var DEFAULT_MAX_REFERENCES = 200;
|
|
284
296
|
var DEFAULT_MAX_SYMBOLS = 200;
|
|
@@ -287,9 +299,12 @@ var DEFAULT_MAX_DIRECTORY_FILES = 50;
|
|
|
287
299
|
var REQUEST_TIMEOUT_MS = 15000;
|
|
288
300
|
var INIT_TIMEOUT_MS = 60000;
|
|
289
301
|
var IDLE_TIMEOUT_MS = 5 * 60000;
|
|
302
|
+
var MAX_RESIDENT_CLIENTS = 6;
|
|
290
303
|
var REAPER_INTERVAL_MS = 60000;
|
|
291
304
|
var STOP_HARD_KILL_TIMEOUT_MS = 5000;
|
|
292
305
|
var STOP_SIGKILL_GRACE_MS = 1000;
|
|
306
|
+
var CLIENT_RESPAWN_RETRY_LIMIT = 2;
|
|
307
|
+
var CLIENT_RESPAWN_COOLDOWN_MS = 60000;
|
|
293
308
|
|
|
294
309
|
// ../lsp-core/src/lsp/json-rpc-connection.ts
|
|
295
310
|
var HEADER_SEPARATOR = `\r
|
|
@@ -301,20 +316,31 @@ var METHOD_NOT_FOUND = -32601;
|
|
|
301
316
|
var INTERNAL_ERROR = -32603;
|
|
302
317
|
|
|
303
318
|
class JsonRpcConnection {
|
|
304
|
-
reader;
|
|
305
|
-
writer;
|
|
306
|
-
pendingRequests = new Map;
|
|
307
|
-
notificationHandlers = new Map;
|
|
308
|
-
requestHandlers = new Map;
|
|
309
|
-
closeHandlers = [];
|
|
310
|
-
errorHandlers = [];
|
|
311
|
-
inputBuffer = Buffer.alloc(0);
|
|
312
|
-
nextRequestId = 1;
|
|
313
|
-
listening = false;
|
|
314
|
-
disposed = false;
|
|
315
319
|
constructor(reader, writer) {
|
|
316
320
|
this.reader = reader;
|
|
317
321
|
this.writer = writer;
|
|
322
|
+
this.pendingRequests = new Map;
|
|
323
|
+
this.notificationHandlers = new Map;
|
|
324
|
+
this.requestHandlers = new Map;
|
|
325
|
+
this.closeHandlers = [];
|
|
326
|
+
this.errorHandlers = [];
|
|
327
|
+
this.inputBuffer = Buffer.alloc(0);
|
|
328
|
+
this.nextRequestId = 1;
|
|
329
|
+
this.listening = false;
|
|
330
|
+
this.disposed = false;
|
|
331
|
+
this.handleData = (chunk) => {
|
|
332
|
+
const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
|
|
333
|
+
this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
|
|
334
|
+
this.drainInputBuffer();
|
|
335
|
+
};
|
|
336
|
+
this.handleClose = () => {
|
|
337
|
+
for (const handler of this.closeHandlers) {
|
|
338
|
+
handler();
|
|
339
|
+
}
|
|
340
|
+
};
|
|
341
|
+
this.handleStreamError = (error) => {
|
|
342
|
+
this.emitError(error);
|
|
343
|
+
};
|
|
318
344
|
}
|
|
319
345
|
listen() {
|
|
320
346
|
if (this.listening)
|
|
@@ -435,19 +461,6 @@ class JsonRpcConnection {
|
|
|
435
461
|
this.notificationHandlers.clear();
|
|
436
462
|
this.requestHandlers.clear();
|
|
437
463
|
}
|
|
438
|
-
handleData = (chunk) => {
|
|
439
|
-
const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
|
|
440
|
-
this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
|
|
441
|
-
this.drainInputBuffer();
|
|
442
|
-
};
|
|
443
|
-
handleClose = () => {
|
|
444
|
-
for (const handler of this.closeHandlers) {
|
|
445
|
-
handler();
|
|
446
|
-
}
|
|
447
|
-
};
|
|
448
|
-
handleStreamError = (error) => {
|
|
449
|
-
this.emitError(error);
|
|
450
|
-
};
|
|
451
464
|
drainInputBuffer() {
|
|
452
465
|
while (true) {
|
|
453
466
|
const headerEnd = this.inputBuffer.indexOf(HEADER_SEPARATOR);
|
|
@@ -795,33 +808,29 @@ function isPosition(value) {
|
|
|
795
808
|
|
|
796
809
|
// ../lsp-core/src/lsp/transport.ts
|
|
797
810
|
class LspClientNotStartedError extends Error {
|
|
798
|
-
serverId;
|
|
799
|
-
root;
|
|
800
|
-
name = "LspClientNotStartedError";
|
|
801
811
|
constructor(serverId, root) {
|
|
802
812
|
super("LSP client not started");
|
|
803
813
|
this.serverId = serverId;
|
|
804
814
|
this.root = root;
|
|
815
|
+
this.name = "LspClientNotStartedError";
|
|
805
816
|
}
|
|
806
817
|
}
|
|
807
818
|
|
|
808
819
|
class LspClientTransport {
|
|
809
|
-
root;
|
|
810
|
-
server;
|
|
811
|
-
proc = null;
|
|
812
|
-
connection = null;
|
|
813
|
-
stderrBuffer = [];
|
|
814
|
-
processExited = false;
|
|
815
|
-
diagnosticsStore = new Map;
|
|
816
|
-
requestTimeoutMs;
|
|
817
|
-
initializeTimeoutMs;
|
|
818
|
-
workspaceApplyEditHandler = null;
|
|
819
|
-
diagnosticPullSupported = false;
|
|
820
820
|
constructor(root, server, timeouts = {}) {
|
|
821
821
|
this.root = root;
|
|
822
822
|
this.server = server;
|
|
823
|
+
this.proc = null;
|
|
824
|
+
this.connection = null;
|
|
825
|
+
this.stderrBuffer = [];
|
|
826
|
+
this.processExited = false;
|
|
827
|
+
this.diagnosticsStore = new Map;
|
|
828
|
+
this.workspaceApplyEditHandler = null;
|
|
829
|
+
this.diagnosticPullSupported = false;
|
|
830
|
+
this.documentFormattingSupported = false;
|
|
823
831
|
this.requestTimeoutMs = timeouts.requestTimeoutMs ?? REQUEST_TIMEOUT_MS;
|
|
824
832
|
this.initializeTimeoutMs = timeouts.initializeTimeoutMs ?? INIT_TIMEOUT_MS;
|
|
833
|
+
this.timerProvider = timeouts.timerProvider ?? realTimerProvider;
|
|
825
834
|
}
|
|
826
835
|
pid() {
|
|
827
836
|
return this.proc?.pid;
|
|
@@ -841,6 +850,12 @@ class LspClientTransport {
|
|
|
841
850
|
isDiagnosticPullSupported() {
|
|
842
851
|
return this.diagnosticPullSupported;
|
|
843
852
|
}
|
|
853
|
+
setDocumentFormattingSupported(supported) {
|
|
854
|
+
this.documentFormattingSupported = supported;
|
|
855
|
+
}
|
|
856
|
+
isDocumentFormattingSupported() {
|
|
857
|
+
return this.documentFormattingSupported;
|
|
858
|
+
}
|
|
844
859
|
handlePublishDiagnostics(params) {
|
|
845
860
|
this.diagnosticsStore.set(params.uri, [...params.diagnostics]);
|
|
846
861
|
}
|
|
@@ -916,7 +931,7 @@ class LspClientTransport {
|
|
|
916
931
|
const options = args[1];
|
|
917
932
|
const timeoutMs = options?.timeoutMs ?? this.requestTimeoutMs;
|
|
918
933
|
const timeoutController = new AbortController;
|
|
919
|
-
const timeoutHandle = setTimeout(() => {
|
|
934
|
+
const timeoutHandle = this.timerProvider.setTimeout(() => {
|
|
920
935
|
const stderrTail = this.stderrBuffer.slice(-5).join(`
|
|
921
936
|
`);
|
|
922
937
|
timeoutController.abort(new LspRequestTimeoutError(method, stderrTail || undefined));
|
|
@@ -935,7 +950,7 @@ class LspClientTransport {
|
|
|
935
950
|
}
|
|
936
951
|
throw error;
|
|
937
952
|
} finally {
|
|
938
|
-
clearTimeout(timeoutHandle);
|
|
953
|
+
this.timerProvider.clearTimeout(timeoutHandle);
|
|
939
954
|
combinedSignal.dispose();
|
|
940
955
|
}
|
|
941
956
|
}
|
|
@@ -1054,6 +1069,14 @@ function supportsDiagnosticPull(capabilities) {
|
|
|
1054
1069
|
return false;
|
|
1055
1070
|
return Object.hasOwn(capabilities, "diagnosticProvider");
|
|
1056
1071
|
}
|
|
1072
|
+
function supportsDocumentFormatting(capabilities) {
|
|
1073
|
+
if (capabilities === undefined)
|
|
1074
|
+
return false;
|
|
1075
|
+
const provider = capabilities.documentFormattingProvider;
|
|
1076
|
+
if (provider === undefined || provider === null || provider === false)
|
|
1077
|
+
return false;
|
|
1078
|
+
return provider === true || typeof provider === "object";
|
|
1079
|
+
}
|
|
1057
1080
|
|
|
1058
1081
|
class LspClientConnection extends LspClientTransport {
|
|
1059
1082
|
async initialize() {
|
|
@@ -1070,6 +1093,7 @@ class LspClientConnection extends LspClientTransport {
|
|
|
1070
1093
|
references: {},
|
|
1071
1094
|
documentSymbol: { hierarchicalDocumentSymbolSupport: true },
|
|
1072
1095
|
publishDiagnostics: {},
|
|
1096
|
+
formatting: { dynamicRegistration: false },
|
|
1073
1097
|
rename: {
|
|
1074
1098
|
prepareSupport: true,
|
|
1075
1099
|
prepareSupportDefaultBehavior: 1
|
|
@@ -1111,6 +1135,7 @@ class LspClientConnection extends LspClientTransport {
|
|
|
1111
1135
|
initializationOptions: this.server.initialization
|
|
1112
1136
|
}, { timeoutMs: this.initializeTimeoutMs });
|
|
1113
1137
|
this.setDiagnosticPullSupported(supportsDiagnosticPull(result?.capabilities));
|
|
1138
|
+
this.setDocumentFormattingSupported(supportsDocumentFormatting(result?.capabilities));
|
|
1114
1139
|
await this.sendNotification("initialized", {});
|
|
1115
1140
|
await this.sendNotification("workspace/didChangeConfiguration", {
|
|
1116
1141
|
settings: { json: { validate: { enable: true } } }
|
|
@@ -1306,6 +1331,17 @@ function canonicalPath(filePath) {
|
|
|
1306
1331
|
return absolute;
|
|
1307
1332
|
}
|
|
1308
1333
|
}
|
|
1334
|
+
function normalizeDocumentUri(uri) {
|
|
1335
|
+
let decoded = uri;
|
|
1336
|
+
try {
|
|
1337
|
+
decoded = decodeURIComponent(uri);
|
|
1338
|
+
} catch {
|
|
1339
|
+
decoded = uri;
|
|
1340
|
+
}
|
|
1341
|
+
if (process.platform !== "win32")
|
|
1342
|
+
return decoded;
|
|
1343
|
+
return decoded.replace(/^(file:\/\/\/)([a-z]):/, (_match, prefix, drive) => `${prefix}${drive.toUpperCase()}:`);
|
|
1344
|
+
}
|
|
1309
1345
|
function isSameOrDescendant(candidate, parent) {
|
|
1310
1346
|
const suffix = relative2(parent, candidate);
|
|
1311
1347
|
return suffix === "" || !suffix.startsWith("..") && suffix !== "..";
|
|
@@ -1316,17 +1352,18 @@ function movedPath(candidate, oldPath, newPath) {
|
|
|
1316
1352
|
}
|
|
1317
1353
|
|
|
1318
1354
|
class WorkspaceDocumentState {
|
|
1319
|
-
sendNotification;
|
|
1320
|
-
clearDiagnostics;
|
|
1321
|
-
openDocuments = new Map;
|
|
1322
|
-
openByUri = new Map;
|
|
1323
|
-
openPromises = new Map;
|
|
1324
|
-
now;
|
|
1325
|
-
versionlessPublishQuiescenceMs;
|
|
1326
1355
|
constructor(sendNotification, clearDiagnostics, options = {}) {
|
|
1327
1356
|
this.sendNotification = sendNotification;
|
|
1328
1357
|
this.clearDiagnostics = clearDiagnostics;
|
|
1329
|
-
this.
|
|
1358
|
+
this.openDocuments = new Map;
|
|
1359
|
+
this.openByUri = new Map;
|
|
1360
|
+
this.openPromises = new Map;
|
|
1361
|
+
this.timerProvider = options.timerProvider ?? {
|
|
1362
|
+
now: options.now ?? (() => Date.now()),
|
|
1363
|
+
setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
|
|
1364
|
+
clearTimeout: (handle) => clearTimeout(handle)
|
|
1365
|
+
};
|
|
1366
|
+
this.now = () => this.timerProvider.now();
|
|
1330
1367
|
this.versionlessPublishQuiescenceMs = options.versionlessPublishQuiescenceMs ?? DEFAULT_VERSIONLESS_PUBLISH_QUIESCENCE_MS;
|
|
1331
1368
|
}
|
|
1332
1369
|
async openFile(filePath) {
|
|
@@ -1348,7 +1385,7 @@ class WorkspaceDocumentState {
|
|
|
1348
1385
|
return this.openDocuments.get(canonicalPath(filePath))?.version;
|
|
1349
1386
|
}
|
|
1350
1387
|
getStoredDiagnostics(uri) {
|
|
1351
|
-
const state = this.openByUri.get(uri);
|
|
1388
|
+
const state = this.openByUri.get(normalizeDocumentUri(uri));
|
|
1352
1389
|
if (!state)
|
|
1353
1390
|
return [];
|
|
1354
1391
|
return state.lastPublish?.diagnostics ?? state.pullCache?.diagnostics ?? [];
|
|
@@ -1370,13 +1407,13 @@ class WorkspaceDocumentState {
|
|
|
1370
1407
|
return state !== undefined && state.uri === snapshot.uri && state.version === snapshot.version && state.generation === snapshot.documentGeneration;
|
|
1371
1408
|
}
|
|
1372
1409
|
getPullCache(snapshot) {
|
|
1373
|
-
const state = this.openByUri.get(snapshot.uri);
|
|
1410
|
+
const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
|
|
1374
1411
|
if (!state?.pullCache || state.pullCache.documentVersion !== snapshot.version)
|
|
1375
1412
|
return null;
|
|
1376
1413
|
return state.pullCache;
|
|
1377
1414
|
}
|
|
1378
1415
|
recordPullDiagnostics(snapshot, report) {
|
|
1379
|
-
const state = this.openByUri.get(snapshot.uri);
|
|
1416
|
+
const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
|
|
1380
1417
|
if (!state)
|
|
1381
1418
|
return;
|
|
1382
1419
|
state.pullCache = {
|
|
@@ -1386,7 +1423,7 @@ class WorkspaceDocumentState {
|
|
|
1386
1423
|
};
|
|
1387
1424
|
}
|
|
1388
1425
|
recordPublishedDiagnostics(params) {
|
|
1389
|
-
const state = this.openByUri.get(params.uri);
|
|
1426
|
+
const state = this.openByUri.get(normalizeDocumentUri(params.uri));
|
|
1390
1427
|
if (!state)
|
|
1391
1428
|
return;
|
|
1392
1429
|
state.publishGeneration += 1;
|
|
@@ -1400,7 +1437,7 @@ class WorkspaceDocumentState {
|
|
|
1400
1437
|
this.notifyWaiters(state);
|
|
1401
1438
|
}
|
|
1402
1439
|
resolvePushDiagnostics(snapshot) {
|
|
1403
|
-
const state = this.openByUri.get(snapshot.uri);
|
|
1440
|
+
const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
|
|
1404
1441
|
if (!state?.lastPublish)
|
|
1405
1442
|
return { status: "missing" };
|
|
1406
1443
|
const publish = state.lastPublish;
|
|
@@ -1414,7 +1451,7 @@ class WorkspaceDocumentState {
|
|
|
1414
1451
|
return waitMs === 0 ? { status: "ready", diagnostics: publish.diagnostics } : { status: "wait", waitMs };
|
|
1415
1452
|
}
|
|
1416
1453
|
waitForDiagnosticsActivity(snapshot, timeoutMs) {
|
|
1417
|
-
const state = this.openByUri.get(snapshot.uri);
|
|
1454
|
+
const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
|
|
1418
1455
|
if (!state || timeoutMs <= 0)
|
|
1419
1456
|
return Promise.resolve();
|
|
1420
1457
|
return new Promise((resolveActivity) => {
|
|
@@ -1423,11 +1460,11 @@ class WorkspaceDocumentState {
|
|
|
1423
1460
|
if (settled)
|
|
1424
1461
|
return;
|
|
1425
1462
|
settled = true;
|
|
1426
|
-
clearTimeout(timer);
|
|
1463
|
+
this.timerProvider.clearTimeout(timer);
|
|
1427
1464
|
state.waiters.delete(finish);
|
|
1428
1465
|
resolveActivity();
|
|
1429
1466
|
};
|
|
1430
|
-
const timer = setTimeout(finish, timeoutMs);
|
|
1467
|
+
const timer = this.timerProvider.setTimeout(finish, timeoutMs);
|
|
1431
1468
|
if (typeof timer.unref === "function")
|
|
1432
1469
|
timer.unref();
|
|
1433
1470
|
state.waiters.add(finish);
|
|
@@ -1535,7 +1572,7 @@ class WorkspaceDocumentState {
|
|
|
1535
1572
|
waiters: new Set
|
|
1536
1573
|
};
|
|
1537
1574
|
this.openDocuments.set(path, state);
|
|
1538
|
-
this.openByUri.set(state.uri, state);
|
|
1575
|
+
this.openByUri.set(normalizeDocumentUri(state.uri), state);
|
|
1539
1576
|
this.notifyWaiters(state);
|
|
1540
1577
|
await this.sendNotification("textDocument/didOpen", {
|
|
1541
1578
|
textDocument: { uri: state.uri, languageId: state.languageId, version: state.version, text }
|
|
@@ -1560,7 +1597,7 @@ class WorkspaceDocumentState {
|
|
|
1560
1597
|
}
|
|
1561
1598
|
async closeDocument(state) {
|
|
1562
1599
|
this.openDocuments.delete(state.path);
|
|
1563
|
-
this.openByUri.delete(state.uri);
|
|
1600
|
+
this.openByUri.delete(normalizeDocumentUri(state.uri));
|
|
1564
1601
|
this.clearDiagnostics(state.uri);
|
|
1565
1602
|
this.notifyWaiters(state);
|
|
1566
1603
|
await this.sendNotification("textDocument/didClose", { textDocument: { uri: state.uri } });
|
|
@@ -1589,13 +1626,11 @@ import { dirname as dirname2, isAbsolute as isAbsolute2, relative as relative3,
|
|
|
1589
1626
|
import { fileURLToPath } from "node:url";
|
|
1590
1627
|
|
|
1591
1628
|
class WorkspaceEditPathError extends Error {
|
|
1592
|
-
path;
|
|
1593
|
-
detail;
|
|
1594
|
-
name = "WorkspaceEditPathError";
|
|
1595
1629
|
constructor(path, detail) {
|
|
1596
1630
|
super(`${detail}: ${path}`);
|
|
1597
1631
|
this.path = path;
|
|
1598
1632
|
this.detail = detail;
|
|
1633
|
+
this.name = "WorkspaceEditPathError";
|
|
1599
1634
|
}
|
|
1600
1635
|
}
|
|
1601
1636
|
function isPathInsideWorkspace(filePath, workspaceRoot) {
|
|
@@ -1887,13 +1922,11 @@ function canonicalFingerprint(operations) {
|
|
|
1887
1922
|
|
|
1888
1923
|
// ../lsp-core/src/lsp/workspace-edit-types.ts
|
|
1889
1924
|
class WorkspaceEditValidationError extends Error {
|
|
1890
|
-
changeIndex;
|
|
1891
|
-
detail;
|
|
1892
|
-
name = "WorkspaceEditValidationError";
|
|
1893
1925
|
constructor(changeIndex, detail) {
|
|
1894
1926
|
super(`change ${changeIndex}: ${detail}`);
|
|
1895
1927
|
this.changeIndex = changeIndex;
|
|
1896
1928
|
this.detail = detail;
|
|
1929
|
+
this.name = "WorkspaceEditValidationError";
|
|
1897
1930
|
}
|
|
1898
1931
|
}
|
|
1899
1932
|
|
|
@@ -2391,10 +2424,9 @@ function simulateDelete(operation, virtual) {
|
|
|
2391
2424
|
import { existsSync as existsSync5, lstatSync as lstatSync3, readdirSync as readdirSync2 } from "node:fs";
|
|
2392
2425
|
import { dirname as dirname4, resolve as resolve5 } from "node:path";
|
|
2393
2426
|
class WorkspaceSnapshotBuilder {
|
|
2394
|
-
workspaceRoot;
|
|
2395
|
-
snapshots = new Map;
|
|
2396
2427
|
constructor(workspaceRoot) {
|
|
2397
2428
|
this.workspaceRoot = workspaceRoot;
|
|
2429
|
+
this.snapshots = new Map;
|
|
2398
2430
|
}
|
|
2399
2431
|
build(operations) {
|
|
2400
2432
|
this.add(this.workspaceRoot, false);
|
|
@@ -2438,8 +2470,10 @@ function snapshotOperations(operations, workspaceRoot) {
|
|
|
2438
2470
|
|
|
2439
2471
|
// ../lsp-core/src/lsp/workspace-edit-plan.ts
|
|
2440
2472
|
class PlanPathIndex {
|
|
2441
|
-
|
|
2442
|
-
|
|
2473
|
+
constructor() {
|
|
2474
|
+
this.firstChangeByPath = new Map;
|
|
2475
|
+
this.reportedPathByCanonical = new Map;
|
|
2476
|
+
}
|
|
2443
2477
|
build(operations) {
|
|
2444
2478
|
for (const operation of operations) {
|
|
2445
2479
|
switch (operation.kind) {
|
|
@@ -2528,14 +2562,11 @@ function isRecord4(value) {
|
|
|
2528
2562
|
}
|
|
2529
2563
|
|
|
2530
2564
|
class WorkspaceMutationController {
|
|
2531
|
-
workspaceRoot;
|
|
2532
|
-
documents;
|
|
2533
|
-
activeLease = null;
|
|
2534
|
-
nextLeaseId = 1;
|
|
2535
|
-
io;
|
|
2536
2565
|
constructor(workspaceRoot, documents) {
|
|
2537
2566
|
this.workspaceRoot = workspaceRoot;
|
|
2538
2567
|
this.documents = documents;
|
|
2568
|
+
this.activeLease = null;
|
|
2569
|
+
this.nextLeaseId = 1;
|
|
2539
2570
|
}
|
|
2540
2571
|
setIo(io) {
|
|
2541
2572
|
this.io = io;
|
|
@@ -2648,14 +2679,12 @@ var DIAGNOSTICS_FRESHNESS_TIMEOUT_MS = 3000;
|
|
|
2648
2679
|
var VERSIONLESS_PUBLISH_QUIESCENCE_MS = 250;
|
|
2649
2680
|
|
|
2650
2681
|
class LspClient extends LspClientConnection {
|
|
2651
|
-
diagnosticPullErrors = [];
|
|
2652
|
-
documents;
|
|
2653
|
-
workspaceMutations;
|
|
2654
|
-
diagnosticsFreshnessTimeoutMs;
|
|
2655
2682
|
constructor(root, server, options = {}) {
|
|
2656
2683
|
super(root, server, options);
|
|
2684
|
+
this.diagnosticPullErrors = [];
|
|
2657
2685
|
this.diagnosticsFreshnessTimeoutMs = options.diagnosticsFreshnessTimeoutMs ?? DIAGNOSTICS_FRESHNESS_TIMEOUT_MS;
|
|
2658
2686
|
this.documents = new WorkspaceDocumentState((method, params) => this.sendNotification(method, params), (uri) => this.diagnosticsStore.delete(uri), {
|
|
2687
|
+
timerProvider: this.timerProvider,
|
|
2659
2688
|
versionlessPublishQuiescenceMs: options.versionlessPublishQuiescenceMs ?? VERSIONLESS_PUBLISH_QUIESCENCE_MS
|
|
2660
2689
|
});
|
|
2661
2690
|
this.workspaceMutations = new WorkspaceMutationController(root, this.documents);
|
|
@@ -2708,6 +2737,18 @@ class LspClient extends LspClientConnection {
|
|
|
2708
2737
|
textDocument: { uri: pathToFileURL3(absPath).href }
|
|
2709
2738
|
}, options);
|
|
2710
2739
|
}
|
|
2740
|
+
async formatDocument(filePath, options, signal) {
|
|
2741
|
+
if (!this.isDocumentFormattingSupported())
|
|
2742
|
+
return null;
|
|
2743
|
+
const absPath = this.resolveWorkspacePath(filePath);
|
|
2744
|
+
await this.openFile(absPath);
|
|
2745
|
+
const requestOptions = signal === undefined ? {} : { signal };
|
|
2746
|
+
const edits = await this.sendRequest("textDocument/formatting", {
|
|
2747
|
+
textDocument: { uri: pathToFileURL3(absPath).href },
|
|
2748
|
+
options
|
|
2749
|
+
}, requestOptions);
|
|
2750
|
+
return edits ?? [];
|
|
2751
|
+
}
|
|
2711
2752
|
async workspaceSymbols(query, signal) {
|
|
2712
2753
|
const options = signal === undefined ? {} : { signal };
|
|
2713
2754
|
return this.sendRequest("workspace/symbol", { query }, options);
|
|
@@ -2747,7 +2788,7 @@ class LspClient extends LspClientConnection {
|
|
|
2747
2788
|
const absPath = this.resolveWorkspacePath(filePath);
|
|
2748
2789
|
const uri = pathToFileURL3(absPath).href;
|
|
2749
2790
|
await this.openFile(absPath);
|
|
2750
|
-
const deadlineAt =
|
|
2791
|
+
const deadlineAt = this.timerProvider.now() + this.diagnosticsFreshnessTimeoutMs;
|
|
2751
2792
|
for (;; ) {
|
|
2752
2793
|
signal?.throwIfAborted();
|
|
2753
2794
|
const snapshot = this.documents.captureDiagnosticSnapshot(absPath);
|
|
@@ -2760,7 +2801,7 @@ class LspClient extends LspClientConnection {
|
|
|
2760
2801
|
if (!pushFallbackOnly) {
|
|
2761
2802
|
const cached = this.documents.getPullCache(snapshot);
|
|
2762
2803
|
try {
|
|
2763
|
-
const remainingMs2 = deadlineAt -
|
|
2804
|
+
const remainingMs2 = deadlineAt - this.timerProvider.now();
|
|
2764
2805
|
if (remainingMs2 <= 0)
|
|
2765
2806
|
return this.freshnessTimeout(absPath);
|
|
2766
2807
|
const result = await this.sendRequest("textDocument/diagnostic", {
|
|
@@ -2795,7 +2836,7 @@ class LspClient extends LspClientConnection {
|
|
|
2795
2836
|
}
|
|
2796
2837
|
if (!pushFallbackOnly)
|
|
2797
2838
|
continue;
|
|
2798
|
-
const remainingMs = deadlineAt -
|
|
2839
|
+
const remainingMs = deadlineAt - this.timerProvider.now();
|
|
2799
2840
|
if (remainingMs <= 0) {
|
|
2800
2841
|
if (!this.isDiagnosticPullSupported() && snapshot.publishGeneration === 0) {
|
|
2801
2842
|
const cached = this.documents.getPullCache(snapshot);
|
|
@@ -2953,18 +2994,16 @@ function awaitWithSignal(promise, signal) {
|
|
|
2953
2994
|
}
|
|
2954
2995
|
|
|
2955
2996
|
class LspManager {
|
|
2956
|
-
clients = new Map;
|
|
2957
|
-
reaperHandle = null;
|
|
2958
|
-
signalDisposer = null;
|
|
2959
|
-
disposed = false;
|
|
2960
|
-
idleTimeoutMs;
|
|
2961
|
-
initTimeoutMs;
|
|
2962
|
-
reaperIntervalMs;
|
|
2963
|
-
clientFactory;
|
|
2964
|
-
now;
|
|
2965
2997
|
constructor(options = {}) {
|
|
2998
|
+
this.clients = new Map;
|
|
2999
|
+
this.pendingStops = new Map;
|
|
3000
|
+
this.respawnBudgets = new Map;
|
|
3001
|
+
this.reaperHandle = null;
|
|
3002
|
+
this.signalDisposer = null;
|
|
3003
|
+
this.disposed = false;
|
|
2966
3004
|
this.idleTimeoutMs = options.idleTimeoutMs ?? IDLE_TIMEOUT_MS;
|
|
2967
3005
|
this.initTimeoutMs = options.initTimeoutMs ?? INIT_TIMEOUT_MS;
|
|
3006
|
+
this.maxResidentClients = options.maxResidentClients ?? MAX_RESIDENT_CLIENTS;
|
|
2968
3007
|
this.reaperIntervalMs = options.reaperIntervalMs ?? REAPER_INTERVAL_MS;
|
|
2969
3008
|
this.clientFactory = options.clientFactory ?? ((root, server) => new LspClient(root, server));
|
|
2970
3009
|
this.now = options.now ?? (() => Date.now());
|
|
@@ -2984,24 +3023,79 @@ class LspManager {
|
|
|
2984
3023
|
getKey(root, serverId) {
|
|
2985
3024
|
return `${root}::${serverId}`;
|
|
2986
3025
|
}
|
|
3026
|
+
tombstoneStop(key, client) {
|
|
3027
|
+
const stop = stopClientBestEffort(client);
|
|
3028
|
+
this.pendingStops.set(key, stop);
|
|
3029
|
+
stop.finally(() => {
|
|
3030
|
+
if (this.pendingStops.get(key) === stop) {
|
|
3031
|
+
this.pendingStops.delete(key);
|
|
3032
|
+
}
|
|
3033
|
+
});
|
|
3034
|
+
return stop;
|
|
3035
|
+
}
|
|
3036
|
+
recordDeadGeneration(key) {
|
|
3037
|
+
let budget = this.respawnBudgets.get(key);
|
|
3038
|
+
if (budget === undefined) {
|
|
3039
|
+
budget = { deadGenerations: 0, exhaustedAt: null };
|
|
3040
|
+
this.respawnBudgets.set(key, budget);
|
|
3041
|
+
}
|
|
3042
|
+
budget.deadGenerations += 1;
|
|
3043
|
+
}
|
|
3044
|
+
markHealthyGeneration(key) {
|
|
3045
|
+
this.respawnBudgets.delete(key);
|
|
3046
|
+
}
|
|
3047
|
+
ensureRespawnAllowed(key, root, serverId) {
|
|
3048
|
+
const budget = this.respawnBudgets.get(key);
|
|
3049
|
+
if (budget === undefined || budget.deadGenerations < CLIENT_RESPAWN_RETRY_LIMIT)
|
|
3050
|
+
return;
|
|
3051
|
+
if (budget.exhaustedAt === null) {
|
|
3052
|
+
budget.exhaustedAt = this.now();
|
|
3053
|
+
throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
|
|
3054
|
+
}
|
|
3055
|
+
if (this.now() - budget.exhaustedAt < CLIENT_RESPAWN_COOLDOWN_MS) {
|
|
3056
|
+
throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
|
|
3057
|
+
}
|
|
3058
|
+
budget.deadGenerations = 0;
|
|
3059
|
+
budget.exhaustedAt = null;
|
|
3060
|
+
}
|
|
2987
3061
|
reapStale() {
|
|
2988
3062
|
const t = this.now();
|
|
2989
3063
|
for (const [key, managed] of this.clients) {
|
|
2990
3064
|
if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
|
|
2991
|
-
stopClientBestEffort(managed.client);
|
|
2992
3065
|
this.clients.delete(key);
|
|
3066
|
+
this.tombstoneStop(key, managed.client);
|
|
2993
3067
|
continue;
|
|
2994
3068
|
}
|
|
2995
3069
|
if (!managed.isInitializing && managed.refCount === 0 && managed.pendingWaiters === 0 && t - managed.lastUsedAt > this.idleTimeoutMs) {
|
|
2996
|
-
stopClientBestEffort(managed.client);
|
|
2997
3070
|
this.clients.delete(key);
|
|
3071
|
+
this.tombstoneStop(key, managed.client);
|
|
3072
|
+
}
|
|
3073
|
+
}
|
|
3074
|
+
}
|
|
3075
|
+
evictForAdmission() {
|
|
3076
|
+
while (this.clients.size >= this.maxResidentClients) {
|
|
3077
|
+
const victim = this.leastRecentlyUsedIdleClient();
|
|
3078
|
+
if (!victim)
|
|
3079
|
+
return;
|
|
3080
|
+
this.clients.delete(victim.key);
|
|
3081
|
+
this.tombstoneStop(victim.key, victim.managed.client);
|
|
3082
|
+
}
|
|
3083
|
+
}
|
|
3084
|
+
leastRecentlyUsedIdleClient() {
|
|
3085
|
+
let candidate = null;
|
|
3086
|
+
for (const [key, managed] of this.clients) {
|
|
3087
|
+
if (managed.refCount > 0 || managed.pendingWaiters > 0 || managed.isInitializing)
|
|
3088
|
+
continue;
|
|
3089
|
+
if (candidate === null || managed.lastUsedAt < candidate.managed.lastUsedAt) {
|
|
3090
|
+
candidate = { key, managed };
|
|
2998
3091
|
}
|
|
2999
3092
|
}
|
|
3093
|
+
return candidate;
|
|
3000
3094
|
}
|
|
3001
3095
|
async tryDeleteIfOrphaned(key, managed) {
|
|
3002
3096
|
if (managed.refCount === 0 && managed.pendingWaiters === 0 && !managed.isInitializing && this.clients.get(key) === managed) {
|
|
3003
3097
|
this.clients.delete(key);
|
|
3004
|
-
await
|
|
3098
|
+
await this.tombstoneStop(key, managed.client);
|
|
3005
3099
|
}
|
|
3006
3100
|
}
|
|
3007
3101
|
async getClient(root, server, signal) {
|
|
@@ -3010,12 +3104,22 @@ class LspManager {
|
|
|
3010
3104
|
}
|
|
3011
3105
|
signal?.throwIfAborted();
|
|
3012
3106
|
const key = this.getKey(root, server.id);
|
|
3107
|
+
for (;; ) {
|
|
3108
|
+
const pendingStop = this.pendingStops.get(key);
|
|
3109
|
+
if (pendingStop === undefined)
|
|
3110
|
+
break;
|
|
3111
|
+
await awaitWithSignal(pendingStop, signal);
|
|
3112
|
+
signal?.throwIfAborted();
|
|
3113
|
+
}
|
|
3114
|
+
if (this.disposed) {
|
|
3115
|
+
throw new Error("LspManager has been disposed");
|
|
3116
|
+
}
|
|
3013
3117
|
let managed = this.clients.get(key);
|
|
3014
3118
|
if (managed) {
|
|
3015
3119
|
const t = this.now();
|
|
3016
3120
|
if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
|
|
3017
|
-
await stopClientBestEffort(managed.client);
|
|
3018
3121
|
this.clients.delete(key);
|
|
3122
|
+
await this.tombstoneStop(key, managed.client);
|
|
3019
3123
|
managed = undefined;
|
|
3020
3124
|
}
|
|
3021
3125
|
}
|
|
@@ -3036,14 +3140,20 @@ class LspManager {
|
|
|
3036
3140
|
signal.throwIfAborted();
|
|
3037
3141
|
}
|
|
3038
3142
|
if (!managed.client.isAlive()) {
|
|
3039
|
-
|
|
3040
|
-
this.clients.
|
|
3143
|
+
this.recordDeadGeneration(key);
|
|
3144
|
+
if (this.clients.get(key) === managed) {
|
|
3145
|
+
this.clients.delete(key);
|
|
3146
|
+
}
|
|
3147
|
+
await this.tombstoneStop(key, managed.client);
|
|
3041
3148
|
return this.getClient(root, server, signal);
|
|
3042
3149
|
}
|
|
3150
|
+
this.markHealthyGeneration(key);
|
|
3043
3151
|
managed.refCount++;
|
|
3044
3152
|
managed.lastUsedAt = this.now();
|
|
3045
3153
|
return managed.client;
|
|
3046
3154
|
}
|
|
3155
|
+
this.evictForAdmission();
|
|
3156
|
+
this.ensureRespawnAllowed(key, root, server.id);
|
|
3047
3157
|
const client = this.clientFactory(root, server);
|
|
3048
3158
|
const initStartedAt = this.now();
|
|
3049
3159
|
const initPromise = (async () => {
|
|
@@ -3067,7 +3177,7 @@ class LspManager {
|
|
|
3067
3177
|
if (this.clients.get(key) === newManaged) {
|
|
3068
3178
|
this.clients.delete(key);
|
|
3069
3179
|
}
|
|
3070
|
-
await
|
|
3180
|
+
await this.tombstoneStop(key, client);
|
|
3071
3181
|
throw err;
|
|
3072
3182
|
}
|
|
3073
3183
|
newManaged.pendingWaiters--;
|
|
@@ -3078,6 +3188,15 @@ class LspManager {
|
|
|
3078
3188
|
await this.tryDeleteIfOrphaned(key, newManaged);
|
|
3079
3189
|
signal.throwIfAborted();
|
|
3080
3190
|
}
|
|
3191
|
+
if (!client.isAlive()) {
|
|
3192
|
+
this.recordDeadGeneration(key);
|
|
3193
|
+
if (this.clients.get(key) === newManaged) {
|
|
3194
|
+
this.clients.delete(key);
|
|
3195
|
+
}
|
|
3196
|
+
await this.tombstoneStop(key, client);
|
|
3197
|
+
return this.getClient(root, server, signal);
|
|
3198
|
+
}
|
|
3199
|
+
this.markHealthyGeneration(key);
|
|
3081
3200
|
newManaged.refCount++;
|
|
3082
3201
|
newManaged.lastUsedAt = this.now();
|
|
3083
3202
|
return client;
|
|
@@ -3098,14 +3217,20 @@ class LspManager {
|
|
|
3098
3217
|
if (client && managed.client !== client)
|
|
3099
3218
|
return;
|
|
3100
3219
|
this.clients.delete(key);
|
|
3101
|
-
|
|
3220
|
+
this.tombstoneStop(key, managed.client);
|
|
3102
3221
|
}
|
|
3103
3222
|
warmupClient(root, server) {
|
|
3104
3223
|
if (this.disposed)
|
|
3105
3224
|
return;
|
|
3106
3225
|
const key = this.getKey(root, server.id);
|
|
3107
|
-
if (this.clients.has(key))
|
|
3226
|
+
if (this.clients.has(key) || this.pendingStops.has(key))
|
|
3227
|
+
return;
|
|
3228
|
+
this.evictForAdmission();
|
|
3229
|
+
try {
|
|
3230
|
+
this.ensureRespawnAllowed(key, root, server.id);
|
|
3231
|
+
} catch {
|
|
3108
3232
|
return;
|
|
3233
|
+
}
|
|
3109
3234
|
const client = this.clientFactory(root, server);
|
|
3110
3235
|
const initStartedAt = this.now();
|
|
3111
3236
|
const initPromise = (async () => {
|
|
@@ -3131,7 +3256,7 @@ class LspManager {
|
|
|
3131
3256
|
if (this.clients.get(key) === managed) {
|
|
3132
3257
|
this.clients.delete(key);
|
|
3133
3258
|
}
|
|
3134
|
-
|
|
3259
|
+
this.tombstoneStop(key, client);
|
|
3135
3260
|
});
|
|
3136
3261
|
}
|
|
3137
3262
|
isServerInitializing(root, serverId) {
|
|
@@ -3175,8 +3300,11 @@ class LspManager {
|
|
|
3175
3300
|
for (const managed of this.clients.values()) {
|
|
3176
3301
|
stopPromises.push(stopClientBestEffort(managed.client));
|
|
3177
3302
|
}
|
|
3303
|
+
const tombstonedStops = [...this.pendingStops.values()];
|
|
3178
3304
|
this.clients.clear();
|
|
3179
|
-
|
|
3305
|
+
this.respawnBudgets.clear();
|
|
3306
|
+
await Promise.allSettled([...stopPromises, ...tombstonedStops]);
|
|
3307
|
+
this.pendingStops.clear();
|
|
3180
3308
|
}
|
|
3181
3309
|
}
|
|
3182
3310
|
var _defaultInstance = null;
|
|
@@ -3194,57 +3322,52 @@ async function disposeDefaultLspManager() {
|
|
|
3194
3322
|
}
|
|
3195
3323
|
}
|
|
3196
3324
|
|
|
3197
|
-
// ../lsp-core/src/lsp/
|
|
3198
|
-
import { existsSync as existsSync6,
|
|
3199
|
-
import { dirname as dirname5 } from "node:path";
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3325
|
+
// ../lsp-core/src/lsp/outside-context-workspace.ts
|
|
3326
|
+
import { existsSync as existsSync6, realpathSync as realpathSync4 } from "node:fs";
|
|
3327
|
+
import { dirname as dirname5, join as join3 } from "node:path";
|
|
3328
|
+
|
|
3329
|
+
// ../lsp-core/src/lsp/workspace-markers.ts
|
|
3330
|
+
var GIT_WORKSPACE_MARKER = ".git";
|
|
3331
|
+
var PROJECT_WORKSPACE_MARKERS = [
|
|
3332
|
+
"package.json",
|
|
3333
|
+
"pyproject.toml",
|
|
3334
|
+
"Cargo.toml",
|
|
3335
|
+
"go.mod",
|
|
3336
|
+
"pom.xml",
|
|
3337
|
+
"build.gradle"
|
|
3338
|
+
];
|
|
3339
|
+
var WORKSPACE_MARKERS = [GIT_WORKSPACE_MARKER, ...PROJECT_WORKSPACE_MARKERS];
|
|
3340
|
+
|
|
3341
|
+
// ../lsp-core/src/lsp/outside-context-workspace.ts
|
|
3342
|
+
function findWorkspaceRootOutsideContext(directory) {
|
|
3343
|
+
const marked = nearestMarkedAncestor(directory);
|
|
3344
|
+
if (marked !== undefined)
|
|
3345
|
+
return marked;
|
|
3346
|
+
return realpathSync4(nearestExistingAncestor(directory));
|
|
3347
|
+
}
|
|
3348
|
+
function nearestMarkedAncestor(directory) {
|
|
3349
|
+
let current = directory;
|
|
3350
|
+
for (;; ) {
|
|
3351
|
+
if (existsSync6(current) && WORKSPACE_MARKERS.some((marker) => existsSync6(join3(current, marker)))) {
|
|
3352
|
+
return realpathSync4(current);
|
|
3353
|
+
}
|
|
3354
|
+
const parent = dirname5(current);
|
|
3355
|
+
if (parent === current)
|
|
3356
|
+
return;
|
|
3357
|
+
current = parent;
|
|
3212
3358
|
}
|
|
3213
3359
|
}
|
|
3214
|
-
function
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
}
|
|
3222
|
-
|
|
3223
|
-
return value === "declined" || value === "allowed";
|
|
3224
|
-
}
|
|
3225
|
-
function writeInstallDecisions(decisions) {
|
|
3226
|
-
const path = getInstallDecisionsPath();
|
|
3227
|
-
mkdirSync(dirname5(path), { recursive: true });
|
|
3228
|
-
const tmpPath = `${path}.tmp`;
|
|
3229
|
-
writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
|
|
3230
|
-
`, "utf8");
|
|
3231
|
-
renameSync2(tmpPath, path);
|
|
3232
|
-
}
|
|
3233
|
-
function isInstallDecisions(value) {
|
|
3234
|
-
return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
|
|
3235
|
-
}
|
|
3236
|
-
function isInstallDecisionRecord(value) {
|
|
3237
|
-
if (!isRecord5(value))
|
|
3238
|
-
return false;
|
|
3239
|
-
return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
|
|
3240
|
-
}
|
|
3241
|
-
function isRecord5(value) {
|
|
3242
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3360
|
+
function nearestExistingAncestor(directory) {
|
|
3361
|
+
let current = directory;
|
|
3362
|
+
while (!existsSync6(current)) {
|
|
3363
|
+
const parent = dirname5(current);
|
|
3364
|
+
if (parent === current)
|
|
3365
|
+
return current;
|
|
3366
|
+
current = parent;
|
|
3367
|
+
}
|
|
3368
|
+
return current;
|
|
3243
3369
|
}
|
|
3244
3370
|
|
|
3245
|
-
// ../lsp-core/src/lsp/config-loader.ts
|
|
3246
|
-
import { existsSync as existsSync7, readFileSync as readFileSync4 } from "node:fs";
|
|
3247
|
-
|
|
3248
3371
|
// ../lsp-core/src/lsp/server-definitions.ts
|
|
3249
3372
|
var LSP_INSTALL_HINTS = {
|
|
3250
3373
|
typescript: "npm install -g typescript-language-server typescript",
|
|
@@ -3290,6 +3413,26 @@ var LSP_INSTALL_HINTS = {
|
|
|
3290
3413
|
julials: `julia -e 'using Pkg; Pkg.add("LanguageServer")'`,
|
|
3291
3414
|
razor: "Razor runs through the Roslyn language server (cohosting). " + "Install: dotnet tool install -g roslyn-language-server --prerelease (requires v5.8.0+). See https://github.com/dotnet/razor"
|
|
3292
3415
|
};
|
|
3416
|
+
var LSP_LOCAL_INSTALL_HINTS = {
|
|
3417
|
+
typescript: "bun add -d typescript-language-server typescript",
|
|
3418
|
+
vue: "bun add -d @vue/language-server",
|
|
3419
|
+
eslint: "bun add -d vscode-langservers-extracted",
|
|
3420
|
+
oxlint: "bun add -d oxlint",
|
|
3421
|
+
biome: "bun add -d @biomejs/biome",
|
|
3422
|
+
svelte: "bun add -d svelte-language-server",
|
|
3423
|
+
astro: "bun add -d @astrojs/language-server",
|
|
3424
|
+
bash: "bun add -d bash-language-server",
|
|
3425
|
+
"bash-ls": "bun add -d bash-language-server",
|
|
3426
|
+
"yaml-ls": "bun add -d yaml-language-server",
|
|
3427
|
+
php: "bun add -d intelephense",
|
|
3428
|
+
prisma: "bun add -d prisma",
|
|
3429
|
+
dockerfile: "bun add -d dockerfile-language-server-nodejs",
|
|
3430
|
+
pyright: "uv add --dev pyright",
|
|
3431
|
+
basedpyright: "uv add --dev basedpyright",
|
|
3432
|
+
ruff: "uv add --dev ruff",
|
|
3433
|
+
ty: "uv add --dev ty",
|
|
3434
|
+
"ruby-lsp": "bundle add ruby-lsp --group development"
|
|
3435
|
+
};
|
|
3293
3436
|
var BUILTIN_SERVERS = {
|
|
3294
3437
|
typescript: {
|
|
3295
3438
|
command: ["typescript-language-server", "--stdio"],
|
|
@@ -3392,7 +3535,56 @@ var BUILTIN_SERVERS = {
|
|
|
3392
3535
|
}
|
|
3393
3536
|
};
|
|
3394
3537
|
|
|
3538
|
+
// ../lsp-core/src/lsp/server-install-state.ts
|
|
3539
|
+
import { existsSync as existsSync7, mkdirSync, readFileSync as readFileSync3, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
3540
|
+
import { dirname as dirname6 } from "node:path";
|
|
3541
|
+
function getInstallDecisionsPath() {
|
|
3542
|
+
return lspRequestContext().installDecisionsPath;
|
|
3543
|
+
}
|
|
3544
|
+
function loadInstallDecisions() {
|
|
3545
|
+
const path = getInstallDecisionsPath();
|
|
3546
|
+
if (!existsSync7(path))
|
|
3547
|
+
return {};
|
|
3548
|
+
try {
|
|
3549
|
+
const parsed = JSON.parse(readFileSync3(path, "utf8"));
|
|
3550
|
+
return isInstallDecisions(parsed) ? parsed : {};
|
|
3551
|
+
} catch {
|
|
3552
|
+
return {};
|
|
3553
|
+
}
|
|
3554
|
+
}
|
|
3555
|
+
function loadInstallDecision(serverId) {
|
|
3556
|
+
return loadInstallDecisions()[serverId];
|
|
3557
|
+
}
|
|
3558
|
+
function recordInstallDecision(serverId, decision, decidedAt = new Date().toISOString()) {
|
|
3559
|
+
const decisions = loadInstallDecisions();
|
|
3560
|
+
decisions[serverId] = { decision, decidedAt };
|
|
3561
|
+
writeInstallDecisions(decisions);
|
|
3562
|
+
}
|
|
3563
|
+
function isInstallDecision(value) {
|
|
3564
|
+
return value === "declined" || value === "allowed";
|
|
3565
|
+
}
|
|
3566
|
+
function writeInstallDecisions(decisions) {
|
|
3567
|
+
const path = getInstallDecisionsPath();
|
|
3568
|
+
mkdirSync(dirname6(path), { recursive: true });
|
|
3569
|
+
const tmpPath = `${path}.tmp`;
|
|
3570
|
+
writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
|
|
3571
|
+
`, "utf8");
|
|
3572
|
+
renameSync2(tmpPath, path);
|
|
3573
|
+
}
|
|
3574
|
+
function isInstallDecisions(value) {
|
|
3575
|
+
return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
|
|
3576
|
+
}
|
|
3577
|
+
function isInstallDecisionRecord(value) {
|
|
3578
|
+
if (!isRecord5(value))
|
|
3579
|
+
return false;
|
|
3580
|
+
return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
|
|
3581
|
+
}
|
|
3582
|
+
function isRecord5(value) {
|
|
3583
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3584
|
+
}
|
|
3585
|
+
|
|
3395
3586
|
// ../lsp-core/src/lsp/config-loader.ts
|
|
3587
|
+
import { existsSync as existsSync8, readFileSync as readFileSync4 } from "node:fs";
|
|
3396
3588
|
function getProjectConfigPaths() {
|
|
3397
3589
|
return lspRequestContext().projectConfigPaths;
|
|
3398
3590
|
}
|
|
@@ -3400,7 +3592,7 @@ function getUserConfigPath() {
|
|
|
3400
3592
|
return lspRequestContext().userConfigPath;
|
|
3401
3593
|
}
|
|
3402
3594
|
function loadJsonFile(path) {
|
|
3403
|
-
if (!
|
|
3595
|
+
if (!existsSync8(path))
|
|
3404
3596
|
return null;
|
|
3405
3597
|
try {
|
|
3406
3598
|
const parsed = JSON.parse(readFileSync4(path, "utf-8"));
|
|
@@ -3588,54 +3780,155 @@ function getDisabledServerIds() {
|
|
|
3588
3780
|
}
|
|
3589
3781
|
|
|
3590
3782
|
// ../lsp-core/src/lsp/server-installation.ts
|
|
3591
|
-
import { existsSync as
|
|
3592
|
-
import { delimiter as delimiter3, join as
|
|
3593
|
-
|
|
3594
|
-
|
|
3595
|
-
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
3783
|
+
import { existsSync as existsSync9 } from "node:fs";
|
|
3784
|
+
import { delimiter as delimiter3, dirname as dirname7, isAbsolute as isAbsolute3, join as join4, resolve as resolve7 } from "node:path";
|
|
3785
|
+
var LOCAL_BIN_RULES = [
|
|
3786
|
+
{
|
|
3787
|
+
markers: ["package.json", "bun.lock", "bun.lockb", "package-lock.json", "yarn.lock", "pnpm-lock.yaml"],
|
|
3788
|
+
binDirs: [join4("node_modules", ".bin")]
|
|
3789
|
+
},
|
|
3790
|
+
{
|
|
3791
|
+
markers: [
|
|
3792
|
+
"pyproject.toml",
|
|
3793
|
+
"ty.toml",
|
|
3794
|
+
"requirements.txt",
|
|
3795
|
+
"setup.py",
|
|
3796
|
+
"setup.cfg",
|
|
3797
|
+
"Pipfile",
|
|
3798
|
+
"pyrightconfig.json",
|
|
3799
|
+
"ruff.toml",
|
|
3800
|
+
".ruff.toml"
|
|
3801
|
+
],
|
|
3802
|
+
binDirs: [
|
|
3803
|
+
join4(".venv", "bin"),
|
|
3804
|
+
join4(".venv", "Scripts"),
|
|
3805
|
+
join4("venv", "bin"),
|
|
3806
|
+
join4("venv", "Scripts"),
|
|
3807
|
+
join4(".env", "bin"),
|
|
3808
|
+
join4(".env", "Scripts")
|
|
3809
|
+
]
|
|
3810
|
+
},
|
|
3811
|
+
{
|
|
3812
|
+
markers: ["Gemfile", "Gemfile.lock"],
|
|
3813
|
+
binDirs: [join4("vendor", "bundle", "bin"), "bin"]
|
|
3814
|
+
},
|
|
3815
|
+
{
|
|
3816
|
+
markers: ["go.mod", "go.sum", "go.work"],
|
|
3817
|
+
binDirs: ["bin"]
|
|
3818
|
+
}
|
|
3819
|
+
];
|
|
3820
|
+
var resolutionCache = new Map;
|
|
3821
|
+
var probeCount = 0;
|
|
3822
|
+
function probe(path) {
|
|
3823
|
+
probeCount += 1;
|
|
3824
|
+
return existsSync9(path);
|
|
3825
|
+
}
|
|
3826
|
+
function executableSuffixes(platform, pathExt) {
|
|
3827
|
+
if (platform !== "win32")
|
|
3828
|
+
return [""];
|
|
3829
|
+
const configured = pathExt ?? process.env["PATHEXT"] ?? "";
|
|
3830
|
+
const systemExts = configured.split(";").filter((entry) => entry.length > 0).map((entry) => entry.toLowerCase());
|
|
3831
|
+
return [...new Set(["", ...systemExts, ".exe", ".cmd", ".bat", ".ps1"])];
|
|
3832
|
+
}
|
|
3833
|
+
function probeWithSuffixes(directory, command, suffixes) {
|
|
3834
|
+
for (const suffix of suffixes) {
|
|
3835
|
+
const candidate = join4(directory, command + suffix);
|
|
3836
|
+
if (probe(candidate))
|
|
3837
|
+
return candidate;
|
|
3602
3838
|
}
|
|
3603
|
-
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
|
|
3839
|
+
return null;
|
|
3840
|
+
}
|
|
3841
|
+
function resolveLocal(command, workingDirectory, suffixes, stopAt) {
|
|
3842
|
+
const boundary = stopAt === undefined ? undefined : resolve7(stopAt);
|
|
3843
|
+
let current = resolve7(workingDirectory);
|
|
3844
|
+
while (true) {
|
|
3845
|
+
for (const rule of LOCAL_BIN_RULES) {
|
|
3846
|
+
if (!rule.markers.some((marker) => probe(join4(current, marker))))
|
|
3847
|
+
continue;
|
|
3848
|
+
for (const binDir of rule.binDirs) {
|
|
3849
|
+
const found = probeWithSuffixes(join4(current, binDir), command, suffixes);
|
|
3850
|
+
if (found !== null)
|
|
3851
|
+
return found;
|
|
3852
|
+
}
|
|
3612
3853
|
}
|
|
3854
|
+
if (probe(join4(current, ".git")))
|
|
3855
|
+
return null;
|
|
3856
|
+
if (boundary !== undefined && current === boundary)
|
|
3857
|
+
return null;
|
|
3858
|
+
const parent = dirname7(current);
|
|
3859
|
+
if (parent === current)
|
|
3860
|
+
return null;
|
|
3861
|
+
current = parent;
|
|
3613
3862
|
}
|
|
3614
|
-
|
|
3615
|
-
|
|
3863
|
+
}
|
|
3864
|
+
function resolveFromPath(command, suffixes, platform, pathEnvOverride) {
|
|
3865
|
+
let pathEnv = pathEnvOverride ?? process.env["PATH"] ?? "";
|
|
3866
|
+
if (platform === "win32" && !pathEnv) {
|
|
3616
3867
|
pathEnv = process.env["Path"] ?? "";
|
|
3617
3868
|
}
|
|
3618
|
-
const
|
|
3619
|
-
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
}
|
|
3869
|
+
for (const entry of pathEnv.split(delimiter3)) {
|
|
3870
|
+
if (entry.length === 0)
|
|
3871
|
+
continue;
|
|
3872
|
+
const found = probeWithSuffixes(entry, command, suffixes);
|
|
3873
|
+
if (found !== null)
|
|
3874
|
+
return found;
|
|
3625
3875
|
}
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
|
|
3876
|
+
return null;
|
|
3877
|
+
}
|
|
3878
|
+
function resolveServerBinary(command, workingDirectory, options = {}) {
|
|
3879
|
+
if (command.length === 0)
|
|
3880
|
+
return null;
|
|
3881
|
+
const [cmd] = command;
|
|
3882
|
+
if (cmd === undefined || cmd.length === 0)
|
|
3883
|
+
return null;
|
|
3884
|
+
const platform = options.platform ?? process.platform;
|
|
3885
|
+
const suffixes = executableSuffixes(platform, options.pathExt);
|
|
3886
|
+
if (cmd.includes("/") || cmd.includes("\\")) {
|
|
3887
|
+
const explicit = isAbsolute3(cmd) ? cmd : resolve7(workingDirectory ?? process.cwd(), cmd);
|
|
3888
|
+
return probe(explicit) ? explicit : null;
|
|
3889
|
+
}
|
|
3890
|
+
const cacheKey = JSON.stringify([
|
|
3891
|
+
workingDirectory ?? "",
|
|
3892
|
+
cmd,
|
|
3893
|
+
platform,
|
|
3894
|
+
options.stopAt ?? "",
|
|
3895
|
+
options.pathExt ?? "",
|
|
3896
|
+
options.pathEnv ?? process.env["PATH"] ?? ""
|
|
3897
|
+
]);
|
|
3898
|
+
const cached = resolutionCache.get(cacheKey);
|
|
3899
|
+
if (cached !== undefined)
|
|
3900
|
+
return cached;
|
|
3901
|
+
let resolved = null;
|
|
3902
|
+
if (workingDirectory !== undefined && workingDirectory.length > 0) {
|
|
3903
|
+
resolved = resolveLocal(cmd, workingDirectory, suffixes, options.stopAt);
|
|
3904
|
+
}
|
|
3905
|
+
resolved ??= resolveFromPath(cmd, suffixes, platform, options.pathEnv);
|
|
3906
|
+
if (resolved === null && cmd === "node")
|
|
3907
|
+
resolved = cmd;
|
|
3908
|
+
resolutionCache.set(cacheKey, resolved);
|
|
3909
|
+
return resolved;
|
|
3910
|
+
}
|
|
3911
|
+
function isServerInstalled(command, workingDirectory, options = {}) {
|
|
3912
|
+
if (command.length === 0)
|
|
3913
|
+
return false;
|
|
3914
|
+
return resolveServerBinary(command, workingDirectory, options) !== null;
|
|
3629
3915
|
}
|
|
3630
3916
|
|
|
3631
3917
|
// ../lsp-core/src/lsp/server-resolution.ts
|
|
3918
|
+
function withResolvedCommand(command, binaryPath) {
|
|
3919
|
+
return [binaryPath, ...command.slice(1)];
|
|
3920
|
+
}
|
|
3632
3921
|
function findServerForExtension(ext) {
|
|
3633
3922
|
const servers = getMergedServers();
|
|
3923
|
+
const workingDirectory = contextCwd();
|
|
3634
3924
|
for (const server of servers) {
|
|
3635
|
-
if (server.extensions.includes(ext)
|
|
3925
|
+
if (!server.extensions.includes(ext))
|
|
3926
|
+
continue;
|
|
3927
|
+
const binaryPath = resolveServerBinary(server.command, workingDirectory);
|
|
3928
|
+
if (binaryPath !== null) {
|
|
3636
3929
|
const resolvedServer = {
|
|
3637
3930
|
id: server.id,
|
|
3638
|
-
command: server.command,
|
|
3931
|
+
command: withResolvedCommand(server.command, binaryPath),
|
|
3639
3932
|
extensions: server.extensions,
|
|
3640
3933
|
priority: server.priority
|
|
3641
3934
|
};
|
|
@@ -3682,6 +3975,7 @@ function findServerForExtension(ext) {
|
|
|
3682
3975
|
function getAllServers() {
|
|
3683
3976
|
const servers = getMergedServers();
|
|
3684
3977
|
const disabled = getDisabledServerIds();
|
|
3978
|
+
const workingDirectory = contextCwd();
|
|
3685
3979
|
const result = [];
|
|
3686
3980
|
const seen = new Set;
|
|
3687
3981
|
for (const server of servers) {
|
|
@@ -3689,7 +3983,7 @@ function getAllServers() {
|
|
|
3689
3983
|
continue;
|
|
3690
3984
|
result.push({
|
|
3691
3985
|
id: server.id,
|
|
3692
|
-
installed: isServerInstalled(server.command),
|
|
3986
|
+
installed: isServerInstalled(server.command, workingDirectory),
|
|
3693
3987
|
extensions: server.extensions,
|
|
3694
3988
|
disabled: false,
|
|
3695
3989
|
source: server.source,
|
|
@@ -3703,7 +3997,7 @@ function getAllServers() {
|
|
|
3703
3997
|
const builtin = BUILTIN_SERVERS[id];
|
|
3704
3998
|
result.push({
|
|
3705
3999
|
id,
|
|
3706
|
-
installed: builtin ? isServerInstalled(builtin.command) : false,
|
|
4000
|
+
installed: builtin ? isServerInstalled(builtin.command, workingDirectory) : false,
|
|
3707
4001
|
extensions: builtin?.extensions ?? [],
|
|
3708
4002
|
disabled: true,
|
|
3709
4003
|
source: "disabled",
|
|
@@ -3714,7 +4008,6 @@ function getAllServers() {
|
|
|
3714
4008
|
}
|
|
3715
4009
|
|
|
3716
4010
|
// ../lsp-core/src/lsp/client-wrapper.ts
|
|
3717
|
-
var WORKSPACE_MARKERS = [".git", "package.json", "pyproject.toml", "Cargo.toml", "go.mod", "pom.xml", "build.gradle"];
|
|
3718
4011
|
function isDirectoryPath(filePath) {
|
|
3719
4012
|
try {
|
|
3720
4013
|
return statSync3(filePath).isDirectory();
|
|
@@ -3723,32 +4016,90 @@ function isDirectoryPath(filePath) {
|
|
|
3723
4016
|
}
|
|
3724
4017
|
}
|
|
3725
4018
|
function findWorkspaceRoot(filePath) {
|
|
3726
|
-
const
|
|
4019
|
+
const cwd = contextCwd();
|
|
4020
|
+
const abs = resolveReadablePathInsideContext(filePath);
|
|
3727
4021
|
let dir = abs;
|
|
3728
4022
|
if (!isDirectoryPath(dir)) {
|
|
3729
|
-
dir =
|
|
3730
|
-
}
|
|
3731
|
-
|
|
3732
|
-
|
|
3733
|
-
|
|
3734
|
-
|
|
3735
|
-
|
|
4023
|
+
dir = dirname8(dir);
|
|
4024
|
+
}
|
|
4025
|
+
if (!isPathInside(cwd, abs))
|
|
4026
|
+
return findWorkspaceRootOutsideContext(dir);
|
|
4027
|
+
const fallbackRoot = nearestExistingDirectoryInsideContext(dir, cwd) ?? cwd;
|
|
4028
|
+
let nearestPackageRoot;
|
|
4029
|
+
while (isPathInside(cwd, dir)) {
|
|
4030
|
+
const canonicalDir = existingDirectoryInsideContext(dir, cwd);
|
|
4031
|
+
if (canonicalDir !== undefined) {
|
|
4032
|
+
if (existsSync10(join5(dir, GIT_WORKSPACE_MARKER))) {
|
|
4033
|
+
return canonicalDir;
|
|
4034
|
+
}
|
|
4035
|
+
if (nearestPackageRoot === undefined && hasProjectWorkspaceMarker(dir)) {
|
|
4036
|
+
nearestPackageRoot = canonicalDir;
|
|
3736
4037
|
}
|
|
3737
4038
|
}
|
|
3738
|
-
|
|
3739
|
-
|
|
4039
|
+
if (dir === cwd)
|
|
4040
|
+
break;
|
|
4041
|
+
dir = dirname8(dir);
|
|
3740
4042
|
}
|
|
3741
|
-
return
|
|
4043
|
+
return nearestPackageRoot ?? fallbackRoot;
|
|
4044
|
+
}
|
|
4045
|
+
function hasProjectWorkspaceMarker(directory) {
|
|
4046
|
+
return PROJECT_WORKSPACE_MARKERS.some((marker) => existsSync10(join5(directory, marker)));
|
|
4047
|
+
}
|
|
4048
|
+
function resolveReadablePathInsideContext(filePath) {
|
|
4049
|
+
const cwd = contextCwd();
|
|
4050
|
+
const abs = resolve8(cwd, filePath);
|
|
4051
|
+
if (isPathInside(cwd, abs))
|
|
4052
|
+
return abs;
|
|
4053
|
+
const rebased = rebaseThroughCanonicalAncestor(abs, cwd);
|
|
4054
|
+
if (rebased !== undefined)
|
|
4055
|
+
return rebased;
|
|
4056
|
+
return canonicalizeExistingOrNearestAncestor(abs);
|
|
3742
4057
|
}
|
|
3743
4058
|
function resolvePathInsideContext(filePath) {
|
|
3744
4059
|
const cwd = contextCwd();
|
|
3745
|
-
const abs =
|
|
4060
|
+
const abs = resolveReadablePathInsideContext(filePath);
|
|
3746
4061
|
const canonical = canonicalizeExistingOrNearestAncestor(abs);
|
|
3747
4062
|
if (!isPathInside(cwd, canonical)) {
|
|
3748
4063
|
throw new LspInvalidPathError(`LSP file path must be inside request cwd: ${filePath}`);
|
|
3749
4064
|
}
|
|
3750
4065
|
return canonical;
|
|
3751
4066
|
}
|
|
4067
|
+
function rebaseThroughCanonicalAncestor(path, cwd) {
|
|
4068
|
+
let current = path;
|
|
4069
|
+
const suffix = [];
|
|
4070
|
+
while (true) {
|
|
4071
|
+
if (existsSync10(current)) {
|
|
4072
|
+
const canonical = realpathSync5(current);
|
|
4073
|
+
if (isPathInside(cwd, canonical))
|
|
4074
|
+
return suffix.length === 0 ? canonical : join5(canonical, ...suffix);
|
|
4075
|
+
}
|
|
4076
|
+
const parent = dirname8(current);
|
|
4077
|
+
if (parent === current)
|
|
4078
|
+
return;
|
|
4079
|
+
suffix.unshift(basename3(current));
|
|
4080
|
+
current = parent;
|
|
4081
|
+
}
|
|
4082
|
+
}
|
|
4083
|
+
function existingDirectoryInsideContext(directory, cwd) {
|
|
4084
|
+
if (!existsSync10(directory))
|
|
4085
|
+
return;
|
|
4086
|
+
const canonical = realpathSync5(directory);
|
|
4087
|
+
if (!statSync3(canonical).isDirectory())
|
|
4088
|
+
return;
|
|
4089
|
+
return isPathInside(cwd, canonical) ? canonical : undefined;
|
|
4090
|
+
}
|
|
4091
|
+
function nearestExistingDirectoryInsideContext(directory, cwd) {
|
|
4092
|
+
let current = directory;
|
|
4093
|
+
while (isPathInside(cwd, current)) {
|
|
4094
|
+
const canonical = existingDirectoryInsideContext(current, cwd);
|
|
4095
|
+
if (canonical !== undefined)
|
|
4096
|
+
return canonical;
|
|
4097
|
+
if (current === cwd)
|
|
4098
|
+
return;
|
|
4099
|
+
current = dirname8(current);
|
|
4100
|
+
}
|
|
4101
|
+
return;
|
|
4102
|
+
}
|
|
3752
4103
|
function formatServerLookupError(result) {
|
|
3753
4104
|
if (result.status === "not_installed") {
|
|
3754
4105
|
return formatNotInstalled(result);
|
|
@@ -3772,6 +4123,19 @@ function formatServerLookupError(result) {
|
|
|
3772
4123
|
].join(`
|
|
3773
4124
|
`);
|
|
3774
4125
|
}
|
|
4126
|
+
function formatInstallOptions(serverId, installHint) {
|
|
4127
|
+
const localHint = LSP_LOCAL_INSTALL_HINTS[serverId];
|
|
4128
|
+
if (localHint === undefined) {
|
|
4129
|
+
return ["To install, run:", ` ${installHint}`];
|
|
4130
|
+
}
|
|
4131
|
+
return [
|
|
4132
|
+
"To install in THIS repository (preferred — no global install needed):",
|
|
4133
|
+
` ${localHint}`,
|
|
4134
|
+
"",
|
|
4135
|
+
"Or install it globally:",
|
|
4136
|
+
` ${installHint}`
|
|
4137
|
+
];
|
|
4138
|
+
}
|
|
3775
4139
|
function formatNotInstalled(result) {
|
|
3776
4140
|
const { server, installHint } = result;
|
|
3777
4141
|
const extensions = server.extensions.join(", ");
|
|
@@ -3786,19 +4150,19 @@ function formatNotInstalled(result) {
|
|
|
3786
4150
|
`Command not found: ${server.command[0]}`,
|
|
3787
4151
|
""
|
|
3788
4152
|
];
|
|
4153
|
+
const installOptions = formatInstallOptions(server.id, installHint);
|
|
3789
4154
|
if (decision === "allowed") {
|
|
3790
4155
|
return [
|
|
3791
4156
|
...header,
|
|
3792
4157
|
"The user has pre-authorized LSP installation. Run the install command, then retry this tool:",
|
|
3793
|
-
|
|
4158
|
+
...installOptions.slice(1)
|
|
3794
4159
|
].join(`
|
|
3795
4160
|
`);
|
|
3796
4161
|
}
|
|
3797
4162
|
if (!context.capabilities.installDecisionTool) {
|
|
3798
4163
|
return [
|
|
3799
4164
|
...header,
|
|
3800
|
-
|
|
3801
|
-
` ${installHint}`,
|
|
4165
|
+
...installOptions,
|
|
3802
4166
|
"",
|
|
3803
4167
|
"ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
|
|
3804
4168
|
"Install-decision recording is unavailable in this harness; proceed without LSP if the user declines."
|
|
@@ -3807,8 +4171,7 @@ function formatNotInstalled(result) {
|
|
|
3807
4171
|
}
|
|
3808
4172
|
return [
|
|
3809
4173
|
...header,
|
|
3810
|
-
|
|
3811
|
-
` ${installHint}`,
|
|
4174
|
+
...installOptions,
|
|
3812
4175
|
"",
|
|
3813
4176
|
"ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
|
|
3814
4177
|
"- If the user agrees: run the install command above, then retry this tool.",
|
|
@@ -3819,7 +4182,7 @@ function formatNotInstalled(result) {
|
|
|
3819
4182
|
].join(`
|
|
3820
4183
|
`);
|
|
3821
4184
|
}
|
|
3822
|
-
var
|
|
4185
|
+
var READ_ONLY_TOOLS = new Set([
|
|
3823
4186
|
"diagnostics",
|
|
3824
4187
|
"definition",
|
|
3825
4188
|
"references",
|
|
@@ -3828,7 +4191,7 @@ var READ_ONLY_RETRY_TOOLS = new Set([
|
|
|
3828
4191
|
"prepareRename"
|
|
3829
4192
|
]);
|
|
3830
4193
|
async function withLspClient(filePath, fn, toolName, options = {}) {
|
|
3831
|
-
const absPath = resolvePathInsideContext(filePath);
|
|
4194
|
+
const absPath = READ_ONLY_TOOLS.has(toolName) ? resolveReadablePathInsideContext(filePath) : resolvePathInsideContext(filePath);
|
|
3832
4195
|
if (isDirectoryPath(absPath)) {
|
|
3833
4196
|
throw new LspInvalidPathError("Directory paths are not supported by this LSP tool. " + "Use lsp.diagnostics with a directory path for directory diagnostics.");
|
|
3834
4197
|
}
|
|
@@ -3843,9 +4206,9 @@ async function withLspClient(filePath, fn, toolName, options = {}) {
|
|
|
3843
4206
|
const acquireAndCall = async (allowRetry) => {
|
|
3844
4207
|
const client = await manager.getClient(root, server, options.signal);
|
|
3845
4208
|
try {
|
|
3846
|
-
return await fn(client, root);
|
|
4209
|
+
return await fn(client, root, absPath);
|
|
3847
4210
|
} catch (err) {
|
|
3848
|
-
if (allowRetry &&
|
|
4211
|
+
if (allowRetry && READ_ONLY_TOOLS.has(toolName) && isLspDeadConnectionError(err)) {
|
|
3849
4212
|
manager.invalidateClient(root, server.id, client);
|
|
3850
4213
|
return acquireAndCall(false);
|
|
3851
4214
|
}
|
|
@@ -3863,8 +4226,8 @@ async function withLspClient(filePath, fn, toolName, options = {}) {
|
|
|
3863
4226
|
}
|
|
3864
4227
|
|
|
3865
4228
|
// ../lsp-core/src/lsp/directory-diagnostics.ts
|
|
3866
|
-
import { existsSync as
|
|
3867
|
-
import { join as
|
|
4229
|
+
import { existsSync as existsSync11, lstatSync as lstatSync4, readdirSync as readdirSync3 } from "node:fs";
|
|
4230
|
+
import { join as join6, resolve as resolve9 } from "node:path";
|
|
3868
4231
|
|
|
3869
4232
|
// ../lsp-core/src/lsp/formatters.ts
|
|
3870
4233
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
@@ -3994,7 +4357,7 @@ function collectFilesWithExtension(dir, extension, maxFiles) {
|
|
|
3994
4357
|
for (const entry of entries) {
|
|
3995
4358
|
if (files.length >= maxFiles)
|
|
3996
4359
|
return;
|
|
3997
|
-
const fullPath =
|
|
4360
|
+
const fullPath = join6(currentDir, entry);
|
|
3998
4361
|
let stat;
|
|
3999
4362
|
try {
|
|
4000
4363
|
stat = lstatSync4(fullPath);
|
|
@@ -4019,8 +4382,8 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
|
|
|
4019
4382
|
if (!extension.startsWith(".")) {
|
|
4020
4383
|
throw new LspInvalidPathError(`Extension must start with a dot (e.g., ".ts", not "${extension}"). Use ".${extension}" instead.`);
|
|
4021
4384
|
}
|
|
4022
|
-
const absDir =
|
|
4023
|
-
if (!
|
|
4385
|
+
const absDir = resolve9(options.workspaceRoot ?? contextCwd(), directory);
|
|
4386
|
+
if (!existsSync11(absDir)) {
|
|
4024
4387
|
throw new LspInvalidPathError(`Directory does not exist: ${absDir}`);
|
|
4025
4388
|
}
|
|
4026
4389
|
const serverResult = options.server === undefined ? findServerForExtension(extension) : { status: "found", server: options.server };
|
|
@@ -4107,7 +4470,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
|
|
|
4107
4470
|
|
|
4108
4471
|
// ../lsp-core/src/lsp/infer-extension.ts
|
|
4109
4472
|
import { lstatSync as lstatSync5, readdirSync as readdirSync4 } from "node:fs";
|
|
4110
|
-
import { join as
|
|
4473
|
+
import { join as join7 } from "node:path";
|
|
4111
4474
|
var SKIP_DIRECTORIES2 = new Set(["node_modules", ".git", "dist", "build", ".next", "out"]);
|
|
4112
4475
|
var MAX_SCAN_ENTRIES = 500;
|
|
4113
4476
|
function inferExtensionFromDirectory(directory) {
|
|
@@ -4125,7 +4488,7 @@ function inferExtensionFromDirectory(directory) {
|
|
|
4125
4488
|
for (const entry of entries) {
|
|
4126
4489
|
if (scanned >= MAX_SCAN_ENTRIES)
|
|
4127
4490
|
return;
|
|
4128
|
-
const fullPath =
|
|
4491
|
+
const fullPath = join7(dir, entry);
|
|
4129
4492
|
let stat;
|
|
4130
4493
|
try {
|
|
4131
4494
|
stat = lstatSync5(fullPath);
|
|
@@ -4300,7 +4663,7 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
4300
4663
|
const filePath = requireString(params, "filePath");
|
|
4301
4664
|
const severity = severityFilter(params);
|
|
4302
4665
|
try {
|
|
4303
|
-
const absPath =
|
|
4666
|
+
const absPath = resolveReadablePathInsideContext(filePath);
|
|
4304
4667
|
if (isDirectoryPath(absPath)) {
|
|
4305
4668
|
const extension = inferExtensionFromDirectory(absPath);
|
|
4306
4669
|
if (!extension) {
|
|
@@ -4329,7 +4692,7 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
4329
4692
|
};
|
|
4330
4693
|
return text(output2.output, details2);
|
|
4331
4694
|
}
|
|
4332
|
-
const result = await withLspClient(filePath, async (client) => client.diagnostics(
|
|
4695
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.diagnostics(resolvedFilePath, signal), "diagnostics", clientOptions(signal));
|
|
4333
4696
|
if (result.transientError) {
|
|
4334
4697
|
const message = result.transientError.message;
|
|
4335
4698
|
const details2 = {
|
|
@@ -4376,6 +4739,96 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
4376
4739
|
throw error;
|
|
4377
4740
|
}
|
|
4378
4741
|
}
|
|
4742
|
+
// ../lsp-core/src/lsp/format-document.ts
|
|
4743
|
+
import { readFileSync as readFileSync5, renameSync as renameSync3, unlinkSync, writeFileSync as writeFileSync3 } from "node:fs";
|
|
4744
|
+
var DEFAULT_FORMATTING_OPTIONS = {
|
|
4745
|
+
tabSize: 4,
|
|
4746
|
+
insertSpaces: false,
|
|
4747
|
+
trimTrailingWhitespace: true,
|
|
4748
|
+
insertFinalNewline: true,
|
|
4749
|
+
trimFinalNewlines: true
|
|
4750
|
+
};
|
|
4751
|
+
var UNCHANGED = { status: "unchanged", linesAdded: 0, linesRemoved: 0 };
|
|
4752
|
+
async function formatDocumentWithClient(client, filePath, options = {}) {
|
|
4753
|
+
const edits = await client.formatDocument(filePath, options.formattingOptions ?? DEFAULT_FORMATTING_OPTIONS, options.signal);
|
|
4754
|
+
if (edits === null)
|
|
4755
|
+
return { status: "unavailable", reason: "capability_not_advertised" };
|
|
4756
|
+
if (edits.length === 0)
|
|
4757
|
+
return UNCHANGED;
|
|
4758
|
+
const before = readFileSync5(filePath, "utf-8");
|
|
4759
|
+
const normalized = normalizeTextEdits(before, edits, 0);
|
|
4760
|
+
if (normalized.text === before)
|
|
4761
|
+
return UNCHANGED;
|
|
4762
|
+
writeAtomically(filePath, normalized.text);
|
|
4763
|
+
await client.openFile(filePath);
|
|
4764
|
+
return {
|
|
4765
|
+
status: "formatted",
|
|
4766
|
+
...lineDelta(normalized.edits)
|
|
4767
|
+
};
|
|
4768
|
+
}
|
|
4769
|
+
function lineDelta(edits) {
|
|
4770
|
+
let linesAdded = 0;
|
|
4771
|
+
let linesRemoved = 0;
|
|
4772
|
+
for (const edit of edits) {
|
|
4773
|
+
linesRemoved += edit.range.end.line - edit.range.start.line + 1;
|
|
4774
|
+
linesAdded += edit.newText.split(`
|
|
4775
|
+
`).length;
|
|
4776
|
+
}
|
|
4777
|
+
return { linesAdded, linesRemoved };
|
|
4778
|
+
}
|
|
4779
|
+
function writeAtomically(filePath, content) {
|
|
4780
|
+
const tempPath = `${filePath}.omo-format.tmp`;
|
|
4781
|
+
writeFileSync3(tempPath, content, "utf-8");
|
|
4782
|
+
try {
|
|
4783
|
+
renameSync3(tempPath, filePath);
|
|
4784
|
+
} catch (error) {
|
|
4785
|
+
try {
|
|
4786
|
+
unlinkSync(tempPath);
|
|
4787
|
+
} catch {}
|
|
4788
|
+
throw error;
|
|
4789
|
+
}
|
|
4790
|
+
}
|
|
4791
|
+
|
|
4792
|
+
// ../lsp-core/src/tools/format.ts
|
|
4793
|
+
async function executeLspFormat(params, signal) {
|
|
4794
|
+
const filePath = requireString(params, "filePath");
|
|
4795
|
+
try {
|
|
4796
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => formatDocumentWithClient(client, resolvedFilePath, signal === undefined ? {} : { signal }), "format", clientOptions(signal));
|
|
4797
|
+
return text(describeResult(filePath, result), formatDetails(filePath, result));
|
|
4798
|
+
} catch (error) {
|
|
4799
|
+
const missingDependency = missingDependencyResult(error, {
|
|
4800
|
+
filePath,
|
|
4801
|
+
status: "unavailable",
|
|
4802
|
+
reason: "server_unavailable",
|
|
4803
|
+
linesAdded: 0,
|
|
4804
|
+
linesRemoved: 0
|
|
4805
|
+
});
|
|
4806
|
+
if (missingDependency)
|
|
4807
|
+
return missingDependency;
|
|
4808
|
+
throw error;
|
|
4809
|
+
}
|
|
4810
|
+
}
|
|
4811
|
+
function formatDetails(filePath, result) {
|
|
4812
|
+
if (result.status === "unavailable") {
|
|
4813
|
+
return { filePath, status: "unavailable", reason: result.reason, linesAdded: 0, linesRemoved: 0 };
|
|
4814
|
+
}
|
|
4815
|
+
return {
|
|
4816
|
+
filePath,
|
|
4817
|
+
status: result.status,
|
|
4818
|
+
linesAdded: result.linesAdded,
|
|
4819
|
+
linesRemoved: result.linesRemoved
|
|
4820
|
+
};
|
|
4821
|
+
}
|
|
4822
|
+
function describeResult(filePath, result) {
|
|
4823
|
+
if (result.status === "unavailable") {
|
|
4824
|
+
return `Formatting unavailable for ${filePath}: the language server does not advertise documentFormattingProvider.`;
|
|
4825
|
+
}
|
|
4826
|
+
if (result.status === "unchanged") {
|
|
4827
|
+
return `Already formatted: ${filePath}`;
|
|
4828
|
+
}
|
|
4829
|
+
return `Formatted ${filePath} (+${result.linesAdded}/-${result.linesRemoved} lines)`;
|
|
4830
|
+
}
|
|
4831
|
+
|
|
4379
4832
|
// ../lsp-core/src/tools/install-decision.ts
|
|
4380
4833
|
async function executeLspInstallDecision(params) {
|
|
4381
4834
|
const serverId = requireString(params, "server_id");
|
|
@@ -4404,7 +4857,7 @@ async function executeLspGotoDefinition(params, signal) {
|
|
|
4404
4857
|
const line = requireNumber(params, "line");
|
|
4405
4858
|
const character = requireNumber(params, "character");
|
|
4406
4859
|
try {
|
|
4407
|
-
const result = await withLspClient(filePath, async (client) => client.definition(
|
|
4860
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.definition(resolvedFilePath, line, character, signal), "definition", clientOptions(signal));
|
|
4408
4861
|
const locations = !result ? [] : Array.isArray(result) ? result : [result];
|
|
4409
4862
|
const details = { filePath, line, character, locations };
|
|
4410
4863
|
if (locations.length === 0)
|
|
@@ -4429,7 +4882,7 @@ async function executeLspFindReferences(params, signal) {
|
|
|
4429
4882
|
const character = requireNumber(params, "character");
|
|
4430
4883
|
const includeDeclaration = optionalBoolean(params, "includeDeclaration") ?? true;
|
|
4431
4884
|
try {
|
|
4432
|
-
const result = await withLspClient(filePath, async (client) => client.references(
|
|
4885
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.references(resolvedFilePath, line, character, includeDeclaration, signal), "references", clientOptions(signal));
|
|
4433
4886
|
const references = Array.isArray(result) ? result : [];
|
|
4434
4887
|
const total = references.length;
|
|
4435
4888
|
const truncated = total > DEFAULT_MAX_REFERENCES;
|
|
@@ -4471,7 +4924,7 @@ async function executeLspPrepareRename(params, signal) {
|
|
|
4471
4924
|
const line = requireNumber(params, "line");
|
|
4472
4925
|
const character = requireNumber(params, "character");
|
|
4473
4926
|
try {
|
|
4474
|
-
const result = await withLspClient(filePath, async (client) => client.prepareRename(
|
|
4927
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.prepareRename(resolvedFilePath, line, character, signal), "prepareRename", clientOptions(signal));
|
|
4475
4928
|
const details = { filePath, line, character, result };
|
|
4476
4929
|
return text(formatPrepareRenameResult(result), details);
|
|
4477
4930
|
} catch (error) {
|
|
@@ -4492,7 +4945,7 @@ async function executeLspRename(params, signal) {
|
|
|
4492
4945
|
const character = requireNumber(params, "character");
|
|
4493
4946
|
const newName = requireString(params, "newName");
|
|
4494
4947
|
try {
|
|
4495
|
-
const result = await withLspClient(filePath, async (client) => client.rename(
|
|
4948
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.rename(resolvedFilePath, line, character, newName, signal), "rename", clientOptions(signal));
|
|
4496
4949
|
const details = { filePath, line, character, newName, apply: result.apply, edit: result.edit };
|
|
4497
4950
|
return text(formatApplyResult(result.apply), details, !result.apply.success);
|
|
4498
4951
|
} catch (error) {
|
|
@@ -4572,7 +5025,7 @@ async function executeLspSymbols(params, signal) {
|
|
|
4572
5025
|
const symbols2 = await withLspClient(filePath, async (client) => client.workspaceSymbols(query, signal), "workspaceSymbols", clientOptions(signal));
|
|
4573
5026
|
return formatSymbolsResult(filePath, scope, symbols2, limit, query);
|
|
4574
5027
|
}
|
|
4575
|
-
const symbols = await withLspClient(filePath, async (client) => client.documentSymbols(
|
|
5028
|
+
const symbols = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.documentSymbols(resolvedFilePath, signal), "documentSymbols", clientOptions(signal));
|
|
4576
5029
|
return formatSymbolsResult(filePath, scope, symbols, limit);
|
|
4577
5030
|
} catch (error) {
|
|
4578
5031
|
const query = optionalString(params, "query");
|
|
@@ -4708,6 +5161,16 @@ var LSP_MCP_TOOLS = [
|
|
|
4708
5161
|
}, ["filePath", "line", "character", "newName"]),
|
|
4709
5162
|
execute: executeLspRename
|
|
4710
5163
|
},
|
|
5164
|
+
{
|
|
5165
|
+
name: "format",
|
|
5166
|
+
aliases: ["lsp_format"],
|
|
5167
|
+
title: "LSP Format",
|
|
5168
|
+
description: "Format a source file with its language server and write the returned edits to disk.",
|
|
5169
|
+
inputSchema: objectSchema({
|
|
5170
|
+
filePath: { type: "string", description: "Source file path to format." }
|
|
5171
|
+
}, ["filePath"]),
|
|
5172
|
+
execute: executeLspFormat
|
|
5173
|
+
},
|
|
4711
5174
|
{
|
|
4712
5175
|
name: "install_decision",
|
|
4713
5176
|
aliases: ["lsp_install_decision"],
|
|
@@ -4741,16 +5204,17 @@ function coerceToolArguments(value) {
|
|
|
4741
5204
|
return isRecord7(value) ? value : {};
|
|
4742
5205
|
}
|
|
4743
5206
|
export {
|
|
4744
|
-
|
|
4745
|
-
executeLspTool,
|
|
4746
|
-
executeLspSymbols,
|
|
4747
|
-
executeLspStatus,
|
|
4748
|
-
executeLspRename,
|
|
4749
|
-
executeLspPrepareRename,
|
|
4750
|
-
executeLspInstallDecision,
|
|
4751
|
-
executeLspGotoDefinition,
|
|
4752
|
-
executeLspFindReferences,
|
|
4753
|
-
executeLspDiagnostics,
|
|
5207
|
+
LSP_MCP_TOOLS,
|
|
4754
5208
|
coerceToolArguments,
|
|
4755
|
-
|
|
5209
|
+
executeLspDiagnostics,
|
|
5210
|
+
executeLspFindReferences,
|
|
5211
|
+
executeLspFormat,
|
|
5212
|
+
executeLspGotoDefinition,
|
|
5213
|
+
executeLspInstallDecision,
|
|
5214
|
+
executeLspPrepareRename,
|
|
5215
|
+
executeLspRename,
|
|
5216
|
+
executeLspStatus,
|
|
5217
|
+
executeLspSymbols,
|
|
5218
|
+
executeLspTool,
|
|
5219
|
+
isRecord7 as isRecord
|
|
4756
5220
|
};
|