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
|
@@ -17,6 +17,13 @@ import { pathToFileURL as pathToFileURL3 } from "node:url";
|
|
|
17
17
|
// ../lsp-core/src/lsp/connection.ts
|
|
18
18
|
import { pathToFileURL } from "node:url";
|
|
19
19
|
|
|
20
|
+
// ../lsp-core/src/lsp/timer-provider.ts
|
|
21
|
+
var realTimerProvider = {
|
|
22
|
+
now: () => Date.now(),
|
|
23
|
+
setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
|
|
24
|
+
clearTimeout: (handle) => clearTimeout(handle)
|
|
25
|
+
};
|
|
26
|
+
|
|
20
27
|
// ../lsp-core/src/lsp/constants.ts
|
|
21
28
|
var DEFAULT_MAX_REFERENCES = 200;
|
|
22
29
|
var DEFAULT_MAX_SYMBOLS = 200;
|
|
@@ -25,28 +32,24 @@ var DEFAULT_MAX_DIRECTORY_FILES = 50;
|
|
|
25
32
|
var REQUEST_TIMEOUT_MS = 15000;
|
|
26
33
|
var INIT_TIMEOUT_MS = 60000;
|
|
27
34
|
var IDLE_TIMEOUT_MS = 5 * 60000;
|
|
35
|
+
var MAX_RESIDENT_CLIENTS = 6;
|
|
28
36
|
var REAPER_INTERVAL_MS = 60000;
|
|
29
37
|
var STOP_HARD_KILL_TIMEOUT_MS = 5000;
|
|
30
38
|
var STOP_SIGKILL_GRACE_MS = 1000;
|
|
39
|
+
var CLIENT_RESPAWN_RETRY_LIMIT = 2;
|
|
40
|
+
var CLIENT_RESPAWN_COOLDOWN_MS = 60000;
|
|
31
41
|
|
|
32
42
|
// ../lsp-core/src/lsp/errors.ts
|
|
33
43
|
class LspConnectionClosedError extends Error {
|
|
34
|
-
serverId;
|
|
35
|
-
root;
|
|
36
|
-
name = "LspConnectionClosedError";
|
|
37
44
|
constructor(serverId, root, message) {
|
|
38
45
|
super(message ?? `LSP connection closed for ${serverId} at ${root}`);
|
|
39
46
|
this.serverId = serverId;
|
|
40
47
|
this.root = root;
|
|
48
|
+
this.name = "LspConnectionClosedError";
|
|
41
49
|
}
|
|
42
50
|
}
|
|
43
51
|
|
|
44
52
|
class LspProcessExitedError extends Error {
|
|
45
|
-
serverId;
|
|
46
|
-
root;
|
|
47
|
-
exitCode;
|
|
48
|
-
stderrTail;
|
|
49
|
-
name = "LspProcessExitedError";
|
|
50
53
|
constructor(serverId, root, exitCode, stderrTail) {
|
|
51
54
|
const stderrSuffix = stderrTail ? `
|
|
52
55
|
stderr tail: ${stderrTail}` : "";
|
|
@@ -55,46 +58,59 @@ stderr tail: ${stderrTail}` : "";
|
|
|
55
58
|
this.root = root;
|
|
56
59
|
this.exitCode = exitCode;
|
|
57
60
|
this.stderrTail = stderrTail;
|
|
61
|
+
this.name = "LspProcessExitedError";
|
|
58
62
|
}
|
|
59
63
|
}
|
|
60
64
|
|
|
61
65
|
class LspRequestTimeoutError extends Error {
|
|
62
|
-
method;
|
|
63
|
-
stderrTail;
|
|
64
|
-
name = "LspRequestTimeoutError";
|
|
65
66
|
constructor(method, stderrTail) {
|
|
66
67
|
const stderrSuffix = stderrTail ? `
|
|
67
68
|
recent stderr: ${stderrTail}` : "";
|
|
68
69
|
super(`LSP request timeout (method: ${method})${stderrSuffix}`);
|
|
69
70
|
this.method = method;
|
|
70
71
|
this.stderrTail = stderrTail;
|
|
72
|
+
this.name = "LspRequestTimeoutError";
|
|
71
73
|
}
|
|
72
74
|
}
|
|
73
75
|
|
|
74
76
|
class LspInvalidPathError extends Error {
|
|
75
|
-
|
|
77
|
+
constructor() {
|
|
78
|
+
super(...arguments);
|
|
79
|
+
this.name = "LspInvalidPathError";
|
|
80
|
+
}
|
|
76
81
|
}
|
|
77
82
|
|
|
78
83
|
class LspServerLookupError extends Error {
|
|
79
|
-
lookup;
|
|
80
|
-
name = "LspServerLookupError";
|
|
81
84
|
constructor(message, lookup) {
|
|
82
85
|
super(message);
|
|
83
86
|
this.lookup = lookup;
|
|
87
|
+
this.name = "LspServerLookupError";
|
|
84
88
|
}
|
|
85
89
|
}
|
|
86
90
|
|
|
87
91
|
class LspServerInitializingError extends Error {
|
|
88
|
-
originalError;
|
|
89
|
-
name = "LspServerInitializingError";
|
|
90
92
|
constructor(originalError) {
|
|
91
93
|
super(`LSP server is still initializing. Please retry in a few seconds. Original error: ${originalError.message}`);
|
|
92
94
|
this.originalError = originalError;
|
|
95
|
+
this.name = "LspServerInitializingError";
|
|
93
96
|
}
|
|
94
97
|
}
|
|
95
98
|
|
|
96
99
|
class LspProcessSpawnError extends Error {
|
|
97
|
-
|
|
100
|
+
constructor() {
|
|
101
|
+
super(...arguments);
|
|
102
|
+
this.name = "LspProcessSpawnError";
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
class LspClientRespawnBudgetExceededError extends Error {
|
|
107
|
+
constructor(serverId, root, retryLimit) {
|
|
108
|
+
super(`LSP server ${serverId} at ${root} failed to stay alive; respawn budget exhausted ` + `(${retryLimit} consecutive dead generations). Retrying after the cooldown may succeed.`);
|
|
109
|
+
this.serverId = serverId;
|
|
110
|
+
this.root = root;
|
|
111
|
+
this.retryLimit = retryLimit;
|
|
112
|
+
this.name = "LspClientRespawnBudgetExceededError";
|
|
113
|
+
}
|
|
98
114
|
}
|
|
99
115
|
function isLspDeadConnectionError(err) {
|
|
100
116
|
return err instanceof LspConnectionClosedError || err instanceof LspProcessExitedError;
|
|
@@ -110,20 +126,31 @@ var METHOD_NOT_FOUND = -32601;
|
|
|
110
126
|
var INTERNAL_ERROR = -32603;
|
|
111
127
|
|
|
112
128
|
class JsonRpcConnection {
|
|
113
|
-
reader;
|
|
114
|
-
writer;
|
|
115
|
-
pendingRequests = new Map;
|
|
116
|
-
notificationHandlers = new Map;
|
|
117
|
-
requestHandlers = new Map;
|
|
118
|
-
closeHandlers = [];
|
|
119
|
-
errorHandlers = [];
|
|
120
|
-
inputBuffer = Buffer.alloc(0);
|
|
121
|
-
nextRequestId = 1;
|
|
122
|
-
listening = false;
|
|
123
|
-
disposed = false;
|
|
124
129
|
constructor(reader, writer) {
|
|
125
130
|
this.reader = reader;
|
|
126
131
|
this.writer = writer;
|
|
132
|
+
this.pendingRequests = new Map;
|
|
133
|
+
this.notificationHandlers = new Map;
|
|
134
|
+
this.requestHandlers = new Map;
|
|
135
|
+
this.closeHandlers = [];
|
|
136
|
+
this.errorHandlers = [];
|
|
137
|
+
this.inputBuffer = Buffer.alloc(0);
|
|
138
|
+
this.nextRequestId = 1;
|
|
139
|
+
this.listening = false;
|
|
140
|
+
this.disposed = false;
|
|
141
|
+
this.handleData = (chunk) => {
|
|
142
|
+
const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
|
|
143
|
+
this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
|
|
144
|
+
this.drainInputBuffer();
|
|
145
|
+
};
|
|
146
|
+
this.handleClose = () => {
|
|
147
|
+
for (const handler of this.closeHandlers) {
|
|
148
|
+
handler();
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
this.handleStreamError = (error) => {
|
|
152
|
+
this.emitError(error);
|
|
153
|
+
};
|
|
127
154
|
}
|
|
128
155
|
listen() {
|
|
129
156
|
if (this.listening)
|
|
@@ -244,19 +271,6 @@ class JsonRpcConnection {
|
|
|
244
271
|
this.notificationHandlers.clear();
|
|
245
272
|
this.requestHandlers.clear();
|
|
246
273
|
}
|
|
247
|
-
handleData = (chunk) => {
|
|
248
|
-
const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
|
|
249
|
-
this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
|
|
250
|
-
this.drainInputBuffer();
|
|
251
|
-
};
|
|
252
|
-
handleClose = () => {
|
|
253
|
-
for (const handler of this.closeHandlers) {
|
|
254
|
-
handler();
|
|
255
|
-
}
|
|
256
|
-
};
|
|
257
|
-
handleStreamError = (error) => {
|
|
258
|
-
this.emitError(error);
|
|
259
|
-
};
|
|
260
274
|
drainInputBuffer() {
|
|
261
275
|
while (true) {
|
|
262
276
|
const headerEnd = this.inputBuffer.indexOf(HEADER_SEPARATOR);
|
|
@@ -604,33 +618,29 @@ function isPosition(value) {
|
|
|
604
618
|
|
|
605
619
|
// ../lsp-core/src/lsp/transport.ts
|
|
606
620
|
class LspClientNotStartedError extends Error {
|
|
607
|
-
serverId;
|
|
608
|
-
root;
|
|
609
|
-
name = "LspClientNotStartedError";
|
|
610
621
|
constructor(serverId, root) {
|
|
611
622
|
super("LSP client not started");
|
|
612
623
|
this.serverId = serverId;
|
|
613
624
|
this.root = root;
|
|
625
|
+
this.name = "LspClientNotStartedError";
|
|
614
626
|
}
|
|
615
627
|
}
|
|
616
628
|
|
|
617
629
|
class LspClientTransport {
|
|
618
|
-
root;
|
|
619
|
-
server;
|
|
620
|
-
proc = null;
|
|
621
|
-
connection = null;
|
|
622
|
-
stderrBuffer = [];
|
|
623
|
-
processExited = false;
|
|
624
|
-
diagnosticsStore = new Map;
|
|
625
|
-
requestTimeoutMs;
|
|
626
|
-
initializeTimeoutMs;
|
|
627
|
-
workspaceApplyEditHandler = null;
|
|
628
|
-
diagnosticPullSupported = false;
|
|
629
630
|
constructor(root, server, timeouts = {}) {
|
|
630
631
|
this.root = root;
|
|
631
632
|
this.server = server;
|
|
633
|
+
this.proc = null;
|
|
634
|
+
this.connection = null;
|
|
635
|
+
this.stderrBuffer = [];
|
|
636
|
+
this.processExited = false;
|
|
637
|
+
this.diagnosticsStore = new Map;
|
|
638
|
+
this.workspaceApplyEditHandler = null;
|
|
639
|
+
this.diagnosticPullSupported = false;
|
|
640
|
+
this.documentFormattingSupported = false;
|
|
632
641
|
this.requestTimeoutMs = timeouts.requestTimeoutMs ?? REQUEST_TIMEOUT_MS;
|
|
633
642
|
this.initializeTimeoutMs = timeouts.initializeTimeoutMs ?? INIT_TIMEOUT_MS;
|
|
643
|
+
this.timerProvider = timeouts.timerProvider ?? realTimerProvider;
|
|
634
644
|
}
|
|
635
645
|
pid() {
|
|
636
646
|
return this.proc?.pid;
|
|
@@ -650,6 +660,12 @@ class LspClientTransport {
|
|
|
650
660
|
isDiagnosticPullSupported() {
|
|
651
661
|
return this.diagnosticPullSupported;
|
|
652
662
|
}
|
|
663
|
+
setDocumentFormattingSupported(supported) {
|
|
664
|
+
this.documentFormattingSupported = supported;
|
|
665
|
+
}
|
|
666
|
+
isDocumentFormattingSupported() {
|
|
667
|
+
return this.documentFormattingSupported;
|
|
668
|
+
}
|
|
653
669
|
handlePublishDiagnostics(params) {
|
|
654
670
|
this.diagnosticsStore.set(params.uri, [...params.diagnostics]);
|
|
655
671
|
}
|
|
@@ -725,7 +741,7 @@ class LspClientTransport {
|
|
|
725
741
|
const options = args[1];
|
|
726
742
|
const timeoutMs = options?.timeoutMs ?? this.requestTimeoutMs;
|
|
727
743
|
const timeoutController = new AbortController;
|
|
728
|
-
const timeoutHandle = setTimeout(() => {
|
|
744
|
+
const timeoutHandle = this.timerProvider.setTimeout(() => {
|
|
729
745
|
const stderrTail = this.stderrBuffer.slice(-5).join(`
|
|
730
746
|
`);
|
|
731
747
|
timeoutController.abort(new LspRequestTimeoutError(method, stderrTail || undefined));
|
|
@@ -744,7 +760,7 @@ class LspClientTransport {
|
|
|
744
760
|
}
|
|
745
761
|
throw error;
|
|
746
762
|
} finally {
|
|
747
|
-
clearTimeout(timeoutHandle);
|
|
763
|
+
this.timerProvider.clearTimeout(timeoutHandle);
|
|
748
764
|
combinedSignal.dispose();
|
|
749
765
|
}
|
|
750
766
|
}
|
|
@@ -863,6 +879,14 @@ function supportsDiagnosticPull(capabilities) {
|
|
|
863
879
|
return false;
|
|
864
880
|
return Object.hasOwn(capabilities, "diagnosticProvider");
|
|
865
881
|
}
|
|
882
|
+
function supportsDocumentFormatting(capabilities) {
|
|
883
|
+
if (capabilities === undefined)
|
|
884
|
+
return false;
|
|
885
|
+
const provider = capabilities.documentFormattingProvider;
|
|
886
|
+
if (provider === undefined || provider === null || provider === false)
|
|
887
|
+
return false;
|
|
888
|
+
return provider === true || typeof provider === "object";
|
|
889
|
+
}
|
|
866
890
|
|
|
867
891
|
class LspClientConnection extends LspClientTransport {
|
|
868
892
|
async initialize() {
|
|
@@ -879,6 +903,7 @@ class LspClientConnection extends LspClientTransport {
|
|
|
879
903
|
references: {},
|
|
880
904
|
documentSymbol: { hierarchicalDocumentSymbolSupport: true },
|
|
881
905
|
publishDiagnostics: {},
|
|
906
|
+
formatting: { dynamicRegistration: false },
|
|
882
907
|
rename: {
|
|
883
908
|
prepareSupport: true,
|
|
884
909
|
prepareSupportDefaultBehavior: 1
|
|
@@ -920,6 +945,7 @@ class LspClientConnection extends LspClientTransport {
|
|
|
920
945
|
initializationOptions: this.server.initialization
|
|
921
946
|
}, { timeoutMs: this.initializeTimeoutMs });
|
|
922
947
|
this.setDiagnosticPullSupported(supportsDiagnosticPull(result?.capabilities));
|
|
948
|
+
this.setDocumentFormattingSupported(supportsDocumentFormatting(result?.capabilities));
|
|
923
949
|
await this.sendNotification("initialized", {});
|
|
924
950
|
await this.sendNotification("workspace/didChangeConfiguration", {
|
|
925
951
|
settings: { json: { validate: { enable: true } } }
|
|
@@ -1125,6 +1151,17 @@ function canonicalPath(filePath) {
|
|
|
1125
1151
|
return absolute;
|
|
1126
1152
|
}
|
|
1127
1153
|
}
|
|
1154
|
+
function normalizeDocumentUri(uri) {
|
|
1155
|
+
let decoded = uri;
|
|
1156
|
+
try {
|
|
1157
|
+
decoded = decodeURIComponent(uri);
|
|
1158
|
+
} catch {
|
|
1159
|
+
decoded = uri;
|
|
1160
|
+
}
|
|
1161
|
+
if (process.platform !== "win32")
|
|
1162
|
+
return decoded;
|
|
1163
|
+
return decoded.replace(/^(file:\/\/\/)([a-z]):/, (_match, prefix, drive) => `${prefix}${drive.toUpperCase()}:`);
|
|
1164
|
+
}
|
|
1128
1165
|
function isSameOrDescendant(candidate, parent) {
|
|
1129
1166
|
const suffix = relative(parent, candidate);
|
|
1130
1167
|
return suffix === "" || !suffix.startsWith("..") && suffix !== "..";
|
|
@@ -1135,17 +1172,18 @@ function movedPath(candidate, oldPath, newPath) {
|
|
|
1135
1172
|
}
|
|
1136
1173
|
|
|
1137
1174
|
class WorkspaceDocumentState {
|
|
1138
|
-
sendNotification;
|
|
1139
|
-
clearDiagnostics;
|
|
1140
|
-
openDocuments = new Map;
|
|
1141
|
-
openByUri = new Map;
|
|
1142
|
-
openPromises = new Map;
|
|
1143
|
-
now;
|
|
1144
|
-
versionlessPublishQuiescenceMs;
|
|
1145
1175
|
constructor(sendNotification, clearDiagnostics, options = {}) {
|
|
1146
1176
|
this.sendNotification = sendNotification;
|
|
1147
1177
|
this.clearDiagnostics = clearDiagnostics;
|
|
1148
|
-
this.
|
|
1178
|
+
this.openDocuments = new Map;
|
|
1179
|
+
this.openByUri = new Map;
|
|
1180
|
+
this.openPromises = new Map;
|
|
1181
|
+
this.timerProvider = options.timerProvider ?? {
|
|
1182
|
+
now: options.now ?? (() => Date.now()),
|
|
1183
|
+
setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
|
|
1184
|
+
clearTimeout: (handle) => clearTimeout(handle)
|
|
1185
|
+
};
|
|
1186
|
+
this.now = () => this.timerProvider.now();
|
|
1149
1187
|
this.versionlessPublishQuiescenceMs = options.versionlessPublishQuiescenceMs ?? DEFAULT_VERSIONLESS_PUBLISH_QUIESCENCE_MS;
|
|
1150
1188
|
}
|
|
1151
1189
|
async openFile(filePath) {
|
|
@@ -1167,7 +1205,7 @@ class WorkspaceDocumentState {
|
|
|
1167
1205
|
return this.openDocuments.get(canonicalPath(filePath))?.version;
|
|
1168
1206
|
}
|
|
1169
1207
|
getStoredDiagnostics(uri) {
|
|
1170
|
-
const state = this.openByUri.get(uri);
|
|
1208
|
+
const state = this.openByUri.get(normalizeDocumentUri(uri));
|
|
1171
1209
|
if (!state)
|
|
1172
1210
|
return [];
|
|
1173
1211
|
return state.lastPublish?.diagnostics ?? state.pullCache?.diagnostics ?? [];
|
|
@@ -1189,13 +1227,13 @@ class WorkspaceDocumentState {
|
|
|
1189
1227
|
return state !== undefined && state.uri === snapshot.uri && state.version === snapshot.version && state.generation === snapshot.documentGeneration;
|
|
1190
1228
|
}
|
|
1191
1229
|
getPullCache(snapshot) {
|
|
1192
|
-
const state = this.openByUri.get(snapshot.uri);
|
|
1230
|
+
const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
|
|
1193
1231
|
if (!state?.pullCache || state.pullCache.documentVersion !== snapshot.version)
|
|
1194
1232
|
return null;
|
|
1195
1233
|
return state.pullCache;
|
|
1196
1234
|
}
|
|
1197
1235
|
recordPullDiagnostics(snapshot, report) {
|
|
1198
|
-
const state = this.openByUri.get(snapshot.uri);
|
|
1236
|
+
const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
|
|
1199
1237
|
if (!state)
|
|
1200
1238
|
return;
|
|
1201
1239
|
state.pullCache = {
|
|
@@ -1205,7 +1243,7 @@ class WorkspaceDocumentState {
|
|
|
1205
1243
|
};
|
|
1206
1244
|
}
|
|
1207
1245
|
recordPublishedDiagnostics(params) {
|
|
1208
|
-
const state = this.openByUri.get(params.uri);
|
|
1246
|
+
const state = this.openByUri.get(normalizeDocumentUri(params.uri));
|
|
1209
1247
|
if (!state)
|
|
1210
1248
|
return;
|
|
1211
1249
|
state.publishGeneration += 1;
|
|
@@ -1219,7 +1257,7 @@ class WorkspaceDocumentState {
|
|
|
1219
1257
|
this.notifyWaiters(state);
|
|
1220
1258
|
}
|
|
1221
1259
|
resolvePushDiagnostics(snapshot) {
|
|
1222
|
-
const state = this.openByUri.get(snapshot.uri);
|
|
1260
|
+
const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
|
|
1223
1261
|
if (!state?.lastPublish)
|
|
1224
1262
|
return { status: "missing" };
|
|
1225
1263
|
const publish = state.lastPublish;
|
|
@@ -1233,7 +1271,7 @@ class WorkspaceDocumentState {
|
|
|
1233
1271
|
return waitMs === 0 ? { status: "ready", diagnostics: publish.diagnostics } : { status: "wait", waitMs };
|
|
1234
1272
|
}
|
|
1235
1273
|
waitForDiagnosticsActivity(snapshot, timeoutMs) {
|
|
1236
|
-
const state = this.openByUri.get(snapshot.uri);
|
|
1274
|
+
const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
|
|
1237
1275
|
if (!state || timeoutMs <= 0)
|
|
1238
1276
|
return Promise.resolve();
|
|
1239
1277
|
return new Promise((resolveActivity) => {
|
|
@@ -1242,11 +1280,11 @@ class WorkspaceDocumentState {
|
|
|
1242
1280
|
if (settled)
|
|
1243
1281
|
return;
|
|
1244
1282
|
settled = true;
|
|
1245
|
-
clearTimeout(timer);
|
|
1283
|
+
this.timerProvider.clearTimeout(timer);
|
|
1246
1284
|
state.waiters.delete(finish);
|
|
1247
1285
|
resolveActivity();
|
|
1248
1286
|
};
|
|
1249
|
-
const timer = setTimeout(finish, timeoutMs);
|
|
1287
|
+
const timer = this.timerProvider.setTimeout(finish, timeoutMs);
|
|
1250
1288
|
if (typeof timer.unref === "function")
|
|
1251
1289
|
timer.unref();
|
|
1252
1290
|
state.waiters.add(finish);
|
|
@@ -1354,7 +1392,7 @@ class WorkspaceDocumentState {
|
|
|
1354
1392
|
waiters: new Set
|
|
1355
1393
|
};
|
|
1356
1394
|
this.openDocuments.set(path, state);
|
|
1357
|
-
this.openByUri.set(state.uri, state);
|
|
1395
|
+
this.openByUri.set(normalizeDocumentUri(state.uri), state);
|
|
1358
1396
|
this.notifyWaiters(state);
|
|
1359
1397
|
await this.sendNotification("textDocument/didOpen", {
|
|
1360
1398
|
textDocument: { uri: state.uri, languageId: state.languageId, version: state.version, text }
|
|
@@ -1379,7 +1417,7 @@ class WorkspaceDocumentState {
|
|
|
1379
1417
|
}
|
|
1380
1418
|
async closeDocument(state) {
|
|
1381
1419
|
this.openDocuments.delete(state.path);
|
|
1382
|
-
this.openByUri.delete(state.uri);
|
|
1420
|
+
this.openByUri.delete(normalizeDocumentUri(state.uri));
|
|
1383
1421
|
this.clearDiagnostics(state.uri);
|
|
1384
1422
|
this.notifyWaiters(state);
|
|
1385
1423
|
await this.sendNotification("textDocument/didClose", { textDocument: { uri: state.uri } });
|
|
@@ -1408,13 +1446,11 @@ import { dirname, isAbsolute, relative as relative2, resolve as resolve2 } from
|
|
|
1408
1446
|
import { fileURLToPath } from "node:url";
|
|
1409
1447
|
|
|
1410
1448
|
class WorkspaceEditPathError extends Error {
|
|
1411
|
-
path;
|
|
1412
|
-
detail;
|
|
1413
|
-
name = "WorkspaceEditPathError";
|
|
1414
1449
|
constructor(path, detail) {
|
|
1415
1450
|
super(`${detail}: ${path}`);
|
|
1416
1451
|
this.path = path;
|
|
1417
1452
|
this.detail = detail;
|
|
1453
|
+
this.name = "WorkspaceEditPathError";
|
|
1418
1454
|
}
|
|
1419
1455
|
}
|
|
1420
1456
|
function isPathInsideWorkspace(filePath, workspaceRoot) {
|
|
@@ -1706,13 +1742,11 @@ function canonicalFingerprint(operations) {
|
|
|
1706
1742
|
|
|
1707
1743
|
// ../lsp-core/src/lsp/workspace-edit-types.ts
|
|
1708
1744
|
class WorkspaceEditValidationError extends Error {
|
|
1709
|
-
changeIndex;
|
|
1710
|
-
detail;
|
|
1711
|
-
name = "WorkspaceEditValidationError";
|
|
1712
1745
|
constructor(changeIndex, detail) {
|
|
1713
1746
|
super(`change ${changeIndex}: ${detail}`);
|
|
1714
1747
|
this.changeIndex = changeIndex;
|
|
1715
1748
|
this.detail = detail;
|
|
1749
|
+
this.name = "WorkspaceEditValidationError";
|
|
1716
1750
|
}
|
|
1717
1751
|
}
|
|
1718
1752
|
|
|
@@ -2210,10 +2244,9 @@ function simulateDelete(operation, virtual) {
|
|
|
2210
2244
|
import { existsSync as existsSync4, lstatSync as lstatSync3, readdirSync as readdirSync2 } from "node:fs";
|
|
2211
2245
|
import { dirname as dirname3, resolve as resolve4 } from "node:path";
|
|
2212
2246
|
class WorkspaceSnapshotBuilder {
|
|
2213
|
-
workspaceRoot;
|
|
2214
|
-
snapshots = new Map;
|
|
2215
2247
|
constructor(workspaceRoot) {
|
|
2216
2248
|
this.workspaceRoot = workspaceRoot;
|
|
2249
|
+
this.snapshots = new Map;
|
|
2217
2250
|
}
|
|
2218
2251
|
build(operations) {
|
|
2219
2252
|
this.add(this.workspaceRoot, false);
|
|
@@ -2257,8 +2290,10 @@ function snapshotOperations(operations, workspaceRoot) {
|
|
|
2257
2290
|
|
|
2258
2291
|
// ../lsp-core/src/lsp/workspace-edit-plan.ts
|
|
2259
2292
|
class PlanPathIndex {
|
|
2260
|
-
|
|
2261
|
-
|
|
2293
|
+
constructor() {
|
|
2294
|
+
this.firstChangeByPath = new Map;
|
|
2295
|
+
this.reportedPathByCanonical = new Map;
|
|
2296
|
+
}
|
|
2262
2297
|
build(operations) {
|
|
2263
2298
|
for (const operation of operations) {
|
|
2264
2299
|
switch (operation.kind) {
|
|
@@ -2347,14 +2382,11 @@ function isRecord3(value) {
|
|
|
2347
2382
|
}
|
|
2348
2383
|
|
|
2349
2384
|
class WorkspaceMutationController {
|
|
2350
|
-
workspaceRoot;
|
|
2351
|
-
documents;
|
|
2352
|
-
activeLease = null;
|
|
2353
|
-
nextLeaseId = 1;
|
|
2354
|
-
io;
|
|
2355
2385
|
constructor(workspaceRoot, documents) {
|
|
2356
2386
|
this.workspaceRoot = workspaceRoot;
|
|
2357
2387
|
this.documents = documents;
|
|
2388
|
+
this.activeLease = null;
|
|
2389
|
+
this.nextLeaseId = 1;
|
|
2358
2390
|
}
|
|
2359
2391
|
setIo(io) {
|
|
2360
2392
|
this.io = io;
|
|
@@ -2467,14 +2499,12 @@ var DIAGNOSTICS_FRESHNESS_TIMEOUT_MS = 3000;
|
|
|
2467
2499
|
var VERSIONLESS_PUBLISH_QUIESCENCE_MS = 250;
|
|
2468
2500
|
|
|
2469
2501
|
class LspClient extends LspClientConnection {
|
|
2470
|
-
diagnosticPullErrors = [];
|
|
2471
|
-
documents;
|
|
2472
|
-
workspaceMutations;
|
|
2473
|
-
diagnosticsFreshnessTimeoutMs;
|
|
2474
2502
|
constructor(root, server, options = {}) {
|
|
2475
2503
|
super(root, server, options);
|
|
2504
|
+
this.diagnosticPullErrors = [];
|
|
2476
2505
|
this.diagnosticsFreshnessTimeoutMs = options.diagnosticsFreshnessTimeoutMs ?? DIAGNOSTICS_FRESHNESS_TIMEOUT_MS;
|
|
2477
2506
|
this.documents = new WorkspaceDocumentState((method, params) => this.sendNotification(method, params), (uri) => this.diagnosticsStore.delete(uri), {
|
|
2507
|
+
timerProvider: this.timerProvider,
|
|
2478
2508
|
versionlessPublishQuiescenceMs: options.versionlessPublishQuiescenceMs ?? VERSIONLESS_PUBLISH_QUIESCENCE_MS
|
|
2479
2509
|
});
|
|
2480
2510
|
this.workspaceMutations = new WorkspaceMutationController(root, this.documents);
|
|
@@ -2527,6 +2557,18 @@ class LspClient extends LspClientConnection {
|
|
|
2527
2557
|
textDocument: { uri: pathToFileURL3(absPath).href }
|
|
2528
2558
|
}, options);
|
|
2529
2559
|
}
|
|
2560
|
+
async formatDocument(filePath, options, signal) {
|
|
2561
|
+
if (!this.isDocumentFormattingSupported())
|
|
2562
|
+
return null;
|
|
2563
|
+
const absPath = this.resolveWorkspacePath(filePath);
|
|
2564
|
+
await this.openFile(absPath);
|
|
2565
|
+
const requestOptions = signal === undefined ? {} : { signal };
|
|
2566
|
+
const edits = await this.sendRequest("textDocument/formatting", {
|
|
2567
|
+
textDocument: { uri: pathToFileURL3(absPath).href },
|
|
2568
|
+
options
|
|
2569
|
+
}, requestOptions);
|
|
2570
|
+
return edits ?? [];
|
|
2571
|
+
}
|
|
2530
2572
|
async workspaceSymbols(query, signal) {
|
|
2531
2573
|
const options = signal === undefined ? {} : { signal };
|
|
2532
2574
|
return this.sendRequest("workspace/symbol", { query }, options);
|
|
@@ -2566,7 +2608,7 @@ class LspClient extends LspClientConnection {
|
|
|
2566
2608
|
const absPath = this.resolveWorkspacePath(filePath);
|
|
2567
2609
|
const uri = pathToFileURL3(absPath).href;
|
|
2568
2610
|
await this.openFile(absPath);
|
|
2569
|
-
const deadlineAt =
|
|
2611
|
+
const deadlineAt = this.timerProvider.now() + this.diagnosticsFreshnessTimeoutMs;
|
|
2570
2612
|
for (;; ) {
|
|
2571
2613
|
signal?.throwIfAborted();
|
|
2572
2614
|
const snapshot = this.documents.captureDiagnosticSnapshot(absPath);
|
|
@@ -2579,7 +2621,7 @@ class LspClient extends LspClientConnection {
|
|
|
2579
2621
|
if (!pushFallbackOnly) {
|
|
2580
2622
|
const cached = this.documents.getPullCache(snapshot);
|
|
2581
2623
|
try {
|
|
2582
|
-
const remainingMs2 = deadlineAt -
|
|
2624
|
+
const remainingMs2 = deadlineAt - this.timerProvider.now();
|
|
2583
2625
|
if (remainingMs2 <= 0)
|
|
2584
2626
|
return this.freshnessTimeout(absPath);
|
|
2585
2627
|
const result = await this.sendRequest("textDocument/diagnostic", {
|
|
@@ -2614,7 +2656,7 @@ class LspClient extends LspClientConnection {
|
|
|
2614
2656
|
}
|
|
2615
2657
|
if (!pushFallbackOnly)
|
|
2616
2658
|
continue;
|
|
2617
|
-
const remainingMs = deadlineAt -
|
|
2659
|
+
const remainingMs = deadlineAt - this.timerProvider.now();
|
|
2618
2660
|
if (remainingMs <= 0) {
|
|
2619
2661
|
if (!this.isDiagnosticPullSupported() && snapshot.publishGeneration === 0) {
|
|
2620
2662
|
const cached = this.documents.getPullCache(snapshot);
|
|
@@ -2772,18 +2814,16 @@ function awaitWithSignal(promise, signal) {
|
|
|
2772
2814
|
}
|
|
2773
2815
|
|
|
2774
2816
|
class LspManager {
|
|
2775
|
-
clients = new Map;
|
|
2776
|
-
reaperHandle = null;
|
|
2777
|
-
signalDisposer = null;
|
|
2778
|
-
disposed = false;
|
|
2779
|
-
idleTimeoutMs;
|
|
2780
|
-
initTimeoutMs;
|
|
2781
|
-
reaperIntervalMs;
|
|
2782
|
-
clientFactory;
|
|
2783
|
-
now;
|
|
2784
2817
|
constructor(options = {}) {
|
|
2818
|
+
this.clients = new Map;
|
|
2819
|
+
this.pendingStops = new Map;
|
|
2820
|
+
this.respawnBudgets = new Map;
|
|
2821
|
+
this.reaperHandle = null;
|
|
2822
|
+
this.signalDisposer = null;
|
|
2823
|
+
this.disposed = false;
|
|
2785
2824
|
this.idleTimeoutMs = options.idleTimeoutMs ?? IDLE_TIMEOUT_MS;
|
|
2786
2825
|
this.initTimeoutMs = options.initTimeoutMs ?? INIT_TIMEOUT_MS;
|
|
2826
|
+
this.maxResidentClients = options.maxResidentClients ?? MAX_RESIDENT_CLIENTS;
|
|
2787
2827
|
this.reaperIntervalMs = options.reaperIntervalMs ?? REAPER_INTERVAL_MS;
|
|
2788
2828
|
this.clientFactory = options.clientFactory ?? ((root, server) => new LspClient(root, server));
|
|
2789
2829
|
this.now = options.now ?? (() => Date.now());
|
|
@@ -2803,24 +2843,79 @@ class LspManager {
|
|
|
2803
2843
|
getKey(root, serverId) {
|
|
2804
2844
|
return `${root}::${serverId}`;
|
|
2805
2845
|
}
|
|
2846
|
+
tombstoneStop(key, client) {
|
|
2847
|
+
const stop = stopClientBestEffort(client);
|
|
2848
|
+
this.pendingStops.set(key, stop);
|
|
2849
|
+
stop.finally(() => {
|
|
2850
|
+
if (this.pendingStops.get(key) === stop) {
|
|
2851
|
+
this.pendingStops.delete(key);
|
|
2852
|
+
}
|
|
2853
|
+
});
|
|
2854
|
+
return stop;
|
|
2855
|
+
}
|
|
2856
|
+
recordDeadGeneration(key) {
|
|
2857
|
+
let budget = this.respawnBudgets.get(key);
|
|
2858
|
+
if (budget === undefined) {
|
|
2859
|
+
budget = { deadGenerations: 0, exhaustedAt: null };
|
|
2860
|
+
this.respawnBudgets.set(key, budget);
|
|
2861
|
+
}
|
|
2862
|
+
budget.deadGenerations += 1;
|
|
2863
|
+
}
|
|
2864
|
+
markHealthyGeneration(key) {
|
|
2865
|
+
this.respawnBudgets.delete(key);
|
|
2866
|
+
}
|
|
2867
|
+
ensureRespawnAllowed(key, root, serverId) {
|
|
2868
|
+
const budget = this.respawnBudgets.get(key);
|
|
2869
|
+
if (budget === undefined || budget.deadGenerations < CLIENT_RESPAWN_RETRY_LIMIT)
|
|
2870
|
+
return;
|
|
2871
|
+
if (budget.exhaustedAt === null) {
|
|
2872
|
+
budget.exhaustedAt = this.now();
|
|
2873
|
+
throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
|
|
2874
|
+
}
|
|
2875
|
+
if (this.now() - budget.exhaustedAt < CLIENT_RESPAWN_COOLDOWN_MS) {
|
|
2876
|
+
throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
|
|
2877
|
+
}
|
|
2878
|
+
budget.deadGenerations = 0;
|
|
2879
|
+
budget.exhaustedAt = null;
|
|
2880
|
+
}
|
|
2806
2881
|
reapStale() {
|
|
2807
2882
|
const t = this.now();
|
|
2808
2883
|
for (const [key, managed] of this.clients) {
|
|
2809
2884
|
if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
|
|
2810
|
-
stopClientBestEffort(managed.client);
|
|
2811
2885
|
this.clients.delete(key);
|
|
2886
|
+
this.tombstoneStop(key, managed.client);
|
|
2812
2887
|
continue;
|
|
2813
2888
|
}
|
|
2814
2889
|
if (!managed.isInitializing && managed.refCount === 0 && managed.pendingWaiters === 0 && t - managed.lastUsedAt > this.idleTimeoutMs) {
|
|
2815
|
-
stopClientBestEffort(managed.client);
|
|
2816
2890
|
this.clients.delete(key);
|
|
2891
|
+
this.tombstoneStop(key, managed.client);
|
|
2892
|
+
}
|
|
2893
|
+
}
|
|
2894
|
+
}
|
|
2895
|
+
evictForAdmission() {
|
|
2896
|
+
while (this.clients.size >= this.maxResidentClients) {
|
|
2897
|
+
const victim = this.leastRecentlyUsedIdleClient();
|
|
2898
|
+
if (!victim)
|
|
2899
|
+
return;
|
|
2900
|
+
this.clients.delete(victim.key);
|
|
2901
|
+
this.tombstoneStop(victim.key, victim.managed.client);
|
|
2902
|
+
}
|
|
2903
|
+
}
|
|
2904
|
+
leastRecentlyUsedIdleClient() {
|
|
2905
|
+
let candidate = null;
|
|
2906
|
+
for (const [key, managed] of this.clients) {
|
|
2907
|
+
if (managed.refCount > 0 || managed.pendingWaiters > 0 || managed.isInitializing)
|
|
2908
|
+
continue;
|
|
2909
|
+
if (candidate === null || managed.lastUsedAt < candidate.managed.lastUsedAt) {
|
|
2910
|
+
candidate = { key, managed };
|
|
2817
2911
|
}
|
|
2818
2912
|
}
|
|
2913
|
+
return candidate;
|
|
2819
2914
|
}
|
|
2820
2915
|
async tryDeleteIfOrphaned(key, managed) {
|
|
2821
2916
|
if (managed.refCount === 0 && managed.pendingWaiters === 0 && !managed.isInitializing && this.clients.get(key) === managed) {
|
|
2822
2917
|
this.clients.delete(key);
|
|
2823
|
-
await
|
|
2918
|
+
await this.tombstoneStop(key, managed.client);
|
|
2824
2919
|
}
|
|
2825
2920
|
}
|
|
2826
2921
|
async getClient(root, server, signal) {
|
|
@@ -2829,12 +2924,22 @@ class LspManager {
|
|
|
2829
2924
|
}
|
|
2830
2925
|
signal?.throwIfAborted();
|
|
2831
2926
|
const key = this.getKey(root, server.id);
|
|
2927
|
+
for (;; ) {
|
|
2928
|
+
const pendingStop = this.pendingStops.get(key);
|
|
2929
|
+
if (pendingStop === undefined)
|
|
2930
|
+
break;
|
|
2931
|
+
await awaitWithSignal(pendingStop, signal);
|
|
2932
|
+
signal?.throwIfAborted();
|
|
2933
|
+
}
|
|
2934
|
+
if (this.disposed) {
|
|
2935
|
+
throw new Error("LspManager has been disposed");
|
|
2936
|
+
}
|
|
2832
2937
|
let managed = this.clients.get(key);
|
|
2833
2938
|
if (managed) {
|
|
2834
2939
|
const t = this.now();
|
|
2835
2940
|
if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
|
|
2836
|
-
await stopClientBestEffort(managed.client);
|
|
2837
2941
|
this.clients.delete(key);
|
|
2942
|
+
await this.tombstoneStop(key, managed.client);
|
|
2838
2943
|
managed = undefined;
|
|
2839
2944
|
}
|
|
2840
2945
|
}
|
|
@@ -2855,14 +2960,20 @@ class LspManager {
|
|
|
2855
2960
|
signal.throwIfAborted();
|
|
2856
2961
|
}
|
|
2857
2962
|
if (!managed.client.isAlive()) {
|
|
2858
|
-
|
|
2859
|
-
this.clients.
|
|
2963
|
+
this.recordDeadGeneration(key);
|
|
2964
|
+
if (this.clients.get(key) === managed) {
|
|
2965
|
+
this.clients.delete(key);
|
|
2966
|
+
}
|
|
2967
|
+
await this.tombstoneStop(key, managed.client);
|
|
2860
2968
|
return this.getClient(root, server, signal);
|
|
2861
2969
|
}
|
|
2970
|
+
this.markHealthyGeneration(key);
|
|
2862
2971
|
managed.refCount++;
|
|
2863
2972
|
managed.lastUsedAt = this.now();
|
|
2864
2973
|
return managed.client;
|
|
2865
2974
|
}
|
|
2975
|
+
this.evictForAdmission();
|
|
2976
|
+
this.ensureRespawnAllowed(key, root, server.id);
|
|
2866
2977
|
const client = this.clientFactory(root, server);
|
|
2867
2978
|
const initStartedAt = this.now();
|
|
2868
2979
|
const initPromise = (async () => {
|
|
@@ -2886,7 +2997,7 @@ class LspManager {
|
|
|
2886
2997
|
if (this.clients.get(key) === newManaged) {
|
|
2887
2998
|
this.clients.delete(key);
|
|
2888
2999
|
}
|
|
2889
|
-
await
|
|
3000
|
+
await this.tombstoneStop(key, client);
|
|
2890
3001
|
throw err;
|
|
2891
3002
|
}
|
|
2892
3003
|
newManaged.pendingWaiters--;
|
|
@@ -2897,6 +3008,15 @@ class LspManager {
|
|
|
2897
3008
|
await this.tryDeleteIfOrphaned(key, newManaged);
|
|
2898
3009
|
signal.throwIfAborted();
|
|
2899
3010
|
}
|
|
3011
|
+
if (!client.isAlive()) {
|
|
3012
|
+
this.recordDeadGeneration(key);
|
|
3013
|
+
if (this.clients.get(key) === newManaged) {
|
|
3014
|
+
this.clients.delete(key);
|
|
3015
|
+
}
|
|
3016
|
+
await this.tombstoneStop(key, client);
|
|
3017
|
+
return this.getClient(root, server, signal);
|
|
3018
|
+
}
|
|
3019
|
+
this.markHealthyGeneration(key);
|
|
2900
3020
|
newManaged.refCount++;
|
|
2901
3021
|
newManaged.lastUsedAt = this.now();
|
|
2902
3022
|
return client;
|
|
@@ -2917,14 +3037,20 @@ class LspManager {
|
|
|
2917
3037
|
if (client && managed.client !== client)
|
|
2918
3038
|
return;
|
|
2919
3039
|
this.clients.delete(key);
|
|
2920
|
-
|
|
3040
|
+
this.tombstoneStop(key, managed.client);
|
|
2921
3041
|
}
|
|
2922
3042
|
warmupClient(root, server) {
|
|
2923
3043
|
if (this.disposed)
|
|
2924
3044
|
return;
|
|
2925
3045
|
const key = this.getKey(root, server.id);
|
|
2926
|
-
if (this.clients.has(key))
|
|
3046
|
+
if (this.clients.has(key) || this.pendingStops.has(key))
|
|
3047
|
+
return;
|
|
3048
|
+
this.evictForAdmission();
|
|
3049
|
+
try {
|
|
3050
|
+
this.ensureRespawnAllowed(key, root, server.id);
|
|
3051
|
+
} catch {
|
|
2927
3052
|
return;
|
|
3053
|
+
}
|
|
2928
3054
|
const client = this.clientFactory(root, server);
|
|
2929
3055
|
const initStartedAt = this.now();
|
|
2930
3056
|
const initPromise = (async () => {
|
|
@@ -2950,7 +3076,7 @@ class LspManager {
|
|
|
2950
3076
|
if (this.clients.get(key) === managed) {
|
|
2951
3077
|
this.clients.delete(key);
|
|
2952
3078
|
}
|
|
2953
|
-
|
|
3079
|
+
this.tombstoneStop(key, client);
|
|
2954
3080
|
});
|
|
2955
3081
|
}
|
|
2956
3082
|
isServerInitializing(root, serverId) {
|
|
@@ -2994,8 +3120,11 @@ class LspManager {
|
|
|
2994
3120
|
for (const managed of this.clients.values()) {
|
|
2995
3121
|
stopPromises.push(stopClientBestEffort(managed.client));
|
|
2996
3122
|
}
|
|
3123
|
+
const tombstonedStops = [...this.pendingStops.values()];
|
|
2997
3124
|
this.clients.clear();
|
|
2998
|
-
|
|
3125
|
+
this.respawnBudgets.clear();
|
|
3126
|
+
await Promise.allSettled([...stopPromises, ...tombstonedStops]);
|
|
3127
|
+
this.pendingStops.clear();
|
|
2999
3128
|
}
|
|
3000
3129
|
}
|
|
3001
3130
|
var _defaultInstance = null;
|
|
@@ -3189,6 +3318,7 @@ async function runJsonRpcStdioServer(config) {
|
|
|
3189
3318
|
const idleTimer = createIdleTimer(idleTimeoutMs, log, () => {
|
|
3190
3319
|
isClosed = true;
|
|
3191
3320
|
config.onIdleTimeout?.();
|
|
3321
|
+
config.input.destroy();
|
|
3192
3322
|
});
|
|
3193
3323
|
const watchdog = createParentWatchdog(config.parentWatchdog, (parentPid, pollIntervalMs) => {
|
|
3194
3324
|
isClosed = true;
|
|
@@ -3285,7 +3415,11 @@ function createParentWatchdog(config, onDeadParent) {
|
|
|
3285
3415
|
const probeAlive = config.probeAlive ?? isProcessAlive;
|
|
3286
3416
|
let fired = false;
|
|
3287
3417
|
const timer = setInterval(() => {
|
|
3288
|
-
if (fired
|
|
3418
|
+
if (fired)
|
|
3419
|
+
return;
|
|
3420
|
+
const alive = probeAlive(parentPid);
|
|
3421
|
+
config.onPoll?.(alive);
|
|
3422
|
+
if (alive)
|
|
3289
3423
|
return;
|
|
3290
3424
|
fired = true;
|
|
3291
3425
|
onDeadParent(parentPid, pollIntervalMs);
|
|
@@ -3320,8 +3454,8 @@ function createIdleTimer(idleTimeoutMs, log, onTimeout) {
|
|
|
3320
3454
|
};
|
|
3321
3455
|
}
|
|
3322
3456
|
// ../lsp-core/src/lsp/client-wrapper.ts
|
|
3323
|
-
import { existsSync as
|
|
3324
|
-
import { dirname as
|
|
3457
|
+
import { existsSync as existsSync10, realpathSync as realpathSync5, statSync as statSync3 } from "node:fs";
|
|
3458
|
+
import { basename as basename3, dirname as dirname8, join as join5, resolve as resolve8 } from "node:path";
|
|
3325
3459
|
|
|
3326
3460
|
// ../lsp-core/src/request-context.ts
|
|
3327
3461
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
@@ -3330,18 +3464,17 @@ import { homedir } from "node:os";
|
|
|
3330
3464
|
import { basename as basename2, delimiter as delimiter2, dirname as dirname4, isAbsolute as isAbsolute2, join as join2, relative as relative4, resolve as resolve6 } from "node:path";
|
|
3331
3465
|
|
|
3332
3466
|
class LspRequestContextParseError extends Error {
|
|
3333
|
-
code;
|
|
3334
|
-
name = "LspRequestContextParseError";
|
|
3335
3467
|
constructor(code, message) {
|
|
3336
3468
|
super(message);
|
|
3337
3469
|
this.code = code;
|
|
3470
|
+
this.name = "LspRequestContextParseError";
|
|
3338
3471
|
}
|
|
3339
3472
|
}
|
|
3340
3473
|
|
|
3341
3474
|
class LspRequestContextUnavailableError extends Error {
|
|
3342
|
-
name = "LspRequestContextUnavailableError";
|
|
3343
3475
|
constructor() {
|
|
3344
3476
|
super("LSP request context is required. Standalone MCP startup must install one with runWithRequestContext(createStandaloneMcpRequestContext()).");
|
|
3477
|
+
this.name = "LspRequestContextUnavailableError";
|
|
3345
3478
|
}
|
|
3346
3479
|
}
|
|
3347
3480
|
var storage = new AsyncLocalStorage;
|
|
@@ -3371,7 +3504,7 @@ function contextEnv(key) {
|
|
|
3371
3504
|
}
|
|
3372
3505
|
function createStandaloneMcpRequestContext(input = {}) {
|
|
3373
3506
|
const env = input.env ?? process.env;
|
|
3374
|
-
const cwd = canonicalCwd(input.cwd ?? process.cwd());
|
|
3507
|
+
const cwd = canonicalCwd(input.cwd ?? env["LSP_TOOLS_MCP_CWD"] ?? process.cwd());
|
|
3375
3508
|
const home = input.homeDir ?? homedir();
|
|
3376
3509
|
const projectConfigPaths = translateProjectConfigEnv(env["LSP_TOOLS_MCP_PROJECT_CONFIG"], cwd);
|
|
3377
3510
|
const userConfigPath = translateHomeConfigEnv(env["LSP_TOOLS_MCP_USER_CONFIG"], home, ".codex/lsp-client.json");
|
|
@@ -3502,57 +3635,52 @@ function errorCode(error) {
|
|
|
3502
3635
|
return typeof code === "string" ? code : undefined;
|
|
3503
3636
|
}
|
|
3504
3637
|
|
|
3505
|
-
// ../lsp-core/src/lsp/
|
|
3506
|
-
import { existsSync as existsSync6,
|
|
3507
|
-
import { dirname as dirname5 } from "node:path";
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
|
|
3512
|
-
|
|
3513
|
-
|
|
3514
|
-
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
|
|
3518
|
-
|
|
3519
|
-
|
|
3638
|
+
// ../lsp-core/src/lsp/outside-context-workspace.ts
|
|
3639
|
+
import { existsSync as existsSync6, realpathSync as realpathSync4 } from "node:fs";
|
|
3640
|
+
import { dirname as dirname5, join as join3 } from "node:path";
|
|
3641
|
+
|
|
3642
|
+
// ../lsp-core/src/lsp/workspace-markers.ts
|
|
3643
|
+
var GIT_WORKSPACE_MARKER = ".git";
|
|
3644
|
+
var PROJECT_WORKSPACE_MARKERS = [
|
|
3645
|
+
"package.json",
|
|
3646
|
+
"pyproject.toml",
|
|
3647
|
+
"Cargo.toml",
|
|
3648
|
+
"go.mod",
|
|
3649
|
+
"pom.xml",
|
|
3650
|
+
"build.gradle"
|
|
3651
|
+
];
|
|
3652
|
+
var WORKSPACE_MARKERS = [GIT_WORKSPACE_MARKER, ...PROJECT_WORKSPACE_MARKERS];
|
|
3653
|
+
|
|
3654
|
+
// ../lsp-core/src/lsp/outside-context-workspace.ts
|
|
3655
|
+
function findWorkspaceRootOutsideContext(directory) {
|
|
3656
|
+
const marked = nearestMarkedAncestor(directory);
|
|
3657
|
+
if (marked !== undefined)
|
|
3658
|
+
return marked;
|
|
3659
|
+
return realpathSync4(nearestExistingAncestor(directory));
|
|
3660
|
+
}
|
|
3661
|
+
function nearestMarkedAncestor(directory) {
|
|
3662
|
+
let current = directory;
|
|
3663
|
+
for (;; ) {
|
|
3664
|
+
if (existsSync6(current) && WORKSPACE_MARKERS.some((marker) => existsSync6(join3(current, marker)))) {
|
|
3665
|
+
return realpathSync4(current);
|
|
3666
|
+
}
|
|
3667
|
+
const parent = dirname5(current);
|
|
3668
|
+
if (parent === current)
|
|
3669
|
+
return;
|
|
3670
|
+
current = parent;
|
|
3520
3671
|
}
|
|
3521
3672
|
}
|
|
3522
|
-
function
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
|
|
3526
|
-
|
|
3527
|
-
|
|
3528
|
-
|
|
3529
|
-
}
|
|
3530
|
-
|
|
3531
|
-
return value === "declined" || value === "allowed";
|
|
3532
|
-
}
|
|
3533
|
-
function writeInstallDecisions(decisions) {
|
|
3534
|
-
const path = getInstallDecisionsPath();
|
|
3535
|
-
mkdirSync(dirname5(path), { recursive: true });
|
|
3536
|
-
const tmpPath = `${path}.tmp`;
|
|
3537
|
-
writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
|
|
3538
|
-
`, "utf8");
|
|
3539
|
-
renameSync2(tmpPath, path);
|
|
3540
|
-
}
|
|
3541
|
-
function isInstallDecisions(value) {
|
|
3542
|
-
return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
|
|
3543
|
-
}
|
|
3544
|
-
function isInstallDecisionRecord(value) {
|
|
3545
|
-
if (!isRecord5(value))
|
|
3546
|
-
return false;
|
|
3547
|
-
return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
|
|
3548
|
-
}
|
|
3549
|
-
function isRecord5(value) {
|
|
3550
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3673
|
+
function nearestExistingAncestor(directory) {
|
|
3674
|
+
let current = directory;
|
|
3675
|
+
while (!existsSync6(current)) {
|
|
3676
|
+
const parent = dirname5(current);
|
|
3677
|
+
if (parent === current)
|
|
3678
|
+
return current;
|
|
3679
|
+
current = parent;
|
|
3680
|
+
}
|
|
3681
|
+
return current;
|
|
3551
3682
|
}
|
|
3552
3683
|
|
|
3553
|
-
// ../lsp-core/src/lsp/config-loader.ts
|
|
3554
|
-
import { existsSync as existsSync7, readFileSync as readFileSync4 } from "node:fs";
|
|
3555
|
-
|
|
3556
3684
|
// ../lsp-core/src/lsp/server-definitions.ts
|
|
3557
3685
|
var LSP_INSTALL_HINTS = {
|
|
3558
3686
|
typescript: "npm install -g typescript-language-server typescript",
|
|
@@ -3598,6 +3726,26 @@ var LSP_INSTALL_HINTS = {
|
|
|
3598
3726
|
julials: `julia -e 'using Pkg; Pkg.add("LanguageServer")'`,
|
|
3599
3727
|
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"
|
|
3600
3728
|
};
|
|
3729
|
+
var LSP_LOCAL_INSTALL_HINTS = {
|
|
3730
|
+
typescript: "bun add -d typescript-language-server typescript",
|
|
3731
|
+
vue: "bun add -d @vue/language-server",
|
|
3732
|
+
eslint: "bun add -d vscode-langservers-extracted",
|
|
3733
|
+
oxlint: "bun add -d oxlint",
|
|
3734
|
+
biome: "bun add -d @biomejs/biome",
|
|
3735
|
+
svelte: "bun add -d svelte-language-server",
|
|
3736
|
+
astro: "bun add -d @astrojs/language-server",
|
|
3737
|
+
bash: "bun add -d bash-language-server",
|
|
3738
|
+
"bash-ls": "bun add -d bash-language-server",
|
|
3739
|
+
"yaml-ls": "bun add -d yaml-language-server",
|
|
3740
|
+
php: "bun add -d intelephense",
|
|
3741
|
+
prisma: "bun add -d prisma",
|
|
3742
|
+
dockerfile: "bun add -d dockerfile-language-server-nodejs",
|
|
3743
|
+
pyright: "uv add --dev pyright",
|
|
3744
|
+
basedpyright: "uv add --dev basedpyright",
|
|
3745
|
+
ruff: "uv add --dev ruff",
|
|
3746
|
+
ty: "uv add --dev ty",
|
|
3747
|
+
"ruby-lsp": "bundle add ruby-lsp --group development"
|
|
3748
|
+
};
|
|
3601
3749
|
var BUILTIN_SERVERS = {
|
|
3602
3750
|
typescript: {
|
|
3603
3751
|
command: ["typescript-language-server", "--stdio"],
|
|
@@ -3700,7 +3848,56 @@ var BUILTIN_SERVERS = {
|
|
|
3700
3848
|
}
|
|
3701
3849
|
};
|
|
3702
3850
|
|
|
3851
|
+
// ../lsp-core/src/lsp/server-install-state.ts
|
|
3852
|
+
import { existsSync as existsSync7, mkdirSync, readFileSync as readFileSync3, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
3853
|
+
import { dirname as dirname6 } from "node:path";
|
|
3854
|
+
function getInstallDecisionsPath() {
|
|
3855
|
+
return lspRequestContext().installDecisionsPath;
|
|
3856
|
+
}
|
|
3857
|
+
function loadInstallDecisions() {
|
|
3858
|
+
const path = getInstallDecisionsPath();
|
|
3859
|
+
if (!existsSync7(path))
|
|
3860
|
+
return {};
|
|
3861
|
+
try {
|
|
3862
|
+
const parsed = JSON.parse(readFileSync3(path, "utf8"));
|
|
3863
|
+
return isInstallDecisions(parsed) ? parsed : {};
|
|
3864
|
+
} catch {
|
|
3865
|
+
return {};
|
|
3866
|
+
}
|
|
3867
|
+
}
|
|
3868
|
+
function loadInstallDecision(serverId) {
|
|
3869
|
+
return loadInstallDecisions()[serverId];
|
|
3870
|
+
}
|
|
3871
|
+
function recordInstallDecision(serverId, decision, decidedAt = new Date().toISOString()) {
|
|
3872
|
+
const decisions = loadInstallDecisions();
|
|
3873
|
+
decisions[serverId] = { decision, decidedAt };
|
|
3874
|
+
writeInstallDecisions(decisions);
|
|
3875
|
+
}
|
|
3876
|
+
function isInstallDecision(value) {
|
|
3877
|
+
return value === "declined" || value === "allowed";
|
|
3878
|
+
}
|
|
3879
|
+
function writeInstallDecisions(decisions) {
|
|
3880
|
+
const path = getInstallDecisionsPath();
|
|
3881
|
+
mkdirSync(dirname6(path), { recursive: true });
|
|
3882
|
+
const tmpPath = `${path}.tmp`;
|
|
3883
|
+
writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
|
|
3884
|
+
`, "utf8");
|
|
3885
|
+
renameSync2(tmpPath, path);
|
|
3886
|
+
}
|
|
3887
|
+
function isInstallDecisions(value) {
|
|
3888
|
+
return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
|
|
3889
|
+
}
|
|
3890
|
+
function isInstallDecisionRecord(value) {
|
|
3891
|
+
if (!isRecord5(value))
|
|
3892
|
+
return false;
|
|
3893
|
+
return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
|
|
3894
|
+
}
|
|
3895
|
+
function isRecord5(value) {
|
|
3896
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3897
|
+
}
|
|
3898
|
+
|
|
3703
3899
|
// ../lsp-core/src/lsp/config-loader.ts
|
|
3900
|
+
import { existsSync as existsSync8, readFileSync as readFileSync4 } from "node:fs";
|
|
3704
3901
|
function getProjectConfigPaths() {
|
|
3705
3902
|
return lspRequestContext().projectConfigPaths;
|
|
3706
3903
|
}
|
|
@@ -3708,7 +3905,7 @@ function getUserConfigPath() {
|
|
|
3708
3905
|
return lspRequestContext().userConfigPath;
|
|
3709
3906
|
}
|
|
3710
3907
|
function loadJsonFile(path) {
|
|
3711
|
-
if (!
|
|
3908
|
+
if (!existsSync8(path))
|
|
3712
3909
|
return null;
|
|
3713
3910
|
try {
|
|
3714
3911
|
const parsed = JSON.parse(readFileSync4(path, "utf-8"));
|
|
@@ -3896,54 +4093,155 @@ function getDisabledServerIds() {
|
|
|
3896
4093
|
}
|
|
3897
4094
|
|
|
3898
4095
|
// ../lsp-core/src/lsp/server-installation.ts
|
|
3899
|
-
import { existsSync as
|
|
3900
|
-
import { delimiter as delimiter3, join as
|
|
3901
|
-
|
|
3902
|
-
|
|
3903
|
-
|
|
3904
|
-
|
|
3905
|
-
|
|
3906
|
-
|
|
3907
|
-
|
|
3908
|
-
|
|
3909
|
-
|
|
4096
|
+
import { existsSync as existsSync9 } from "node:fs";
|
|
4097
|
+
import { delimiter as delimiter3, dirname as dirname7, isAbsolute as isAbsolute3, join as join4, resolve as resolve7 } from "node:path";
|
|
4098
|
+
var LOCAL_BIN_RULES = [
|
|
4099
|
+
{
|
|
4100
|
+
markers: ["package.json", "bun.lock", "bun.lockb", "package-lock.json", "yarn.lock", "pnpm-lock.yaml"],
|
|
4101
|
+
binDirs: [join4("node_modules", ".bin")]
|
|
4102
|
+
},
|
|
4103
|
+
{
|
|
4104
|
+
markers: [
|
|
4105
|
+
"pyproject.toml",
|
|
4106
|
+
"ty.toml",
|
|
4107
|
+
"requirements.txt",
|
|
4108
|
+
"setup.py",
|
|
4109
|
+
"setup.cfg",
|
|
4110
|
+
"Pipfile",
|
|
4111
|
+
"pyrightconfig.json",
|
|
4112
|
+
"ruff.toml",
|
|
4113
|
+
".ruff.toml"
|
|
4114
|
+
],
|
|
4115
|
+
binDirs: [
|
|
4116
|
+
join4(".venv", "bin"),
|
|
4117
|
+
join4(".venv", "Scripts"),
|
|
4118
|
+
join4("venv", "bin"),
|
|
4119
|
+
join4("venv", "Scripts"),
|
|
4120
|
+
join4(".env", "bin"),
|
|
4121
|
+
join4(".env", "Scripts")
|
|
4122
|
+
]
|
|
4123
|
+
},
|
|
4124
|
+
{
|
|
4125
|
+
markers: ["Gemfile", "Gemfile.lock"],
|
|
4126
|
+
binDirs: [join4("vendor", "bundle", "bin"), "bin"]
|
|
4127
|
+
},
|
|
4128
|
+
{
|
|
4129
|
+
markers: ["go.mod", "go.sum", "go.work"],
|
|
4130
|
+
binDirs: ["bin"]
|
|
4131
|
+
}
|
|
4132
|
+
];
|
|
4133
|
+
var resolutionCache = new Map;
|
|
4134
|
+
var probeCount = 0;
|
|
4135
|
+
function probe(path) {
|
|
4136
|
+
probeCount += 1;
|
|
4137
|
+
return existsSync9(path);
|
|
4138
|
+
}
|
|
4139
|
+
function executableSuffixes(platform, pathExt) {
|
|
4140
|
+
if (platform !== "win32")
|
|
4141
|
+
return [""];
|
|
4142
|
+
const configured = pathExt ?? process.env["PATHEXT"] ?? "";
|
|
4143
|
+
const systemExts = configured.split(";").filter((entry) => entry.length > 0).map((entry) => entry.toLowerCase());
|
|
4144
|
+
return [...new Set(["", ...systemExts, ".exe", ".cmd", ".bat", ".ps1"])];
|
|
4145
|
+
}
|
|
4146
|
+
function probeWithSuffixes(directory, command, suffixes) {
|
|
4147
|
+
for (const suffix of suffixes) {
|
|
4148
|
+
const candidate = join4(directory, command + suffix);
|
|
4149
|
+
if (probe(candidate))
|
|
4150
|
+
return candidate;
|
|
3910
4151
|
}
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
|
|
3915
|
-
|
|
3916
|
-
|
|
3917
|
-
|
|
3918
|
-
|
|
3919
|
-
|
|
4152
|
+
return null;
|
|
4153
|
+
}
|
|
4154
|
+
function resolveLocal(command, workingDirectory, suffixes, stopAt) {
|
|
4155
|
+
const boundary = stopAt === undefined ? undefined : resolve7(stopAt);
|
|
4156
|
+
let current = resolve7(workingDirectory);
|
|
4157
|
+
while (true) {
|
|
4158
|
+
for (const rule of LOCAL_BIN_RULES) {
|
|
4159
|
+
if (!rule.markers.some((marker) => probe(join4(current, marker))))
|
|
4160
|
+
continue;
|
|
4161
|
+
for (const binDir of rule.binDirs) {
|
|
4162
|
+
const found = probeWithSuffixes(join4(current, binDir), command, suffixes);
|
|
4163
|
+
if (found !== null)
|
|
4164
|
+
return found;
|
|
4165
|
+
}
|
|
3920
4166
|
}
|
|
4167
|
+
if (probe(join4(current, ".git")))
|
|
4168
|
+
return null;
|
|
4169
|
+
if (boundary !== undefined && current === boundary)
|
|
4170
|
+
return null;
|
|
4171
|
+
const parent = dirname7(current);
|
|
4172
|
+
if (parent === current)
|
|
4173
|
+
return null;
|
|
4174
|
+
current = parent;
|
|
3921
4175
|
}
|
|
3922
|
-
|
|
3923
|
-
|
|
4176
|
+
}
|
|
4177
|
+
function resolveFromPath(command, suffixes, platform, pathEnvOverride) {
|
|
4178
|
+
let pathEnv = pathEnvOverride ?? process.env["PATH"] ?? "";
|
|
4179
|
+
if (platform === "win32" && !pathEnv) {
|
|
3924
4180
|
pathEnv = process.env["Path"] ?? "";
|
|
3925
4181
|
}
|
|
3926
|
-
const
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
|
|
3932
|
-
}
|
|
4182
|
+
for (const entry of pathEnv.split(delimiter3)) {
|
|
4183
|
+
if (entry.length === 0)
|
|
4184
|
+
continue;
|
|
4185
|
+
const found = probeWithSuffixes(entry, command, suffixes);
|
|
4186
|
+
if (found !== null)
|
|
4187
|
+
return found;
|
|
3933
4188
|
}
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
|
|
4189
|
+
return null;
|
|
4190
|
+
}
|
|
4191
|
+
function resolveServerBinary(command, workingDirectory, options = {}) {
|
|
4192
|
+
if (command.length === 0)
|
|
4193
|
+
return null;
|
|
4194
|
+
const [cmd] = command;
|
|
4195
|
+
if (cmd === undefined || cmd.length === 0)
|
|
4196
|
+
return null;
|
|
4197
|
+
const platform = options.platform ?? process.platform;
|
|
4198
|
+
const suffixes = executableSuffixes(platform, options.pathExt);
|
|
4199
|
+
if (cmd.includes("/") || cmd.includes("\\")) {
|
|
4200
|
+
const explicit = isAbsolute3(cmd) ? cmd : resolve7(workingDirectory ?? process.cwd(), cmd);
|
|
4201
|
+
return probe(explicit) ? explicit : null;
|
|
4202
|
+
}
|
|
4203
|
+
const cacheKey = JSON.stringify([
|
|
4204
|
+
workingDirectory ?? "",
|
|
4205
|
+
cmd,
|
|
4206
|
+
platform,
|
|
4207
|
+
options.stopAt ?? "",
|
|
4208
|
+
options.pathExt ?? "",
|
|
4209
|
+
options.pathEnv ?? process.env["PATH"] ?? ""
|
|
4210
|
+
]);
|
|
4211
|
+
const cached = resolutionCache.get(cacheKey);
|
|
4212
|
+
if (cached !== undefined)
|
|
4213
|
+
return cached;
|
|
4214
|
+
let resolved = null;
|
|
4215
|
+
if (workingDirectory !== undefined && workingDirectory.length > 0) {
|
|
4216
|
+
resolved = resolveLocal(cmd, workingDirectory, suffixes, options.stopAt);
|
|
4217
|
+
}
|
|
4218
|
+
resolved ??= resolveFromPath(cmd, suffixes, platform, options.pathEnv);
|
|
4219
|
+
if (resolved === null && cmd === "node")
|
|
4220
|
+
resolved = cmd;
|
|
4221
|
+
resolutionCache.set(cacheKey, resolved);
|
|
4222
|
+
return resolved;
|
|
4223
|
+
}
|
|
4224
|
+
function isServerInstalled(command, workingDirectory, options = {}) {
|
|
4225
|
+
if (command.length === 0)
|
|
4226
|
+
return false;
|
|
4227
|
+
return resolveServerBinary(command, workingDirectory, options) !== null;
|
|
3937
4228
|
}
|
|
3938
4229
|
|
|
3939
4230
|
// ../lsp-core/src/lsp/server-resolution.ts
|
|
4231
|
+
function withResolvedCommand(command, binaryPath) {
|
|
4232
|
+
return [binaryPath, ...command.slice(1)];
|
|
4233
|
+
}
|
|
3940
4234
|
function findServerForExtension(ext) {
|
|
3941
4235
|
const servers = getMergedServers();
|
|
4236
|
+
const workingDirectory = contextCwd();
|
|
3942
4237
|
for (const server2 of servers) {
|
|
3943
|
-
if (server2.extensions.includes(ext)
|
|
4238
|
+
if (!server2.extensions.includes(ext))
|
|
4239
|
+
continue;
|
|
4240
|
+
const binaryPath = resolveServerBinary(server2.command, workingDirectory);
|
|
4241
|
+
if (binaryPath !== null) {
|
|
3944
4242
|
const resolvedServer = {
|
|
3945
4243
|
id: server2.id,
|
|
3946
|
-
command: server2.command,
|
|
4244
|
+
command: withResolvedCommand(server2.command, binaryPath),
|
|
3947
4245
|
extensions: server2.extensions,
|
|
3948
4246
|
priority: server2.priority
|
|
3949
4247
|
};
|
|
@@ -3990,6 +4288,7 @@ function findServerForExtension(ext) {
|
|
|
3990
4288
|
function getAllServers() {
|
|
3991
4289
|
const servers = getMergedServers();
|
|
3992
4290
|
const disabled = getDisabledServerIds();
|
|
4291
|
+
const workingDirectory = contextCwd();
|
|
3993
4292
|
const result = [];
|
|
3994
4293
|
const seen = new Set;
|
|
3995
4294
|
for (const server2 of servers) {
|
|
@@ -3997,7 +4296,7 @@ function getAllServers() {
|
|
|
3997
4296
|
continue;
|
|
3998
4297
|
result.push({
|
|
3999
4298
|
id: server2.id,
|
|
4000
|
-
installed: isServerInstalled(server2.command),
|
|
4299
|
+
installed: isServerInstalled(server2.command, workingDirectory),
|
|
4001
4300
|
extensions: server2.extensions,
|
|
4002
4301
|
disabled: false,
|
|
4003
4302
|
source: server2.source,
|
|
@@ -4011,7 +4310,7 @@ function getAllServers() {
|
|
|
4011
4310
|
const builtin = BUILTIN_SERVERS[id];
|
|
4012
4311
|
result.push({
|
|
4013
4312
|
id,
|
|
4014
|
-
installed: builtin ? isServerInstalled(builtin.command) : false,
|
|
4313
|
+
installed: builtin ? isServerInstalled(builtin.command, workingDirectory) : false,
|
|
4015
4314
|
extensions: builtin?.extensions ?? [],
|
|
4016
4315
|
disabled: true,
|
|
4017
4316
|
source: "disabled",
|
|
@@ -4022,7 +4321,6 @@ function getAllServers() {
|
|
|
4022
4321
|
}
|
|
4023
4322
|
|
|
4024
4323
|
// ../lsp-core/src/lsp/client-wrapper.ts
|
|
4025
|
-
var WORKSPACE_MARKERS = [".git", "package.json", "pyproject.toml", "Cargo.toml", "go.mod", "pom.xml", "build.gradle"];
|
|
4026
4324
|
function isDirectoryPath(filePath) {
|
|
4027
4325
|
try {
|
|
4028
4326
|
return statSync3(filePath).isDirectory();
|
|
@@ -4031,32 +4329,90 @@ function isDirectoryPath(filePath) {
|
|
|
4031
4329
|
}
|
|
4032
4330
|
}
|
|
4033
4331
|
function findWorkspaceRoot(filePath) {
|
|
4034
|
-
const
|
|
4332
|
+
const cwd = contextCwd();
|
|
4333
|
+
const abs = resolveReadablePathInsideContext(filePath);
|
|
4035
4334
|
let dir = abs;
|
|
4036
4335
|
if (!isDirectoryPath(dir)) {
|
|
4037
|
-
dir =
|
|
4038
|
-
}
|
|
4039
|
-
|
|
4040
|
-
|
|
4041
|
-
|
|
4042
|
-
|
|
4043
|
-
|
|
4336
|
+
dir = dirname8(dir);
|
|
4337
|
+
}
|
|
4338
|
+
if (!isPathInside(cwd, abs))
|
|
4339
|
+
return findWorkspaceRootOutsideContext(dir);
|
|
4340
|
+
const fallbackRoot = nearestExistingDirectoryInsideContext(dir, cwd) ?? cwd;
|
|
4341
|
+
let nearestPackageRoot;
|
|
4342
|
+
while (isPathInside(cwd, dir)) {
|
|
4343
|
+
const canonicalDir = existingDirectoryInsideContext(dir, cwd);
|
|
4344
|
+
if (canonicalDir !== undefined) {
|
|
4345
|
+
if (existsSync10(join5(dir, GIT_WORKSPACE_MARKER))) {
|
|
4346
|
+
return canonicalDir;
|
|
4347
|
+
}
|
|
4348
|
+
if (nearestPackageRoot === undefined && hasProjectWorkspaceMarker(dir)) {
|
|
4349
|
+
nearestPackageRoot = canonicalDir;
|
|
4044
4350
|
}
|
|
4045
4351
|
}
|
|
4046
|
-
|
|
4047
|
-
|
|
4352
|
+
if (dir === cwd)
|
|
4353
|
+
break;
|
|
4354
|
+
dir = dirname8(dir);
|
|
4048
4355
|
}
|
|
4049
|
-
return
|
|
4356
|
+
return nearestPackageRoot ?? fallbackRoot;
|
|
4357
|
+
}
|
|
4358
|
+
function hasProjectWorkspaceMarker(directory) {
|
|
4359
|
+
return PROJECT_WORKSPACE_MARKERS.some((marker) => existsSync10(join5(directory, marker)));
|
|
4360
|
+
}
|
|
4361
|
+
function resolveReadablePathInsideContext(filePath) {
|
|
4362
|
+
const cwd = contextCwd();
|
|
4363
|
+
const abs = resolve8(cwd, filePath);
|
|
4364
|
+
if (isPathInside(cwd, abs))
|
|
4365
|
+
return abs;
|
|
4366
|
+
const rebased = rebaseThroughCanonicalAncestor(abs, cwd);
|
|
4367
|
+
if (rebased !== undefined)
|
|
4368
|
+
return rebased;
|
|
4369
|
+
return canonicalizeExistingOrNearestAncestor(abs);
|
|
4050
4370
|
}
|
|
4051
4371
|
function resolvePathInsideContext(filePath) {
|
|
4052
4372
|
const cwd = contextCwd();
|
|
4053
|
-
const abs =
|
|
4373
|
+
const abs = resolveReadablePathInsideContext(filePath);
|
|
4054
4374
|
const canonical = canonicalizeExistingOrNearestAncestor(abs);
|
|
4055
4375
|
if (!isPathInside(cwd, canonical)) {
|
|
4056
4376
|
throw new LspInvalidPathError(`LSP file path must be inside request cwd: ${filePath}`);
|
|
4057
4377
|
}
|
|
4058
4378
|
return canonical;
|
|
4059
4379
|
}
|
|
4380
|
+
function rebaseThroughCanonicalAncestor(path, cwd) {
|
|
4381
|
+
let current = path;
|
|
4382
|
+
const suffix = [];
|
|
4383
|
+
while (true) {
|
|
4384
|
+
if (existsSync10(current)) {
|
|
4385
|
+
const canonical = realpathSync5(current);
|
|
4386
|
+
if (isPathInside(cwd, canonical))
|
|
4387
|
+
return suffix.length === 0 ? canonical : join5(canonical, ...suffix);
|
|
4388
|
+
}
|
|
4389
|
+
const parent = dirname8(current);
|
|
4390
|
+
if (parent === current)
|
|
4391
|
+
return;
|
|
4392
|
+
suffix.unshift(basename3(current));
|
|
4393
|
+
current = parent;
|
|
4394
|
+
}
|
|
4395
|
+
}
|
|
4396
|
+
function existingDirectoryInsideContext(directory, cwd) {
|
|
4397
|
+
if (!existsSync10(directory))
|
|
4398
|
+
return;
|
|
4399
|
+
const canonical = realpathSync5(directory);
|
|
4400
|
+
if (!statSync3(canonical).isDirectory())
|
|
4401
|
+
return;
|
|
4402
|
+
return isPathInside(cwd, canonical) ? canonical : undefined;
|
|
4403
|
+
}
|
|
4404
|
+
function nearestExistingDirectoryInsideContext(directory, cwd) {
|
|
4405
|
+
let current = directory;
|
|
4406
|
+
while (isPathInside(cwd, current)) {
|
|
4407
|
+
const canonical = existingDirectoryInsideContext(current, cwd);
|
|
4408
|
+
if (canonical !== undefined)
|
|
4409
|
+
return canonical;
|
|
4410
|
+
if (current === cwd)
|
|
4411
|
+
return;
|
|
4412
|
+
current = dirname8(current);
|
|
4413
|
+
}
|
|
4414
|
+
return;
|
|
4415
|
+
}
|
|
4060
4416
|
function formatServerLookupError(result) {
|
|
4061
4417
|
if (result.status === "not_installed") {
|
|
4062
4418
|
return formatNotInstalled(result);
|
|
@@ -4080,6 +4436,19 @@ function formatServerLookupError(result) {
|
|
|
4080
4436
|
].join(`
|
|
4081
4437
|
`);
|
|
4082
4438
|
}
|
|
4439
|
+
function formatInstallOptions(serverId, installHint) {
|
|
4440
|
+
const localHint = LSP_LOCAL_INSTALL_HINTS[serverId];
|
|
4441
|
+
if (localHint === undefined) {
|
|
4442
|
+
return ["To install, run:", ` ${installHint}`];
|
|
4443
|
+
}
|
|
4444
|
+
return [
|
|
4445
|
+
"To install in THIS repository (preferred — no global install needed):",
|
|
4446
|
+
` ${localHint}`,
|
|
4447
|
+
"",
|
|
4448
|
+
"Or install it globally:",
|
|
4449
|
+
` ${installHint}`
|
|
4450
|
+
];
|
|
4451
|
+
}
|
|
4083
4452
|
function formatNotInstalled(result) {
|
|
4084
4453
|
const { server: server2, installHint } = result;
|
|
4085
4454
|
const extensions = server2.extensions.join(", ");
|
|
@@ -4094,19 +4463,19 @@ function formatNotInstalled(result) {
|
|
|
4094
4463
|
`Command not found: ${server2.command[0]}`,
|
|
4095
4464
|
""
|
|
4096
4465
|
];
|
|
4466
|
+
const installOptions = formatInstallOptions(server2.id, installHint);
|
|
4097
4467
|
if (decision === "allowed") {
|
|
4098
4468
|
return [
|
|
4099
4469
|
...header,
|
|
4100
4470
|
"The user has pre-authorized LSP installation. Run the install command, then retry this tool:",
|
|
4101
|
-
|
|
4471
|
+
...installOptions.slice(1)
|
|
4102
4472
|
].join(`
|
|
4103
4473
|
`);
|
|
4104
4474
|
}
|
|
4105
4475
|
if (!context.capabilities.installDecisionTool) {
|
|
4106
4476
|
return [
|
|
4107
4477
|
...header,
|
|
4108
|
-
|
|
4109
|
-
` ${installHint}`,
|
|
4478
|
+
...installOptions,
|
|
4110
4479
|
"",
|
|
4111
4480
|
"ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
|
|
4112
4481
|
"Install-decision recording is unavailable in this harness; proceed without LSP if the user declines."
|
|
@@ -4115,8 +4484,7 @@ function formatNotInstalled(result) {
|
|
|
4115
4484
|
}
|
|
4116
4485
|
return [
|
|
4117
4486
|
...header,
|
|
4118
|
-
|
|
4119
|
-
` ${installHint}`,
|
|
4487
|
+
...installOptions,
|
|
4120
4488
|
"",
|
|
4121
4489
|
"ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
|
|
4122
4490
|
"- If the user agrees: run the install command above, then retry this tool.",
|
|
@@ -4127,7 +4495,7 @@ function formatNotInstalled(result) {
|
|
|
4127
4495
|
].join(`
|
|
4128
4496
|
`);
|
|
4129
4497
|
}
|
|
4130
|
-
var
|
|
4498
|
+
var READ_ONLY_TOOLS = new Set([
|
|
4131
4499
|
"diagnostics",
|
|
4132
4500
|
"definition",
|
|
4133
4501
|
"references",
|
|
@@ -4136,7 +4504,7 @@ var READ_ONLY_RETRY_TOOLS = new Set([
|
|
|
4136
4504
|
"prepareRename"
|
|
4137
4505
|
]);
|
|
4138
4506
|
async function withLspClient(filePath, fn, toolName, options = {}) {
|
|
4139
|
-
const absPath = resolvePathInsideContext(filePath);
|
|
4507
|
+
const absPath = READ_ONLY_TOOLS.has(toolName) ? resolveReadablePathInsideContext(filePath) : resolvePathInsideContext(filePath);
|
|
4140
4508
|
if (isDirectoryPath(absPath)) {
|
|
4141
4509
|
throw new LspInvalidPathError("Directory paths are not supported by this LSP tool. " + "Use lsp.diagnostics with a directory path for directory diagnostics.");
|
|
4142
4510
|
}
|
|
@@ -4151,9 +4519,9 @@ async function withLspClient(filePath, fn, toolName, options = {}) {
|
|
|
4151
4519
|
const acquireAndCall = async (allowRetry) => {
|
|
4152
4520
|
const client = await manager2.getClient(root, server2, options.signal);
|
|
4153
4521
|
try {
|
|
4154
|
-
return await fn(client, root);
|
|
4522
|
+
return await fn(client, root, absPath);
|
|
4155
4523
|
} catch (err) {
|
|
4156
|
-
if (allowRetry &&
|
|
4524
|
+
if (allowRetry && READ_ONLY_TOOLS.has(toolName) && isLspDeadConnectionError(err)) {
|
|
4157
4525
|
manager2.invalidateClient(root, server2.id, client);
|
|
4158
4526
|
return acquireAndCall(false);
|
|
4159
4527
|
}
|
|
@@ -4171,8 +4539,8 @@ async function withLspClient(filePath, fn, toolName, options = {}) {
|
|
|
4171
4539
|
}
|
|
4172
4540
|
|
|
4173
4541
|
// ../lsp-core/src/lsp/directory-diagnostics.ts
|
|
4174
|
-
import { existsSync as
|
|
4175
|
-
import { join as
|
|
4542
|
+
import { existsSync as existsSync11, lstatSync as lstatSync4, readdirSync as readdirSync3 } from "node:fs";
|
|
4543
|
+
import { join as join6, resolve as resolve9 } from "node:path";
|
|
4176
4544
|
|
|
4177
4545
|
// ../lsp-core/src/lsp/formatters.ts
|
|
4178
4546
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
@@ -4302,7 +4670,7 @@ function collectFilesWithExtension(dir, extension, maxFiles) {
|
|
|
4302
4670
|
for (const entry of entries) {
|
|
4303
4671
|
if (files.length >= maxFiles)
|
|
4304
4672
|
return;
|
|
4305
|
-
const fullPath =
|
|
4673
|
+
const fullPath = join6(currentDir, entry);
|
|
4306
4674
|
let stat;
|
|
4307
4675
|
try {
|
|
4308
4676
|
stat = lstatSync4(fullPath);
|
|
@@ -4327,8 +4695,8 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
|
|
|
4327
4695
|
if (!extension.startsWith(".")) {
|
|
4328
4696
|
throw new LspInvalidPathError(`Extension must start with a dot (e.g., ".ts", not "${extension}"). Use ".${extension}" instead.`);
|
|
4329
4697
|
}
|
|
4330
|
-
const absDir =
|
|
4331
|
-
if (!
|
|
4698
|
+
const absDir = resolve9(options.workspaceRoot ?? contextCwd(), directory);
|
|
4699
|
+
if (!existsSync11(absDir)) {
|
|
4332
4700
|
throw new LspInvalidPathError(`Directory does not exist: ${absDir}`);
|
|
4333
4701
|
}
|
|
4334
4702
|
const serverResult = options.server === undefined ? findServerForExtension(extension) : { status: "found", server: options.server };
|
|
@@ -4415,7 +4783,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
|
|
|
4415
4783
|
|
|
4416
4784
|
// ../lsp-core/src/lsp/infer-extension.ts
|
|
4417
4785
|
import { lstatSync as lstatSync5, readdirSync as readdirSync4 } from "node:fs";
|
|
4418
|
-
import { join as
|
|
4786
|
+
import { join as join7 } from "node:path";
|
|
4419
4787
|
var SKIP_DIRECTORIES2 = new Set(["node_modules", ".git", "dist", "build", ".next", "out"]);
|
|
4420
4788
|
var MAX_SCAN_ENTRIES = 500;
|
|
4421
4789
|
function inferExtensionFromDirectory(directory) {
|
|
@@ -4433,7 +4801,7 @@ function inferExtensionFromDirectory(directory) {
|
|
|
4433
4801
|
for (const entry of entries) {
|
|
4434
4802
|
if (scanned >= MAX_SCAN_ENTRIES)
|
|
4435
4803
|
return;
|
|
4436
|
-
const fullPath =
|
|
4804
|
+
const fullPath = join7(dir, entry);
|
|
4437
4805
|
let stat;
|
|
4438
4806
|
try {
|
|
4439
4807
|
stat = lstatSync5(fullPath);
|
|
@@ -4608,7 +4976,7 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
4608
4976
|
const filePath = requireString(params, "filePath");
|
|
4609
4977
|
const severity = severityFilter(params);
|
|
4610
4978
|
try {
|
|
4611
|
-
const absPath =
|
|
4979
|
+
const absPath = resolveReadablePathInsideContext(filePath);
|
|
4612
4980
|
if (isDirectoryPath(absPath)) {
|
|
4613
4981
|
const extension = inferExtensionFromDirectory(absPath);
|
|
4614
4982
|
if (!extension) {
|
|
@@ -4637,7 +5005,7 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
4637
5005
|
};
|
|
4638
5006
|
return text(output2.output, details2);
|
|
4639
5007
|
}
|
|
4640
|
-
const result = await withLspClient(filePath, async (client) => client.diagnostics(
|
|
5008
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.diagnostics(resolvedFilePath, signal), "diagnostics", clientOptions(signal));
|
|
4641
5009
|
if (result.transientError) {
|
|
4642
5010
|
const message = result.transientError.message;
|
|
4643
5011
|
const details2 = {
|
|
@@ -4684,6 +5052,96 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
4684
5052
|
throw error;
|
|
4685
5053
|
}
|
|
4686
5054
|
}
|
|
5055
|
+
// ../lsp-core/src/lsp/format-document.ts
|
|
5056
|
+
import { readFileSync as readFileSync5, renameSync as renameSync3, unlinkSync, writeFileSync as writeFileSync3 } from "node:fs";
|
|
5057
|
+
var DEFAULT_FORMATTING_OPTIONS = {
|
|
5058
|
+
tabSize: 4,
|
|
5059
|
+
insertSpaces: false,
|
|
5060
|
+
trimTrailingWhitespace: true,
|
|
5061
|
+
insertFinalNewline: true,
|
|
5062
|
+
trimFinalNewlines: true
|
|
5063
|
+
};
|
|
5064
|
+
var UNCHANGED = { status: "unchanged", linesAdded: 0, linesRemoved: 0 };
|
|
5065
|
+
async function formatDocumentWithClient(client, filePath, options = {}) {
|
|
5066
|
+
const edits = await client.formatDocument(filePath, options.formattingOptions ?? DEFAULT_FORMATTING_OPTIONS, options.signal);
|
|
5067
|
+
if (edits === null)
|
|
5068
|
+
return { status: "unavailable", reason: "capability_not_advertised" };
|
|
5069
|
+
if (edits.length === 0)
|
|
5070
|
+
return UNCHANGED;
|
|
5071
|
+
const before = readFileSync5(filePath, "utf-8");
|
|
5072
|
+
const normalized = normalizeTextEdits(before, edits, 0);
|
|
5073
|
+
if (normalized.text === before)
|
|
5074
|
+
return UNCHANGED;
|
|
5075
|
+
writeAtomically(filePath, normalized.text);
|
|
5076
|
+
await client.openFile(filePath);
|
|
5077
|
+
return {
|
|
5078
|
+
status: "formatted",
|
|
5079
|
+
...lineDelta(normalized.edits)
|
|
5080
|
+
};
|
|
5081
|
+
}
|
|
5082
|
+
function lineDelta(edits) {
|
|
5083
|
+
let linesAdded = 0;
|
|
5084
|
+
let linesRemoved = 0;
|
|
5085
|
+
for (const edit of edits) {
|
|
5086
|
+
linesRemoved += edit.range.end.line - edit.range.start.line + 1;
|
|
5087
|
+
linesAdded += edit.newText.split(`
|
|
5088
|
+
`).length;
|
|
5089
|
+
}
|
|
5090
|
+
return { linesAdded, linesRemoved };
|
|
5091
|
+
}
|
|
5092
|
+
function writeAtomically(filePath, content) {
|
|
5093
|
+
const tempPath = `${filePath}.omo-format.tmp`;
|
|
5094
|
+
writeFileSync3(tempPath, content, "utf-8");
|
|
5095
|
+
try {
|
|
5096
|
+
renameSync3(tempPath, filePath);
|
|
5097
|
+
} catch (error) {
|
|
5098
|
+
try {
|
|
5099
|
+
unlinkSync(tempPath);
|
|
5100
|
+
} catch {}
|
|
5101
|
+
throw error;
|
|
5102
|
+
}
|
|
5103
|
+
}
|
|
5104
|
+
|
|
5105
|
+
// ../lsp-core/src/tools/format.ts
|
|
5106
|
+
async function executeLspFormat(params, signal) {
|
|
5107
|
+
const filePath = requireString(params, "filePath");
|
|
5108
|
+
try {
|
|
5109
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => formatDocumentWithClient(client, resolvedFilePath, signal === undefined ? {} : { signal }), "format", clientOptions(signal));
|
|
5110
|
+
return text(describeResult(filePath, result), formatDetails(filePath, result));
|
|
5111
|
+
} catch (error) {
|
|
5112
|
+
const missingDependency = missingDependencyResult(error, {
|
|
5113
|
+
filePath,
|
|
5114
|
+
status: "unavailable",
|
|
5115
|
+
reason: "server_unavailable",
|
|
5116
|
+
linesAdded: 0,
|
|
5117
|
+
linesRemoved: 0
|
|
5118
|
+
});
|
|
5119
|
+
if (missingDependency)
|
|
5120
|
+
return missingDependency;
|
|
5121
|
+
throw error;
|
|
5122
|
+
}
|
|
5123
|
+
}
|
|
5124
|
+
function formatDetails(filePath, result) {
|
|
5125
|
+
if (result.status === "unavailable") {
|
|
5126
|
+
return { filePath, status: "unavailable", reason: result.reason, linesAdded: 0, linesRemoved: 0 };
|
|
5127
|
+
}
|
|
5128
|
+
return {
|
|
5129
|
+
filePath,
|
|
5130
|
+
status: result.status,
|
|
5131
|
+
linesAdded: result.linesAdded,
|
|
5132
|
+
linesRemoved: result.linesRemoved
|
|
5133
|
+
};
|
|
5134
|
+
}
|
|
5135
|
+
function describeResult(filePath, result) {
|
|
5136
|
+
if (result.status === "unavailable") {
|
|
5137
|
+
return `Formatting unavailable for ${filePath}: the language server does not advertise documentFormattingProvider.`;
|
|
5138
|
+
}
|
|
5139
|
+
if (result.status === "unchanged") {
|
|
5140
|
+
return `Already formatted: ${filePath}`;
|
|
5141
|
+
}
|
|
5142
|
+
return `Formatted ${filePath} (+${result.linesAdded}/-${result.linesRemoved} lines)`;
|
|
5143
|
+
}
|
|
5144
|
+
|
|
4687
5145
|
// ../lsp-core/src/tools/install-decision.ts
|
|
4688
5146
|
async function executeLspInstallDecision(params) {
|
|
4689
5147
|
const serverId = requireString(params, "server_id");
|
|
@@ -4712,7 +5170,7 @@ async function executeLspGotoDefinition(params, signal) {
|
|
|
4712
5170
|
const line = requireNumber(params, "line");
|
|
4713
5171
|
const character = requireNumber(params, "character");
|
|
4714
5172
|
try {
|
|
4715
|
-
const result = await withLspClient(filePath, async (client) => client.definition(
|
|
5173
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.definition(resolvedFilePath, line, character, signal), "definition", clientOptions(signal));
|
|
4716
5174
|
const locations = !result ? [] : Array.isArray(result) ? result : [result];
|
|
4717
5175
|
const details = { filePath, line, character, locations };
|
|
4718
5176
|
if (locations.length === 0)
|
|
@@ -4737,7 +5195,7 @@ async function executeLspFindReferences(params, signal) {
|
|
|
4737
5195
|
const character = requireNumber(params, "character");
|
|
4738
5196
|
const includeDeclaration = optionalBoolean(params, "includeDeclaration") ?? true;
|
|
4739
5197
|
try {
|
|
4740
|
-
const result = await withLspClient(filePath, async (client) => client.references(
|
|
5198
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.references(resolvedFilePath, line, character, includeDeclaration, signal), "references", clientOptions(signal));
|
|
4741
5199
|
const references = Array.isArray(result) ? result : [];
|
|
4742
5200
|
const total = references.length;
|
|
4743
5201
|
const truncated = total > DEFAULT_MAX_REFERENCES;
|
|
@@ -4779,7 +5237,7 @@ async function executeLspPrepareRename(params, signal) {
|
|
|
4779
5237
|
const line = requireNumber(params, "line");
|
|
4780
5238
|
const character = requireNumber(params, "character");
|
|
4781
5239
|
try {
|
|
4782
|
-
const result = await withLspClient(filePath, async (client) => client.prepareRename(
|
|
5240
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.prepareRename(resolvedFilePath, line, character, signal), "prepareRename", clientOptions(signal));
|
|
4783
5241
|
const details = { filePath, line, character, result };
|
|
4784
5242
|
return text(formatPrepareRenameResult(result), details);
|
|
4785
5243
|
} catch (error) {
|
|
@@ -4800,7 +5258,7 @@ async function executeLspRename(params, signal) {
|
|
|
4800
5258
|
const character = requireNumber(params, "character");
|
|
4801
5259
|
const newName = requireString(params, "newName");
|
|
4802
5260
|
try {
|
|
4803
|
-
const result = await withLspClient(filePath, async (client) => client.rename(
|
|
5261
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.rename(resolvedFilePath, line, character, newName, signal), "rename", clientOptions(signal));
|
|
4804
5262
|
const details = { filePath, line, character, newName, apply: result.apply, edit: result.edit };
|
|
4805
5263
|
return text(formatApplyResult(result.apply), details, !result.apply.success);
|
|
4806
5264
|
} catch (error) {
|
|
@@ -4880,7 +5338,7 @@ async function executeLspSymbols(params, signal) {
|
|
|
4880
5338
|
const symbols2 = await withLspClient(filePath, async (client) => client.workspaceSymbols(query, signal), "workspaceSymbols", clientOptions(signal));
|
|
4881
5339
|
return formatSymbolsResult(filePath, scope, symbols2, limit, query);
|
|
4882
5340
|
}
|
|
4883
|
-
const symbols = await withLspClient(filePath, async (client) => client.documentSymbols(
|
|
5341
|
+
const symbols = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.documentSymbols(resolvedFilePath, signal), "documentSymbols", clientOptions(signal));
|
|
4884
5342
|
return formatSymbolsResult(filePath, scope, symbols, limit);
|
|
4885
5343
|
} catch (error) {
|
|
4886
5344
|
const query = optionalString(params, "query");
|
|
@@ -5016,6 +5474,16 @@ var LSP_MCP_TOOLS = [
|
|
|
5016
5474
|
}, ["filePath", "line", "character", "newName"]),
|
|
5017
5475
|
execute: executeLspRename
|
|
5018
5476
|
},
|
|
5477
|
+
{
|
|
5478
|
+
name: "format",
|
|
5479
|
+
aliases: ["lsp_format"],
|
|
5480
|
+
title: "LSP Format",
|
|
5481
|
+
description: "Format a source file with its language server and write the returned edits to disk.",
|
|
5482
|
+
inputSchema: objectSchema({
|
|
5483
|
+
filePath: { type: "string", description: "Source file path to format." }
|
|
5484
|
+
}, ["filePath"]),
|
|
5485
|
+
execute: executeLspFormat
|
|
5486
|
+
},
|
|
5019
5487
|
{
|
|
5020
5488
|
name: "install_decision",
|
|
5021
5489
|
aliases: ["lsp_install_decision"],
|