oh-my-opencode 5.0.0-beta.4 → 5.0.0-beta.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/command/publish.md +44 -16
- package/.agents/skills/codex-qa/scripts/lsp-e2e.sh +1 -3
- package/.agents/skills/opencode-qa/scripts/lsp-e2e.sh +1 -1
- package/.agents/skills/pre-publish-review/SKILL.md +9 -12
- package/.agents/skills/publish/SKILL.md +44 -16
- package/.agents/skills/senpi-qa/SKILL.md +80 -0
- package/.agents/skills/senpi-qa/scripts/resolve-evidence-dir.mjs +65 -0
- package/.agents/skills/senpi-qa/scripts/resolve-evidence-dir.test.mjs +171 -0
- package/.agents/skills/tech-debt-audit/SKILL.md +6 -76
- package/.agents/skills/work-with-pr/SKILL.md +37 -23
- package/.opencode/command/publish.md +44 -16
- package/.opencode/skills/pre-publish-review/SKILL.md +9 -12
- package/.opencode/skills/work-with-pr/SKILL.md +37 -23
- package/README.ja.md +25 -21
- package/README.ko.md +25 -21
- package/README.md +38 -23
- package/README.ru.md +24 -20
- package/README.zh-cn.md +25 -21
- package/THIRD-PARTY-NOTICES.md +27 -99
- package/dist/agents/atlas/agent.d.ts +0 -1
- package/dist/agents/sisyphus/grok-4.d.ts +20 -0
- package/dist/agents/sisyphus/index.d.ts +2 -0
- package/dist/agents/sisyphus-agent-config.d.ts +6 -0
- package/dist/agents/sisyphus-agent-factory.d.ts +1 -1
- package/dist/agents/sisyphus-runtime-prompt-reconciler.d.ts +15 -4
- package/dist/agents/types.d.ts +2 -2
- package/dist/cli/config-manager/parse-opencode-config-file.d.ts +2 -1
- package/dist/cli/doctor/checks/system-plugin.d.ts +4 -3
- package/dist/cli/fallback-lane-policy.d.ts +1 -0
- package/dist/cli/index.js +67006 -64814
- 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 +67283 -65068
- package/dist/config/index.d.ts +1 -1
- package/dist/config/schema/background-task.d.ts +1 -0
- package/dist/config/schema/commands.d.ts +1 -1
- package/dist/config/schema/hooks.d.ts +1 -2
- package/dist/config/schema/oh-my-opencode-config.d.ts +5 -11
- package/dist/config/schema/ulw-execute.d.ts +5 -0
- package/dist/config/schema.d.ts +0 -1
- package/dist/config/validate.d.ts +2 -0
- package/dist/create-hooks.d.ts +3 -2
- package/dist/features/background-agent/compaction-aware-message-resolver.d.ts +1 -0
- package/dist/features/background-agent/constants.d.ts +0 -7
- package/dist/features/background-agent/manager.d.ts +2 -1
- package/dist/features/background-agent/parent-wake-dispatched-tracker.d.ts +0 -1
- package/dist/features/background-agent/parent-wake-notifier-types.d.ts +1 -1
- package/dist/features/background-agent/parent-wake-prompt-dispatch.d.ts +1 -1
- package/dist/features/background-agent/parent-wake-session-inspector.d.ts +1 -1
- package/dist/features/background-agent/subagent-spawn-limits.d.ts +8 -0
- package/dist/features/btw-side/btw-command-draft.d.ts +7 -0
- package/dist/features/btw-side/context-injector.d.ts +15 -0
- package/dist/features/btw-side/index.d.ts +8 -0
- package/dist/features/btw-side/metadata.d.ts +15 -0
- package/dist/features/btw-side/parent-context-budget.d.ts +9 -0
- package/dist/features/btw-side/server-session-registry.d.ts +8 -0
- package/dist/features/btw-side/tui-adoption-cache.d.ts +13 -0
- package/dist/features/btw-side/tui-adoption-guard.d.ts +5 -0
- package/dist/features/btw-side/tui-controller-types.d.ts +68 -0
- package/dist/features/btw-side/tui-controller.d.ts +19 -0
- package/dist/features/btw-side/tui-escape-return.d.ts +12 -0
- package/dist/features/btw-side/tui-keymap.d.ts +17 -0
- package/dist/features/btw-side/tui-parent-validator.d.ts +6 -0
- package/dist/features/btw-side/tui-picker-options.d.ts +20 -0
- package/dist/features/btw-side/tui-picker.d.ts +9 -0
- package/dist/features/btw-side/tui-prompt-queue.d.ts +8 -0
- package/dist/features/btw-side/tui-session-bridge.d.ts +11 -0
- package/dist/features/btw-side/tui-session-catalog.d.ts +35 -0
- package/dist/features/btw-side/tui-side-removal.d.ts +11 -0
- package/dist/features/btw-side/tui-side-start.d.ts +9 -0
- package/dist/features/btw-side/tui-wiring.d.ts +8 -0
- package/dist/features/builtin-commands/templates/ulw-execute.d.ts +1 -0
- package/dist/features/builtin-commands/types.d.ts +1 -1
- package/dist/features/monitor/manager-internals.d.ts +1 -1
- package/dist/features/monitor/output-injector-types.d.ts +1 -1
- package/dist/features/opengateway-provider/index.d.ts +13 -0
- package/dist/features/task-toast-manager/manager.d.ts +0 -24
- package/dist/features/team-mode/tools/messaging-fallback-wake.d.ts +15 -0
- package/dist/features/team-mode/tools/messaging-live-delivery-recipient.d.ts +1 -0
- package/dist/features/team-mode/tools/messaging-runtime.d.ts +1 -0
- package/dist/hooks/anthropic-context-window-limit-recovery/message-storage-directory.d.ts +0 -3
- package/dist/hooks/anthropic-context-window-limit-recovery/state.d.ts +1 -0
- package/dist/hooks/anthropic-context-window-limit-recovery/storage/empty-messages.d.ts +0 -1
- package/dist/hooks/anthropic-context-window-limit-recovery/tool-result-storage.d.ts +11 -0
- package/dist/hooks/atlas/atlas-hook.d.ts +1 -0
- package/dist/hooks/atlas/atlas-lifecycle-store.d.ts +50 -0
- package/dist/hooks/atlas/event-handler.d.ts +1 -0
- package/dist/hooks/atlas/final-wave-approval-gate.test-support.d.ts +50 -0
- package/dist/hooks/atlas/system-reminder-templates.d.ts +0 -1
- package/dist/hooks/atlas/tool-execute-before.d.ts +3 -0
- package/dist/hooks/atlas/types.d.ts +1 -0
- package/dist/hooks/claude-code-hooks/session-hook-state.d.ts +1 -0
- package/dist/hooks/claude-code-hooks/stop.d.ts +2 -0
- package/dist/hooks/claude-code-hooks/todo.d.ts +0 -1
- package/dist/hooks/claude-code-hooks/transcript.d.ts +2 -0
- package/dist/hooks/compaction-context-injector/validated-model.d.ts +2 -0
- package/dist/hooks/fsync-skip-warning/index.d.ts +4 -0
- package/dist/hooks/hashline-edit-diff-enhancer/hook.d.ts +1 -0
- package/dist/hooks/hashline-edit-diff-enhancer/pending-captures.d.ts +13 -0
- package/dist/hooks/index.d.ts +1 -2
- package/dist/hooks/keyword-detector/hook.d.ts +7 -0
- package/dist/hooks/keyword-detector/ultrawork/source-detector.d.ts +0 -1
- package/dist/hooks/model-fallback/hook.d.ts +1 -1
- package/dist/hooks/prometheus-md-only/agent-resolution.d.ts +2 -2
- package/dist/hooks/runtime-fallback/chat-message-handler.d.ts +2 -0
- package/dist/hooks/runtime-fallback/retry-model-payload.d.ts +1 -0
- package/dist/hooks/runtime-fallback/runtime-model-settings.d.ts +6 -0
- package/dist/hooks/runtime-fallback/session-status-handler.d.ts +1 -1
- package/dist/hooks/runtime-fallback/types.d.ts +3 -1
- package/dist/hooks/sisyphus-junior-notepad/constants.d.ts +1 -1
- package/dist/hooks/todo-continuation-enforcer/types.d.ts +1 -0
- package/dist/hooks/{start-work → ulw-execute}/context-info-builder.d.ts +1 -1
- package/dist/hooks/{start-work → ulw-execute}/index.d.ts +1 -1
- package/dist/hooks/ulw-execute/ulw-execute-hook.d.ts +23 -0
- package/dist/index.js +24677 -20710
- package/dist/mcp/index.d.ts +0 -4
- package/dist/mcp/types.d.ts +0 -1
- package/dist/oh-my-opencode.schema.json +21 -47
- package/dist/plugin/chat-message/types.d.ts +3 -3
- package/dist/plugin/chat-message/ulw-execute-message.d.ts +5 -0
- package/dist/plugin/event-session-lifecycle.d.ts +1 -0
- package/dist/plugin/hooks/create-core-hooks.d.ts +2 -2
- package/dist/plugin/hooks/create-session-hooks.d.ts +2 -3
- package/dist/plugin/hooks/create-transform-hooks.d.ts +2 -0
- package/dist/plugin/messages-transform.d.ts +1 -0
- package/dist/plugin-dispose.d.ts +3 -0
- package/dist/shared/agent-tool-restrictions.d.ts +0 -1
- package/dist/shared/compaction-agent-config-checkpoint.d.ts +1 -0
- package/dist/shared/index.d.ts +2 -0
- package/dist/shared/legacy-plugin-warning.d.ts +2 -1
- package/dist/shared/normalize-sdk-response.d.ts +1 -0
- package/dist/shared/omo-process-sweep.d.ts +2 -4
- package/dist/shared/plugin-entry-migrator.d.ts +4 -3
- package/dist/shared/plugin-entry-shape.d.ts +6 -0
- package/dist/shared/runtime-fallback-retry-marker.d.ts +16 -0
- package/dist/shared/shell-env.d.ts +1 -1
- package/dist/skills/ast-grep/AGENTS.md +51 -0
- package/dist/skills/ast-grep/SKILL.md +1 -1
- package/dist/skills/coding-agent-sessions/AGENTS.md +62 -0
- package/dist/skills/coding-agent-sessions/SKILL.md +3 -2
- package/dist/skills/coding-agent-sessions/references/all-platforms.md +1 -1
- package/dist/skills/coding-agent-sessions/references/senpi.md +4 -4
- package/dist/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +1 -1
- package/dist/skills/data-scientist/SKILL.md +99 -239
- package/dist/skills/data-scientist/references/execution-surfaces.md +91 -0
- package/dist/skills/data-scientist/references/placement.md +74 -0
- package/dist/skills/data-scientist/references/polars-lane.md +95 -0
- package/dist/skills/data-scientist/references/uv-setup.md +1 -1
- package/dist/skills/data-scientist/references/visualization.md +64 -0
- package/dist/skills/data-scientist/scripts/ensure-js-deps.sh +28 -0
- package/dist/skills/data-scientist/scripts/ensure-py-deps.sh +37 -0
- package/dist/skills/debugging/SKILL.md +3 -1
- package/dist/skills/debugging/references/methodology/00-setup.md +12 -0
- package/dist/skills/debugging/references/methodology/02-investigate.md +21 -0
- package/dist/skills/debugging/references/runtimes/go.md +15 -1
- package/dist/skills/debugging/references/runtimes/native-binary.md +38 -0
- package/dist/skills/debugging/references/runtimes/node.md +25 -0
- package/dist/skills/debugging/references/runtimes/python.md +13 -0
- package/dist/skills/debugging/references/runtimes/rust.md +41 -0
- package/dist/skills/debugging/references/scripts/dap.mjs +267 -0
- package/dist/skills/debugging/references/scripts/dap.test.ts +86 -0
- package/dist/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
- package/dist/skills/debugging/references/tools/dap.md +103 -0
- package/dist/skills/debugging/references/tools/frida.md +193 -0
- package/dist/skills/frontend/SKILL.md +12 -8
- package/dist/skills/frontend/references/design/_INDEX.md +1 -0
- package/dist/skills/frontend/references/design/print-paged-media.md +76 -0
- package/dist/skills/frontend/references/design/stylegallery.md +80 -0
- package/dist/skills/frontend/references/designpowers/README.md +1 -1
- package/dist/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
- package/dist/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
- package/dist/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
- package/dist/skills/frontend/references/designpowers/orchestration.md +1 -1
- package/dist/skills/frontend/references/designpowers/routing.md +5 -5
- package/dist/skills/git-master/SKILL.md +1 -1
- package/dist/skills/init-deep/SKILL.md +14 -14
- package/dist/skills/lsp-setup/SKILL.md +1 -1
- package/dist/skills/programming/SKILL.md +1 -1
- package/dist/skills/refactor/SKILL.md +1 -1
- package/dist/skills/remove-ai-slops/SKILL.md +1 -1
- package/dist/skills/review-work/SKILL.md +100 -418
- package/dist/skills/ultimate-browsing/ATTRIBUTION.md +38 -11
- package/dist/skills/ultimate-browsing/SKILL.md +26 -9
- package/dist/skills/ultimate-browsing/engine/AGENTS.md +110 -0
- package/dist/skills/ultimate-browsing/engine/templates/package.json +1 -1
- package/dist/skills/ultimate-browsing/references/chrome-stealth.md +23 -18
- package/dist/skills/ultimate-browsing/references/insane-search/README.md +9 -2
- package/dist/skills/{start-work → ulw-execute}/SKILL.md +17 -16
- package/dist/skills/ulw-plan/SKILL.md +7 -8
- package/dist/skills/ulw-plan/references/full-workflow.md +31 -7
- package/dist/skills/ulw-plan/references/intent-clear.md +2 -1
- package/dist/skills/ulw-plan/references/intent-unclear.md +5 -5
- package/dist/skills/ulw-research/SKILL.md +8 -3
- package/dist/skills/visual-qa/AGENTS.md +58 -0
- package/dist/skills/visual-qa/SKILL.md +4 -3
- package/dist/tools/delegate-task/builtin-categories.d.ts +1 -0
- package/dist/tools/delegate-task/builtin-category-definition.d.ts +1 -0
- package/dist/tools/delegate-task/sync-session-cleanup.d.ts +3 -0
- package/dist/tools/delegate-task/sync-session-poller.d.ts +1 -0
- package/dist/tools/delegate-task/tool-description.d.ts +3 -1
- package/dist/tools/delegate-task/types.d.ts +4 -0
- package/dist/tools/session-manager/directory-filter.d.ts +2 -0
- package/dist/tui.d.ts +12 -0
- package/dist/tui.js +49320 -49316
- package/package.json +44 -39
- package/packages/git-bash-mcp/dist/cli.js +6 -1
- package/packages/git-bash-mcp/package.json +1 -1
- package/packages/lsp-core/src/index.ts +1 -0
- package/packages/lsp-core/src/lsp/client-diagnostics-concurrency.integration.test.ts +44 -0
- package/packages/lsp-core/src/lsp/client-diagnostics-freshness.integration.test.ts +47 -47
- package/packages/lsp-core/src/lsp/client-diagnostics-pull-timeout.test.ts +64 -0
- package/packages/lsp-core/src/lsp/client-wrapper-outside-cwd.test.ts +78 -0
- package/packages/lsp-core/src/lsp/client-wrapper.test.ts +163 -13
- package/packages/lsp-core/src/lsp/client-wrapper.ts +110 -23
- package/packages/lsp-core/src/lsp/client.ts +32 -3
- package/packages/lsp-core/src/lsp/connection.ts +16 -0
- package/packages/lsp-core/src/lsp/constants.ts +6 -0
- package/packages/lsp-core/src/lsp/controlled-clock-test-support.ts +61 -0
- package/packages/lsp-core/src/lsp/errors.ts +15 -0
- package/packages/lsp-core/src/lsp/fixtures/workspace-edit-server.mjs +10 -3
- package/packages/lsp-core/src/lsp/format-document.test.ts +143 -0
- package/packages/lsp-core/src/lsp/format-document.ts +90 -0
- package/packages/lsp-core/src/lsp/json-rpc-connection.ts +11 -6
- package/packages/lsp-core/src/lsp/manager-lifecycle.test.ts +262 -0
- package/packages/lsp-core/src/lsp/manager-max-clients.test.ts +151 -0
- package/packages/lsp-core/src/lsp/manager.ts +138 -12
- package/packages/lsp-core/src/lsp/outside-context-workspace.ts +33 -0
- package/packages/lsp-core/src/lsp/server-definitions.ts +29 -0
- package/packages/lsp-core/src/lsp/server-installation.test.ts +376 -0
- package/packages/lsp-core/src/lsp/server-installation.ts +200 -27
- package/packages/lsp-core/src/lsp/server-resolution-local-binary.test.ts +170 -0
- package/packages/lsp-core/src/lsp/server-resolution.ts +18 -5
- package/packages/lsp-core/src/lsp/timer-provider.ts +13 -0
- package/packages/lsp-core/src/lsp/transport-request-timeout.test.ts +73 -0
- package/packages/lsp-core/src/lsp/transport.ts +16 -2
- package/packages/lsp-core/src/lsp/types.ts +8 -0
- package/packages/lsp-core/src/lsp/workspace-document-state.test.ts +84 -1
- package/packages/lsp-core/src/lsp/workspace-document-state.ts +30 -11
- package/packages/lsp-core/src/lsp/workspace-edit-adversarial.test.ts +20 -1
- package/packages/lsp-core/src/lsp/workspace-markers.ts +18 -0
- package/packages/lsp-core/src/mcp.ts +3 -0
- package/packages/lsp-core/src/request-context.test.ts +29 -0
- package/packages/lsp-core/src/request-context.ts +1 -1
- package/packages/lsp-core/src/tool-surface.test.ts +13 -1
- package/packages/lsp-core/src/tools/definitions.ts +14 -0
- package/packages/lsp-core/src/tools/diagnostics.ts +3 -3
- package/packages/lsp-core/src/tools/format.test.ts +56 -0
- package/packages/lsp-core/src/tools/format.ts +56 -0
- package/packages/lsp-core/src/tools/index.ts +1 -0
- package/packages/lsp-core/src/tools/navigation.ts +4 -2
- package/packages/lsp-core/src/tools/parameters.test.ts +51 -0
- package/packages/lsp-core/src/tools/rename.ts +4 -2
- package/packages/lsp-core/src/tools/symbols.ts +1 -1
- package/packages/lsp-core/src/tools/types.ts +10 -0
- package/packages/lsp-daemon/dist/cli.js +804 -329
- package/packages/lsp-daemon/dist/client.d.ts +10 -0
- package/packages/lsp-daemon/dist/client.js +764 -286
- 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 +768 -295
- 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 +723 -250
- package/packages/lsp-tools-mcp/dist/lsp/manager.js +259 -125
- package/packages/lsp-tools-mcp/dist/mcp.js +725 -252
- package/packages/lsp-tools-mcp/dist/request-context.js +12 -13
- package/packages/lsp-tools-mcp/dist/tools.js +729 -260
- package/packages/lsp-tools-mcp/package.json +1 -1
- package/packages/omo-codex/THIRD-PARTY-NOTICES.md +4 -21
- 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 +752 -300
- 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 +4 -3
- 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 +42 -31
- 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/ast-grep/SKILL.md +1 -1
- 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 +3 -1
- 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 +12 -8
- 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/git-master/SKILL.md +1 -1
- package/packages/omo-codex/plugin/skills/init-deep/SKILL.md +14 -14
- package/packages/omo-codex/plugin/skills/lcx-doctor/SKILL.md +1 -1
- package/packages/omo-codex/plugin/skills/lsp-setup/SKILL.md +1 -1
- package/packages/omo-codex/plugin/skills/programming/SKILL.md +1 -1
- package/packages/omo-codex/plugin/skills/refactor/SKILL.md +1 -1
- package/packages/omo-codex/plugin/skills/remove-ai-slops/SKILL.md +1 -1
- package/packages/omo-codex/plugin/skills/review-work/SKILL.md +101 -419
- package/packages/omo-codex/plugin/skills/ultimate-browsing/ATTRIBUTION.md +38 -11
- package/packages/omo-codex/plugin/skills/ultimate-browsing/SKILL.md +26 -9
- 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 +23 -18
- 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 +4 -3
- 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 +8 -3
- package/packages/omo-codex/plugin/skills/visual-qa/AGENTS.md +58 -0
- package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +4 -3
- 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 +24 -14
- 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/AGENTS.md +36 -0
- package/packages/omo-codex/scripts/install-cache-copy.test.mjs +27 -1
- package/packages/omo-codex/scripts/install-config-autonomous-features.test.mjs +1 -1
- package/packages/omo-codex/scripts/install-config-autonomous.test.mjs +2 -1
- package/packages/omo-codex/scripts/install-config-git-bash.test.mjs +0 -23
- package/packages/omo-codex/scripts/install-config-reasoning.test.mjs +2 -2
- package/packages/omo-codex/scripts/install-dist/install-local.mjs +2818 -913
- package/packages/omo-codex/scripts/install-git-bash-mcp-env.test.mjs +1 -25
- package/packages/omo-codex/scripts/install-lazycodex-version-stamp.test.mjs +7 -2
- package/packages/omo-codex/scripts/install-mcp-runtime.test.mjs +0 -36
- package/packages/shared-skills/package.json +7 -1
- package/packages/shared-skills/skill-source-filter.d.ts +16 -0
- package/packages/shared-skills/skill-source-filter.mjs +44 -0
- package/packages/shared-skills/skills/ast-grep/AGENTS.md +51 -0
- package/packages/shared-skills/skills/ast-grep/SKILL.md +1 -1
- 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 +3 -1
- 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 +12 -8
- 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/git-master/SKILL.md +1 -1
- package/packages/shared-skills/skills/init-deep/SKILL.md +14 -14
- package/packages/shared-skills/skills/lsp-setup/SKILL.md +1 -1
- package/packages/shared-skills/skills/programming/SKILL.md +1 -1
- package/packages/shared-skills/skills/refactor/SKILL.md +1 -1
- package/packages/shared-skills/skills/remove-ai-slops/SKILL.md +1 -1
- package/packages/shared-skills/skills/review-work/SKILL.md +100 -418
- package/packages/shared-skills/skills/ultimate-browsing/ATTRIBUTION.md +38 -11
- package/packages/shared-skills/skills/ultimate-browsing/SKILL.md +26 -9
- 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 +23 -18
- 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 +7 -8
- 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 +8 -3
- package/packages/shared-skills/skills/visual-qa/AGENTS.md +58 -0
- package/packages/shared-skills/skills/visual-qa/SKILL.md +4 -3
- package/script/qa/web-terminal-visual-qa.mjs +2 -0
- package/script/qa/xterm-live-terminal.mjs +18 -2
- package/dist/config/schema/codegraph.d.ts +0 -12
- package/dist/config/schema/start-work.d.ts +0 -5
- package/dist/features/builtin-commands/templates/start-work.d.ts +0 -1
- package/dist/features/builtin-skills/index.d.ts +0 -1
- package/dist/features/builtin-skills/skill-file-loader.d.ts +0 -1
- package/dist/features/builtin-skills/skills/agent-browser-skill.d.ts +0 -1
- package/dist/features/builtin-skills/skills/agent-browser-template.d.ts +0 -1
- package/dist/features/builtin-skills/skills/debugging.d.ts +0 -1
- package/dist/features/builtin-skills/skills/dev-browser.d.ts +0 -1
- package/dist/features/builtin-skills/skills/frontend.d.ts +0 -1
- package/dist/features/builtin-skills/skills/git-master-sections/commit-atomic-planning.d.ts +0 -1
- package/dist/features/builtin-skills/skills/git-master-sections/commit-context-analysis.d.ts +0 -1
- package/dist/features/builtin-skills/skills/git-master-sections/commit-execution-verification.d.ts +0 -1
- package/dist/features/builtin-skills/skills/git-master-sections/commit-workflow.d.ts +0 -1
- package/dist/features/builtin-skills/skills/git-master-sections/history-search-workflow.d.ts +0 -1
- package/dist/features/builtin-skills/skills/git-master-sections/overview.d.ts +0 -1
- package/dist/features/builtin-skills/skills/git-master-sections/quick-reference.d.ts +0 -1
- package/dist/features/builtin-skills/skills/git-master-sections/rebase-workflow.d.ts +0 -1
- package/dist/features/builtin-skills/skills/git-master-skill-metadata.d.ts +0 -1
- package/dist/features/builtin-skills/skills/git-master.d.ts +0 -1
- package/dist/features/builtin-skills/skills/index.d.ts +0 -1
- package/dist/features/builtin-skills/skills/init-deep.d.ts +0 -1
- package/dist/features/builtin-skills/skills/playwright-cli.d.ts +0 -1
- package/dist/features/builtin-skills/skills/playwright-mcp-skill.d.ts +0 -1
- package/dist/features/builtin-skills/skills/playwright.d.ts +0 -1
- package/dist/features/builtin-skills/skills/remove-ai-slops.d.ts +0 -1
- package/dist/features/builtin-skills/skills/review-work.d.ts +0 -1
- package/dist/features/builtin-skills/skills/security-research.d.ts +0 -1
- package/dist/features/builtin-skills/skills/security-review.d.ts +0 -1
- package/dist/features/builtin-skills/skills/team-mode.d.ts +0 -1
- package/dist/features/builtin-skills/skills/visual-qa.d.ts +0 -1
- package/dist/features/builtin-skills/skills.d.ts +0 -1
- package/dist/features/builtin-skills/types.d.ts +0 -1
- package/dist/features/claude-code-plugin-loader/agent-loader.d.ts +0 -1
- package/dist/features/claude-code-plugin-loader/command-loader.d.ts +0 -1
- package/dist/features/claude-code-plugin-loader/discovery-core.d.ts +0 -1
- package/dist/features/claude-code-plugin-loader/discovery-paths.d.ts +0 -1
- package/dist/features/claude-code-plugin-loader/discovery.d.ts +0 -1
- package/dist/features/claude-code-plugin-loader/hook-loader.d.ts +0 -1
- package/dist/features/claude-code-plugin-loader/index.d.ts +0 -1
- package/dist/features/claude-code-plugin-loader/install-path-resolver.d.ts +0 -1
- package/dist/features/claude-code-plugin-loader/installed-plugin-database.d.ts +0 -1
- package/dist/features/claude-code-plugin-loader/loaded-plugin.d.ts +0 -1
- package/dist/features/claude-code-plugin-loader/loader.d.ts +0 -1
- package/dist/features/claude-code-plugin-loader/mcp-server-loader.d.ts +0 -1
- package/dist/features/claude-code-plugin-loader/plugin-key.d.ts +0 -1
- package/dist/features/claude-code-plugin-loader/plugin-manifest.d.ts +0 -1
- package/dist/features/claude-code-plugin-loader/plugin-path-resolver.d.ts +0 -1
- package/dist/features/claude-code-plugin-loader/plugin-settings.d.ts +0 -1
- package/dist/features/claude-code-plugin-loader/scope-filter.d.ts +0 -1
- package/dist/features/claude-code-plugin-loader/skill-loader.d.ts +0 -1
- package/dist/features/claude-code-plugin-loader/types.d.ts +0 -1
- package/dist/hooks/codegraph-bootstrap/command-runner.d.ts +0 -17
- package/dist/hooks/codegraph-bootstrap/hook.d.ts +0 -35
- package/dist/hooks/codegraph-bootstrap/index.d.ts +0 -1
- package/dist/hooks/codegraph-bootstrap/project-root.d.ts +0 -1
- package/dist/hooks/codegraph-bootstrap/status.d.ts +0 -11
- package/dist/hooks/ralph-loop/completion-promise-detector-test-input.d.ts +0 -11
- package/dist/hooks/ralph-loop/loop-session-recovery.d.ts +0 -7
- package/dist/hooks/start-work/start-work-hook.d.ts +0 -23
- package/dist/mcp/codegraph.d.ts +0 -16
- package/dist/plugin/chat-message/start-work-message.d.ts +0 -5
- package/dist/shared/prompt-async-gate/message-inspection-error.d.ts +0 -1
- package/dist/shared/prompt-async-gate/pending-tool-turn.d.ts +0 -1
- package/dist/shared/prompt-async-gate/prompt-message-state.d.ts +0 -1
- package/dist/shared/prompt-async-gate/queue.d.ts +0 -1
- package/dist/shared/prompt-async-gate/recent-dispatches.d.ts +0 -1
- package/dist/shared/prompt-async-gate/reservations.d.ts +0 -1
- package/dist/shared/prompt-async-gate/semantic-dedupe.d.ts +0 -1
- package/dist/shared/prompt-async-gate/session-idle-dispatch.d.ts +0 -1
- package/dist/shared/prompt-async-gate/timing.d.ts +0 -1
- package/dist/shared/prompt-async-gate/types.d.ts +0 -1
- package/dist/skills/data-scientist/references/common-scenarios.md +0 -176
- package/dist/skills/data-scientist/references/execution-templates.md +0 -197
- package/dist/skills/data-scientist/references/integration-patterns.md +0 -153
- package/dist/skills/data-scientist/references/performance-benchmarks.md +0 -37
- package/dist/tools/call-omo-agent/background-agent-executor.d.ts +0 -5
- package/dist/tools/call-omo-agent/message-storage-directory.d.ts +0 -1
- package/dist/tools/delegate-task/model-string-parser.d.ts +0 -1
- package/packages/lsp-tools-mcp/dist/lsp/cleanup-errors.d.ts +0 -1
- package/packages/lsp-tools-mcp/dist/lsp/constants.d.ts +0 -1
- package/packages/lsp-tools-mcp/dist/lsp/language-mappings.d.ts +0 -1
- package/packages/lsp-tools-mcp/dist/lsp/process-signal-cleanup.d.ts +0 -1
- package/packages/lsp-tools-mcp/dist/missing-dependency-result.d.ts +0 -1
- package/packages/omo-codex/plugin/components/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/components/ultrawork/skills/ultrawork/SKILL.md +0 -478
- 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/dist/hooks/{start-work → ulw-execute}/context-info-formatters.d.ts +0 -0
- /package/dist/hooks/{start-work → ulw-execute}/explicit-plan-context.d.ts +0 -0
- /package/dist/hooks/{start-work → ulw-execute}/notepad-scaffold.d.ts +0 -0
- /package/dist/hooks/{start-work → ulw-execute}/parse-user-request.d.ts +0 -0
- /package/dist/hooks/{start-work → ulw-execute}/plan-discovery-context.d.ts +0 -0
- /package/dist/hooks/{start-work → ulw-execute}/plan-selection.d.ts +0 -0
- /package/dist/hooks/{start-work → ulw-execute}/session-plan-affinity.d.ts +0 -0
- /package/dist/hooks/{start-work → ulw-execute}/work-initializer.d.ts +0 -0
- /package/dist/hooks/{start-work → ulw-execute}/worktree-block.d.ts +0 -0
- /package/dist/hooks/{start-work → ulw-execute}/worktree-detector.d.ts +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/.gitattributes +0 -0
- /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/CHANGELOG.md +0 -0
- /package/packages/omo-codex/plugin/components/{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
|
@@ -15,6 +15,13 @@ import { pathToFileURL as pathToFileURL3 } from "node:url";
|
|
|
15
15
|
// ../lsp-core/src/lsp/connection.ts
|
|
16
16
|
import { pathToFileURL } from "node:url";
|
|
17
17
|
|
|
18
|
+
// ../lsp-core/src/lsp/timer-provider.ts
|
|
19
|
+
var realTimerProvider = {
|
|
20
|
+
now: () => Date.now(),
|
|
21
|
+
setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
|
|
22
|
+
clearTimeout: (handle) => clearTimeout(handle)
|
|
23
|
+
};
|
|
24
|
+
|
|
18
25
|
// ../lsp-core/src/lsp/constants.ts
|
|
19
26
|
var DEFAULT_MAX_REFERENCES = 200;
|
|
20
27
|
var DEFAULT_MAX_SYMBOLS = 200;
|
|
@@ -23,28 +30,24 @@ var DEFAULT_MAX_DIRECTORY_FILES = 50;
|
|
|
23
30
|
var REQUEST_TIMEOUT_MS = 15000;
|
|
24
31
|
var INIT_TIMEOUT_MS = 60000;
|
|
25
32
|
var IDLE_TIMEOUT_MS = 5 * 60000;
|
|
33
|
+
var MAX_RESIDENT_CLIENTS = 6;
|
|
26
34
|
var REAPER_INTERVAL_MS = 60000;
|
|
27
35
|
var STOP_HARD_KILL_TIMEOUT_MS = 5000;
|
|
28
36
|
var STOP_SIGKILL_GRACE_MS = 1000;
|
|
37
|
+
var CLIENT_RESPAWN_RETRY_LIMIT = 2;
|
|
38
|
+
var CLIENT_RESPAWN_COOLDOWN_MS = 60000;
|
|
29
39
|
|
|
30
40
|
// ../lsp-core/src/lsp/errors.ts
|
|
31
41
|
class LspConnectionClosedError extends Error {
|
|
32
|
-
serverId;
|
|
33
|
-
root;
|
|
34
|
-
name = "LspConnectionClosedError";
|
|
35
42
|
constructor(serverId, root, message) {
|
|
36
43
|
super(message ?? `LSP connection closed for ${serverId} at ${root}`);
|
|
37
44
|
this.serverId = serverId;
|
|
38
45
|
this.root = root;
|
|
46
|
+
this.name = "LspConnectionClosedError";
|
|
39
47
|
}
|
|
40
48
|
}
|
|
41
49
|
|
|
42
50
|
class LspProcessExitedError extends Error {
|
|
43
|
-
serverId;
|
|
44
|
-
root;
|
|
45
|
-
exitCode;
|
|
46
|
-
stderrTail;
|
|
47
|
-
name = "LspProcessExitedError";
|
|
48
51
|
constructor(serverId, root, exitCode, stderrTail) {
|
|
49
52
|
const stderrSuffix = stderrTail ? `
|
|
50
53
|
stderr tail: ${stderrTail}` : "";
|
|
@@ -53,46 +56,59 @@ stderr tail: ${stderrTail}` : "";
|
|
|
53
56
|
this.root = root;
|
|
54
57
|
this.exitCode = exitCode;
|
|
55
58
|
this.stderrTail = stderrTail;
|
|
59
|
+
this.name = "LspProcessExitedError";
|
|
56
60
|
}
|
|
57
61
|
}
|
|
58
62
|
|
|
59
63
|
class LspRequestTimeoutError extends Error {
|
|
60
|
-
method;
|
|
61
|
-
stderrTail;
|
|
62
|
-
name = "LspRequestTimeoutError";
|
|
63
64
|
constructor(method, stderrTail) {
|
|
64
65
|
const stderrSuffix = stderrTail ? `
|
|
65
66
|
recent stderr: ${stderrTail}` : "";
|
|
66
67
|
super(`LSP request timeout (method: ${method})${stderrSuffix}`);
|
|
67
68
|
this.method = method;
|
|
68
69
|
this.stderrTail = stderrTail;
|
|
70
|
+
this.name = "LspRequestTimeoutError";
|
|
69
71
|
}
|
|
70
72
|
}
|
|
71
73
|
|
|
72
74
|
class LspInvalidPathError extends Error {
|
|
73
|
-
|
|
75
|
+
constructor() {
|
|
76
|
+
super(...arguments);
|
|
77
|
+
this.name = "LspInvalidPathError";
|
|
78
|
+
}
|
|
74
79
|
}
|
|
75
80
|
|
|
76
81
|
class LspServerLookupError extends Error {
|
|
77
|
-
lookup;
|
|
78
|
-
name = "LspServerLookupError";
|
|
79
82
|
constructor(message, lookup) {
|
|
80
83
|
super(message);
|
|
81
84
|
this.lookup = lookup;
|
|
85
|
+
this.name = "LspServerLookupError";
|
|
82
86
|
}
|
|
83
87
|
}
|
|
84
88
|
|
|
85
89
|
class LspServerInitializingError extends Error {
|
|
86
|
-
originalError;
|
|
87
|
-
name = "LspServerInitializingError";
|
|
88
90
|
constructor(originalError) {
|
|
89
91
|
super(`LSP server is still initializing. Please retry in a few seconds. Original error: ${originalError.message}`);
|
|
90
92
|
this.originalError = originalError;
|
|
93
|
+
this.name = "LspServerInitializingError";
|
|
91
94
|
}
|
|
92
95
|
}
|
|
93
96
|
|
|
94
97
|
class LspProcessSpawnError extends Error {
|
|
95
|
-
|
|
98
|
+
constructor() {
|
|
99
|
+
super(...arguments);
|
|
100
|
+
this.name = "LspProcessSpawnError";
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
class LspClientRespawnBudgetExceededError extends Error {
|
|
105
|
+
constructor(serverId, root, retryLimit) {
|
|
106
|
+
super(`LSP server ${serverId} at ${root} failed to stay alive; respawn budget exhausted ` + `(${retryLimit} consecutive dead generations). Retrying after the cooldown may succeed.`);
|
|
107
|
+
this.serverId = serverId;
|
|
108
|
+
this.root = root;
|
|
109
|
+
this.retryLimit = retryLimit;
|
|
110
|
+
this.name = "LspClientRespawnBudgetExceededError";
|
|
111
|
+
}
|
|
96
112
|
}
|
|
97
113
|
function isLspDeadConnectionError(err) {
|
|
98
114
|
return err instanceof LspConnectionClosedError || err instanceof LspProcessExitedError;
|
|
@@ -108,20 +124,31 @@ var METHOD_NOT_FOUND = -32601;
|
|
|
108
124
|
var INTERNAL_ERROR = -32603;
|
|
109
125
|
|
|
110
126
|
class JsonRpcConnection {
|
|
111
|
-
reader;
|
|
112
|
-
writer;
|
|
113
|
-
pendingRequests = new Map;
|
|
114
|
-
notificationHandlers = new Map;
|
|
115
|
-
requestHandlers = new Map;
|
|
116
|
-
closeHandlers = [];
|
|
117
|
-
errorHandlers = [];
|
|
118
|
-
inputBuffer = Buffer.alloc(0);
|
|
119
|
-
nextRequestId = 1;
|
|
120
|
-
listening = false;
|
|
121
|
-
disposed = false;
|
|
122
127
|
constructor(reader, writer) {
|
|
123
128
|
this.reader = reader;
|
|
124
129
|
this.writer = writer;
|
|
130
|
+
this.pendingRequests = new Map;
|
|
131
|
+
this.notificationHandlers = new Map;
|
|
132
|
+
this.requestHandlers = new Map;
|
|
133
|
+
this.closeHandlers = [];
|
|
134
|
+
this.errorHandlers = [];
|
|
135
|
+
this.inputBuffer = Buffer.alloc(0);
|
|
136
|
+
this.nextRequestId = 1;
|
|
137
|
+
this.listening = false;
|
|
138
|
+
this.disposed = false;
|
|
139
|
+
this.handleData = (chunk) => {
|
|
140
|
+
const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
|
|
141
|
+
this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
|
|
142
|
+
this.drainInputBuffer();
|
|
143
|
+
};
|
|
144
|
+
this.handleClose = () => {
|
|
145
|
+
for (const handler of this.closeHandlers) {
|
|
146
|
+
handler();
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
this.handleStreamError = (error) => {
|
|
150
|
+
this.emitError(error);
|
|
151
|
+
};
|
|
125
152
|
}
|
|
126
153
|
listen() {
|
|
127
154
|
if (this.listening)
|
|
@@ -156,6 +183,7 @@ class JsonRpcConnection {
|
|
|
156
183
|
let cancelAfterWrite = false;
|
|
157
184
|
let settled = false;
|
|
158
185
|
const writeCancel = () => this.writeMessage({ jsonrpc: "2.0", method: "$/cancelRequest", params: { id } });
|
|
186
|
+
let rejectAfterCancelWrite;
|
|
159
187
|
const responsePromise = new Promise((resolve, reject) => {
|
|
160
188
|
const cleanup = () => {
|
|
161
189
|
options.signal?.removeEventListener("abort", onAbort);
|
|
@@ -167,15 +195,19 @@ class JsonRpcConnection {
|
|
|
167
195
|
this.pendingRequests.delete(key);
|
|
168
196
|
cleanup();
|
|
169
197
|
const rejectCancelled = () => reject(abortError(options.signal));
|
|
198
|
+
rejectAfterCancelWrite = async () => {
|
|
199
|
+
try {
|
|
200
|
+
await writeCancel();
|
|
201
|
+
} catch (error) {
|
|
202
|
+
this.emitError(toError(error));
|
|
203
|
+
}
|
|
204
|
+
rejectCancelled();
|
|
205
|
+
};
|
|
170
206
|
if (!requestWritten) {
|
|
171
207
|
cancelAfterWrite = true;
|
|
172
|
-
rejectCancelled();
|
|
173
208
|
return;
|
|
174
209
|
}
|
|
175
|
-
|
|
176
|
-
this.emitError(toError(error));
|
|
177
|
-
rejectCancelled();
|
|
178
|
-
});
|
|
210
|
+
rejectAfterCancelWrite();
|
|
179
211
|
};
|
|
180
212
|
const onAbort = () => settleCancel();
|
|
181
213
|
this.pendingRequests.set(key, {
|
|
@@ -203,7 +235,7 @@ class JsonRpcConnection {
|
|
|
203
235
|
await this.writeMessage(message);
|
|
204
236
|
requestWritten = true;
|
|
205
237
|
if (cancelAfterWrite)
|
|
206
|
-
await
|
|
238
|
+
await rejectAfterCancelWrite?.();
|
|
207
239
|
} catch (error) {
|
|
208
240
|
if (settled)
|
|
209
241
|
return responsePromise;
|
|
@@ -242,19 +274,6 @@ class JsonRpcConnection {
|
|
|
242
274
|
this.notificationHandlers.clear();
|
|
243
275
|
this.requestHandlers.clear();
|
|
244
276
|
}
|
|
245
|
-
handleData = (chunk) => {
|
|
246
|
-
const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
|
|
247
|
-
this.inputBuffer = Buffer.concat([this.inputBuffer, chunkBuffer]);
|
|
248
|
-
this.drainInputBuffer();
|
|
249
|
-
};
|
|
250
|
-
handleClose = () => {
|
|
251
|
-
for (const handler of this.closeHandlers) {
|
|
252
|
-
handler();
|
|
253
|
-
}
|
|
254
|
-
};
|
|
255
|
-
handleStreamError = (error) => {
|
|
256
|
-
this.emitError(error);
|
|
257
|
-
};
|
|
258
277
|
drainInputBuffer() {
|
|
259
278
|
while (true) {
|
|
260
279
|
const headerEnd = this.inputBuffer.indexOf(HEADER_SEPARATOR);
|
|
@@ -602,33 +621,29 @@ function isPosition(value) {
|
|
|
602
621
|
|
|
603
622
|
// ../lsp-core/src/lsp/transport.ts
|
|
604
623
|
class LspClientNotStartedError extends Error {
|
|
605
|
-
serverId;
|
|
606
|
-
root;
|
|
607
|
-
name = "LspClientNotStartedError";
|
|
608
624
|
constructor(serverId, root) {
|
|
609
625
|
super("LSP client not started");
|
|
610
626
|
this.serverId = serverId;
|
|
611
627
|
this.root = root;
|
|
628
|
+
this.name = "LspClientNotStartedError";
|
|
612
629
|
}
|
|
613
630
|
}
|
|
614
631
|
|
|
615
632
|
class LspClientTransport {
|
|
616
|
-
root;
|
|
617
|
-
server;
|
|
618
|
-
proc = null;
|
|
619
|
-
connection = null;
|
|
620
|
-
stderrBuffer = [];
|
|
621
|
-
processExited = false;
|
|
622
|
-
diagnosticsStore = new Map;
|
|
623
|
-
requestTimeoutMs;
|
|
624
|
-
initializeTimeoutMs;
|
|
625
|
-
workspaceApplyEditHandler = null;
|
|
626
|
-
diagnosticPullSupported = false;
|
|
627
633
|
constructor(root, server, timeouts = {}) {
|
|
628
634
|
this.root = root;
|
|
629
635
|
this.server = server;
|
|
636
|
+
this.proc = null;
|
|
637
|
+
this.connection = null;
|
|
638
|
+
this.stderrBuffer = [];
|
|
639
|
+
this.processExited = false;
|
|
640
|
+
this.diagnosticsStore = new Map;
|
|
641
|
+
this.workspaceApplyEditHandler = null;
|
|
642
|
+
this.diagnosticPullSupported = false;
|
|
643
|
+
this.documentFormattingSupported = false;
|
|
630
644
|
this.requestTimeoutMs = timeouts.requestTimeoutMs ?? REQUEST_TIMEOUT_MS;
|
|
631
645
|
this.initializeTimeoutMs = timeouts.initializeTimeoutMs ?? INIT_TIMEOUT_MS;
|
|
646
|
+
this.timerProvider = timeouts.timerProvider ?? realTimerProvider;
|
|
632
647
|
}
|
|
633
648
|
pid() {
|
|
634
649
|
return this.proc?.pid;
|
|
@@ -648,6 +663,12 @@ class LspClientTransport {
|
|
|
648
663
|
isDiagnosticPullSupported() {
|
|
649
664
|
return this.diagnosticPullSupported;
|
|
650
665
|
}
|
|
666
|
+
setDocumentFormattingSupported(supported) {
|
|
667
|
+
this.documentFormattingSupported = supported;
|
|
668
|
+
}
|
|
669
|
+
isDocumentFormattingSupported() {
|
|
670
|
+
return this.documentFormattingSupported;
|
|
671
|
+
}
|
|
651
672
|
handlePublishDiagnostics(params) {
|
|
652
673
|
this.diagnosticsStore.set(params.uri, [...params.diagnostics]);
|
|
653
674
|
}
|
|
@@ -723,7 +744,7 @@ class LspClientTransport {
|
|
|
723
744
|
const options = args[1];
|
|
724
745
|
const timeoutMs = options?.timeoutMs ?? this.requestTimeoutMs;
|
|
725
746
|
const timeoutController = new AbortController;
|
|
726
|
-
const timeoutHandle = setTimeout(() => {
|
|
747
|
+
const timeoutHandle = this.timerProvider.setTimeout(() => {
|
|
727
748
|
const stderrTail = this.stderrBuffer.slice(-5).join(`
|
|
728
749
|
`);
|
|
729
750
|
timeoutController.abort(new LspRequestTimeoutError(method, stderrTail || undefined));
|
|
@@ -742,7 +763,7 @@ class LspClientTransport {
|
|
|
742
763
|
}
|
|
743
764
|
throw error;
|
|
744
765
|
} finally {
|
|
745
|
-
clearTimeout(timeoutHandle);
|
|
766
|
+
this.timerProvider.clearTimeout(timeoutHandle);
|
|
746
767
|
combinedSignal.dispose();
|
|
747
768
|
}
|
|
748
769
|
}
|
|
@@ -861,6 +882,14 @@ function supportsDiagnosticPull(capabilities) {
|
|
|
861
882
|
return false;
|
|
862
883
|
return Object.hasOwn(capabilities, "diagnosticProvider");
|
|
863
884
|
}
|
|
885
|
+
function supportsDocumentFormatting(capabilities) {
|
|
886
|
+
if (capabilities === undefined)
|
|
887
|
+
return false;
|
|
888
|
+
const provider = capabilities.documentFormattingProvider;
|
|
889
|
+
if (provider === undefined || provider === null || provider === false)
|
|
890
|
+
return false;
|
|
891
|
+
return provider === true || typeof provider === "object";
|
|
892
|
+
}
|
|
864
893
|
|
|
865
894
|
class LspClientConnection extends LspClientTransport {
|
|
866
895
|
async initialize() {
|
|
@@ -877,6 +906,7 @@ class LspClientConnection extends LspClientTransport {
|
|
|
877
906
|
references: {},
|
|
878
907
|
documentSymbol: { hierarchicalDocumentSymbolSupport: true },
|
|
879
908
|
publishDiagnostics: {},
|
|
909
|
+
formatting: { dynamicRegistration: false },
|
|
880
910
|
rename: {
|
|
881
911
|
prepareSupport: true,
|
|
882
912
|
prepareSupportDefaultBehavior: 1
|
|
@@ -918,6 +948,7 @@ class LspClientConnection extends LspClientTransport {
|
|
|
918
948
|
initializationOptions: this.server.initialization
|
|
919
949
|
}, { timeoutMs: this.initializeTimeoutMs });
|
|
920
950
|
this.setDiagnosticPullSupported(supportsDiagnosticPull(result?.capabilities));
|
|
951
|
+
this.setDocumentFormattingSupported(supportsDocumentFormatting(result?.capabilities));
|
|
921
952
|
await this.sendNotification("initialized", {});
|
|
922
953
|
await this.sendNotification("workspace/didChangeConfiguration", {
|
|
923
954
|
settings: { json: { validate: { enable: true } } }
|
|
@@ -1123,6 +1154,17 @@ function canonicalPath(filePath) {
|
|
|
1123
1154
|
return absolute;
|
|
1124
1155
|
}
|
|
1125
1156
|
}
|
|
1157
|
+
function normalizeDocumentUri(uri) {
|
|
1158
|
+
let decoded = uri;
|
|
1159
|
+
try {
|
|
1160
|
+
decoded = decodeURIComponent(uri);
|
|
1161
|
+
} catch {
|
|
1162
|
+
decoded = uri;
|
|
1163
|
+
}
|
|
1164
|
+
if (process.platform !== "win32")
|
|
1165
|
+
return decoded;
|
|
1166
|
+
return decoded.replace(/^(file:\/\/\/)([a-z]):/, (_match, prefix, drive) => `${prefix}${drive.toUpperCase()}:`);
|
|
1167
|
+
}
|
|
1126
1168
|
function isSameOrDescendant(candidate, parent) {
|
|
1127
1169
|
const suffix = relative(parent, candidate);
|
|
1128
1170
|
return suffix === "" || !suffix.startsWith("..") && suffix !== "..";
|
|
@@ -1133,17 +1175,18 @@ function movedPath(candidate, oldPath, newPath) {
|
|
|
1133
1175
|
}
|
|
1134
1176
|
|
|
1135
1177
|
class WorkspaceDocumentState {
|
|
1136
|
-
sendNotification;
|
|
1137
|
-
clearDiagnostics;
|
|
1138
|
-
openDocuments = new Map;
|
|
1139
|
-
openByUri = new Map;
|
|
1140
|
-
openPromises = new Map;
|
|
1141
|
-
now;
|
|
1142
|
-
versionlessPublishQuiescenceMs;
|
|
1143
1178
|
constructor(sendNotification, clearDiagnostics, options = {}) {
|
|
1144
1179
|
this.sendNotification = sendNotification;
|
|
1145
1180
|
this.clearDiagnostics = clearDiagnostics;
|
|
1146
|
-
this.
|
|
1181
|
+
this.openDocuments = new Map;
|
|
1182
|
+
this.openByUri = new Map;
|
|
1183
|
+
this.openPromises = new Map;
|
|
1184
|
+
this.timerProvider = options.timerProvider ?? {
|
|
1185
|
+
now: options.now ?? (() => Date.now()),
|
|
1186
|
+
setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
|
|
1187
|
+
clearTimeout: (handle) => clearTimeout(handle)
|
|
1188
|
+
};
|
|
1189
|
+
this.now = () => this.timerProvider.now();
|
|
1147
1190
|
this.versionlessPublishQuiescenceMs = options.versionlessPublishQuiescenceMs ?? DEFAULT_VERSIONLESS_PUBLISH_QUIESCENCE_MS;
|
|
1148
1191
|
}
|
|
1149
1192
|
async openFile(filePath) {
|
|
@@ -1165,7 +1208,7 @@ class WorkspaceDocumentState {
|
|
|
1165
1208
|
return this.openDocuments.get(canonicalPath(filePath))?.version;
|
|
1166
1209
|
}
|
|
1167
1210
|
getStoredDiagnostics(uri) {
|
|
1168
|
-
const state = this.openByUri.get(uri);
|
|
1211
|
+
const state = this.openByUri.get(normalizeDocumentUri(uri));
|
|
1169
1212
|
if (!state)
|
|
1170
1213
|
return [];
|
|
1171
1214
|
return state.lastPublish?.diagnostics ?? state.pullCache?.diagnostics ?? [];
|
|
@@ -1187,13 +1230,13 @@ class WorkspaceDocumentState {
|
|
|
1187
1230
|
return state !== undefined && state.uri === snapshot.uri && state.version === snapshot.version && state.generation === snapshot.documentGeneration;
|
|
1188
1231
|
}
|
|
1189
1232
|
getPullCache(snapshot) {
|
|
1190
|
-
const state = this.openByUri.get(snapshot.uri);
|
|
1233
|
+
const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
|
|
1191
1234
|
if (!state?.pullCache || state.pullCache.documentVersion !== snapshot.version)
|
|
1192
1235
|
return null;
|
|
1193
1236
|
return state.pullCache;
|
|
1194
1237
|
}
|
|
1195
1238
|
recordPullDiagnostics(snapshot, report) {
|
|
1196
|
-
const state = this.openByUri.get(snapshot.uri);
|
|
1239
|
+
const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
|
|
1197
1240
|
if (!state)
|
|
1198
1241
|
return;
|
|
1199
1242
|
state.pullCache = {
|
|
@@ -1203,7 +1246,7 @@ class WorkspaceDocumentState {
|
|
|
1203
1246
|
};
|
|
1204
1247
|
}
|
|
1205
1248
|
recordPublishedDiagnostics(params) {
|
|
1206
|
-
const state = this.openByUri.get(params.uri);
|
|
1249
|
+
const state = this.openByUri.get(normalizeDocumentUri(params.uri));
|
|
1207
1250
|
if (!state)
|
|
1208
1251
|
return;
|
|
1209
1252
|
state.publishGeneration += 1;
|
|
@@ -1217,7 +1260,7 @@ class WorkspaceDocumentState {
|
|
|
1217
1260
|
this.notifyWaiters(state);
|
|
1218
1261
|
}
|
|
1219
1262
|
resolvePushDiagnostics(snapshot) {
|
|
1220
|
-
const state = this.openByUri.get(snapshot.uri);
|
|
1263
|
+
const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
|
|
1221
1264
|
if (!state?.lastPublish)
|
|
1222
1265
|
return { status: "missing" };
|
|
1223
1266
|
const publish = state.lastPublish;
|
|
@@ -1231,7 +1274,7 @@ class WorkspaceDocumentState {
|
|
|
1231
1274
|
return waitMs === 0 ? { status: "ready", diagnostics: publish.diagnostics } : { status: "wait", waitMs };
|
|
1232
1275
|
}
|
|
1233
1276
|
waitForDiagnosticsActivity(snapshot, timeoutMs) {
|
|
1234
|
-
const state = this.openByUri.get(snapshot.uri);
|
|
1277
|
+
const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
|
|
1235
1278
|
if (!state || timeoutMs <= 0)
|
|
1236
1279
|
return Promise.resolve();
|
|
1237
1280
|
return new Promise((resolveActivity) => {
|
|
@@ -1240,11 +1283,11 @@ class WorkspaceDocumentState {
|
|
|
1240
1283
|
if (settled)
|
|
1241
1284
|
return;
|
|
1242
1285
|
settled = true;
|
|
1243
|
-
clearTimeout(timer);
|
|
1286
|
+
this.timerProvider.clearTimeout(timer);
|
|
1244
1287
|
state.waiters.delete(finish);
|
|
1245
1288
|
resolveActivity();
|
|
1246
1289
|
};
|
|
1247
|
-
const timer = setTimeout(finish, timeoutMs);
|
|
1290
|
+
const timer = this.timerProvider.setTimeout(finish, timeoutMs);
|
|
1248
1291
|
if (typeof timer.unref === "function")
|
|
1249
1292
|
timer.unref();
|
|
1250
1293
|
state.waiters.add(finish);
|
|
@@ -1352,7 +1395,7 @@ class WorkspaceDocumentState {
|
|
|
1352
1395
|
waiters: new Set
|
|
1353
1396
|
};
|
|
1354
1397
|
this.openDocuments.set(path, state);
|
|
1355
|
-
this.openByUri.set(state.uri, state);
|
|
1398
|
+
this.openByUri.set(normalizeDocumentUri(state.uri), state);
|
|
1356
1399
|
this.notifyWaiters(state);
|
|
1357
1400
|
await this.sendNotification("textDocument/didOpen", {
|
|
1358
1401
|
textDocument: { uri: state.uri, languageId: state.languageId, version: state.version, text }
|
|
@@ -1377,7 +1420,7 @@ class WorkspaceDocumentState {
|
|
|
1377
1420
|
}
|
|
1378
1421
|
async closeDocument(state) {
|
|
1379
1422
|
this.openDocuments.delete(state.path);
|
|
1380
|
-
this.openByUri.delete(state.uri);
|
|
1423
|
+
this.openByUri.delete(normalizeDocumentUri(state.uri));
|
|
1381
1424
|
this.clearDiagnostics(state.uri);
|
|
1382
1425
|
this.notifyWaiters(state);
|
|
1383
1426
|
await this.sendNotification("textDocument/didClose", { textDocument: { uri: state.uri } });
|
|
@@ -1406,13 +1449,11 @@ import { dirname, isAbsolute, relative as relative2, resolve as resolve2 } from
|
|
|
1406
1449
|
import { fileURLToPath } from "node:url";
|
|
1407
1450
|
|
|
1408
1451
|
class WorkspaceEditPathError extends Error {
|
|
1409
|
-
path;
|
|
1410
|
-
detail;
|
|
1411
|
-
name = "WorkspaceEditPathError";
|
|
1412
1452
|
constructor(path, detail) {
|
|
1413
1453
|
super(`${detail}: ${path}`);
|
|
1414
1454
|
this.path = path;
|
|
1415
1455
|
this.detail = detail;
|
|
1456
|
+
this.name = "WorkspaceEditPathError";
|
|
1416
1457
|
}
|
|
1417
1458
|
}
|
|
1418
1459
|
function isPathInsideWorkspace(filePath, workspaceRoot) {
|
|
@@ -1704,13 +1745,11 @@ function canonicalFingerprint(operations) {
|
|
|
1704
1745
|
|
|
1705
1746
|
// ../lsp-core/src/lsp/workspace-edit-types.ts
|
|
1706
1747
|
class WorkspaceEditValidationError extends Error {
|
|
1707
|
-
changeIndex;
|
|
1708
|
-
detail;
|
|
1709
|
-
name = "WorkspaceEditValidationError";
|
|
1710
1748
|
constructor(changeIndex, detail) {
|
|
1711
1749
|
super(`change ${changeIndex}: ${detail}`);
|
|
1712
1750
|
this.changeIndex = changeIndex;
|
|
1713
1751
|
this.detail = detail;
|
|
1752
|
+
this.name = "WorkspaceEditValidationError";
|
|
1714
1753
|
}
|
|
1715
1754
|
}
|
|
1716
1755
|
|
|
@@ -2208,10 +2247,9 @@ function simulateDelete(operation, virtual) {
|
|
|
2208
2247
|
import { existsSync as existsSync4, lstatSync as lstatSync3, readdirSync as readdirSync2 } from "node:fs";
|
|
2209
2248
|
import { dirname as dirname3, resolve as resolve4 } from "node:path";
|
|
2210
2249
|
class WorkspaceSnapshotBuilder {
|
|
2211
|
-
workspaceRoot;
|
|
2212
|
-
snapshots = new Map;
|
|
2213
2250
|
constructor(workspaceRoot) {
|
|
2214
2251
|
this.workspaceRoot = workspaceRoot;
|
|
2252
|
+
this.snapshots = new Map;
|
|
2215
2253
|
}
|
|
2216
2254
|
build(operations) {
|
|
2217
2255
|
this.add(this.workspaceRoot, false);
|
|
@@ -2255,8 +2293,10 @@ function snapshotOperations(operations, workspaceRoot) {
|
|
|
2255
2293
|
|
|
2256
2294
|
// ../lsp-core/src/lsp/workspace-edit-plan.ts
|
|
2257
2295
|
class PlanPathIndex {
|
|
2258
|
-
|
|
2259
|
-
|
|
2296
|
+
constructor() {
|
|
2297
|
+
this.firstChangeByPath = new Map;
|
|
2298
|
+
this.reportedPathByCanonical = new Map;
|
|
2299
|
+
}
|
|
2260
2300
|
build(operations) {
|
|
2261
2301
|
for (const operation of operations) {
|
|
2262
2302
|
switch (operation.kind) {
|
|
@@ -2345,14 +2385,11 @@ function isRecord3(value) {
|
|
|
2345
2385
|
}
|
|
2346
2386
|
|
|
2347
2387
|
class WorkspaceMutationController {
|
|
2348
|
-
workspaceRoot;
|
|
2349
|
-
documents;
|
|
2350
|
-
activeLease = null;
|
|
2351
|
-
nextLeaseId = 1;
|
|
2352
|
-
io;
|
|
2353
2388
|
constructor(workspaceRoot, documents) {
|
|
2354
2389
|
this.workspaceRoot = workspaceRoot;
|
|
2355
2390
|
this.documents = documents;
|
|
2391
|
+
this.activeLease = null;
|
|
2392
|
+
this.nextLeaseId = 1;
|
|
2356
2393
|
}
|
|
2357
2394
|
setIo(io) {
|
|
2358
2395
|
this.io = io;
|
|
@@ -2465,14 +2502,12 @@ var DIAGNOSTICS_FRESHNESS_TIMEOUT_MS = 3000;
|
|
|
2465
2502
|
var VERSIONLESS_PUBLISH_QUIESCENCE_MS = 250;
|
|
2466
2503
|
|
|
2467
2504
|
class LspClient extends LspClientConnection {
|
|
2468
|
-
diagnosticPullErrors = [];
|
|
2469
|
-
documents;
|
|
2470
|
-
workspaceMutations;
|
|
2471
|
-
diagnosticsFreshnessTimeoutMs;
|
|
2472
2505
|
constructor(root, server, options = {}) {
|
|
2473
2506
|
super(root, server, options);
|
|
2507
|
+
this.diagnosticPullErrors = [];
|
|
2474
2508
|
this.diagnosticsFreshnessTimeoutMs = options.diagnosticsFreshnessTimeoutMs ?? DIAGNOSTICS_FRESHNESS_TIMEOUT_MS;
|
|
2475
2509
|
this.documents = new WorkspaceDocumentState((method, params) => this.sendNotification(method, params), (uri) => this.diagnosticsStore.delete(uri), {
|
|
2510
|
+
timerProvider: this.timerProvider,
|
|
2476
2511
|
versionlessPublishQuiescenceMs: options.versionlessPublishQuiescenceMs ?? VERSIONLESS_PUBLISH_QUIESCENCE_MS
|
|
2477
2512
|
});
|
|
2478
2513
|
this.workspaceMutations = new WorkspaceMutationController(root, this.documents);
|
|
@@ -2525,6 +2560,18 @@ class LspClient extends LspClientConnection {
|
|
|
2525
2560
|
textDocument: { uri: pathToFileURL3(absPath).href }
|
|
2526
2561
|
}, options);
|
|
2527
2562
|
}
|
|
2563
|
+
async formatDocument(filePath, options, signal) {
|
|
2564
|
+
if (!this.isDocumentFormattingSupported())
|
|
2565
|
+
return null;
|
|
2566
|
+
const absPath = this.resolveWorkspacePath(filePath);
|
|
2567
|
+
await this.openFile(absPath);
|
|
2568
|
+
const requestOptions = signal === undefined ? {} : { signal };
|
|
2569
|
+
const edits = await this.sendRequest("textDocument/formatting", {
|
|
2570
|
+
textDocument: { uri: pathToFileURL3(absPath).href },
|
|
2571
|
+
options
|
|
2572
|
+
}, requestOptions);
|
|
2573
|
+
return edits ?? [];
|
|
2574
|
+
}
|
|
2528
2575
|
async workspaceSymbols(query, signal) {
|
|
2529
2576
|
const options = signal === undefined ? {} : { signal };
|
|
2530
2577
|
return this.sendRequest("workspace/symbol", { query }, options);
|
|
@@ -2564,7 +2611,7 @@ class LspClient extends LspClientConnection {
|
|
|
2564
2611
|
const absPath = this.resolveWorkspacePath(filePath);
|
|
2565
2612
|
const uri = pathToFileURL3(absPath).href;
|
|
2566
2613
|
await this.openFile(absPath);
|
|
2567
|
-
const deadlineAt =
|
|
2614
|
+
const deadlineAt = this.timerProvider.now() + this.diagnosticsFreshnessTimeoutMs;
|
|
2568
2615
|
for (;; ) {
|
|
2569
2616
|
signal?.throwIfAborted();
|
|
2570
2617
|
const snapshot = this.documents.captureDiagnosticSnapshot(absPath);
|
|
@@ -2577,7 +2624,7 @@ class LspClient extends LspClientConnection {
|
|
|
2577
2624
|
if (!pushFallbackOnly) {
|
|
2578
2625
|
const cached = this.documents.getPullCache(snapshot);
|
|
2579
2626
|
try {
|
|
2580
|
-
const remainingMs2 = deadlineAt -
|
|
2627
|
+
const remainingMs2 = deadlineAt - this.timerProvider.now();
|
|
2581
2628
|
if (remainingMs2 <= 0)
|
|
2582
2629
|
return this.freshnessTimeout(absPath);
|
|
2583
2630
|
const result = await this.sendRequest("textDocument/diagnostic", {
|
|
@@ -2612,7 +2659,7 @@ class LspClient extends LspClientConnection {
|
|
|
2612
2659
|
}
|
|
2613
2660
|
if (!pushFallbackOnly)
|
|
2614
2661
|
continue;
|
|
2615
|
-
const remainingMs = deadlineAt -
|
|
2662
|
+
const remainingMs = deadlineAt - this.timerProvider.now();
|
|
2616
2663
|
if (remainingMs <= 0) {
|
|
2617
2664
|
if (!this.isDiagnosticPullSupported() && snapshot.publishGeneration === 0) {
|
|
2618
2665
|
const cached = this.documents.getPullCache(snapshot);
|
|
@@ -2770,18 +2817,16 @@ function awaitWithSignal(promise, signal) {
|
|
|
2770
2817
|
}
|
|
2771
2818
|
|
|
2772
2819
|
class LspManager {
|
|
2773
|
-
clients = new Map;
|
|
2774
|
-
reaperHandle = null;
|
|
2775
|
-
signalDisposer = null;
|
|
2776
|
-
disposed = false;
|
|
2777
|
-
idleTimeoutMs;
|
|
2778
|
-
initTimeoutMs;
|
|
2779
|
-
reaperIntervalMs;
|
|
2780
|
-
clientFactory;
|
|
2781
|
-
now;
|
|
2782
2820
|
constructor(options = {}) {
|
|
2821
|
+
this.clients = new Map;
|
|
2822
|
+
this.pendingStops = new Map;
|
|
2823
|
+
this.respawnBudgets = new Map;
|
|
2824
|
+
this.reaperHandle = null;
|
|
2825
|
+
this.signalDisposer = null;
|
|
2826
|
+
this.disposed = false;
|
|
2783
2827
|
this.idleTimeoutMs = options.idleTimeoutMs ?? IDLE_TIMEOUT_MS;
|
|
2784
2828
|
this.initTimeoutMs = options.initTimeoutMs ?? INIT_TIMEOUT_MS;
|
|
2829
|
+
this.maxResidentClients = options.maxResidentClients ?? MAX_RESIDENT_CLIENTS;
|
|
2785
2830
|
this.reaperIntervalMs = options.reaperIntervalMs ?? REAPER_INTERVAL_MS;
|
|
2786
2831
|
this.clientFactory = options.clientFactory ?? ((root, server) => new LspClient(root, server));
|
|
2787
2832
|
this.now = options.now ?? (() => Date.now());
|
|
@@ -2801,24 +2846,79 @@ class LspManager {
|
|
|
2801
2846
|
getKey(root, serverId) {
|
|
2802
2847
|
return `${root}::${serverId}`;
|
|
2803
2848
|
}
|
|
2849
|
+
tombstoneStop(key, client) {
|
|
2850
|
+
const stop = stopClientBestEffort(client);
|
|
2851
|
+
this.pendingStops.set(key, stop);
|
|
2852
|
+
stop.finally(() => {
|
|
2853
|
+
if (this.pendingStops.get(key) === stop) {
|
|
2854
|
+
this.pendingStops.delete(key);
|
|
2855
|
+
}
|
|
2856
|
+
});
|
|
2857
|
+
return stop;
|
|
2858
|
+
}
|
|
2859
|
+
recordDeadGeneration(key) {
|
|
2860
|
+
let budget = this.respawnBudgets.get(key);
|
|
2861
|
+
if (budget === undefined) {
|
|
2862
|
+
budget = { deadGenerations: 0, exhaustedAt: null };
|
|
2863
|
+
this.respawnBudgets.set(key, budget);
|
|
2864
|
+
}
|
|
2865
|
+
budget.deadGenerations += 1;
|
|
2866
|
+
}
|
|
2867
|
+
markHealthyGeneration(key) {
|
|
2868
|
+
this.respawnBudgets.delete(key);
|
|
2869
|
+
}
|
|
2870
|
+
ensureRespawnAllowed(key, root, serverId) {
|
|
2871
|
+
const budget = this.respawnBudgets.get(key);
|
|
2872
|
+
if (budget === undefined || budget.deadGenerations < CLIENT_RESPAWN_RETRY_LIMIT)
|
|
2873
|
+
return;
|
|
2874
|
+
if (budget.exhaustedAt === null) {
|
|
2875
|
+
budget.exhaustedAt = this.now();
|
|
2876
|
+
throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
|
|
2877
|
+
}
|
|
2878
|
+
if (this.now() - budget.exhaustedAt < CLIENT_RESPAWN_COOLDOWN_MS) {
|
|
2879
|
+
throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
|
|
2880
|
+
}
|
|
2881
|
+
budget.deadGenerations = 0;
|
|
2882
|
+
budget.exhaustedAt = null;
|
|
2883
|
+
}
|
|
2804
2884
|
reapStale() {
|
|
2805
2885
|
const t = this.now();
|
|
2806
2886
|
for (const [key, managed] of this.clients) {
|
|
2807
2887
|
if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
|
|
2808
|
-
stopClientBestEffort(managed.client);
|
|
2809
2888
|
this.clients.delete(key);
|
|
2889
|
+
this.tombstoneStop(key, managed.client);
|
|
2810
2890
|
continue;
|
|
2811
2891
|
}
|
|
2812
2892
|
if (!managed.isInitializing && managed.refCount === 0 && managed.pendingWaiters === 0 && t - managed.lastUsedAt > this.idleTimeoutMs) {
|
|
2813
|
-
stopClientBestEffort(managed.client);
|
|
2814
2893
|
this.clients.delete(key);
|
|
2894
|
+
this.tombstoneStop(key, managed.client);
|
|
2815
2895
|
}
|
|
2816
2896
|
}
|
|
2817
2897
|
}
|
|
2898
|
+
evictForAdmission() {
|
|
2899
|
+
while (this.clients.size >= this.maxResidentClients) {
|
|
2900
|
+
const victim = this.leastRecentlyUsedIdleClient();
|
|
2901
|
+
if (!victim)
|
|
2902
|
+
return;
|
|
2903
|
+
this.clients.delete(victim.key);
|
|
2904
|
+
this.tombstoneStop(victim.key, victim.managed.client);
|
|
2905
|
+
}
|
|
2906
|
+
}
|
|
2907
|
+
leastRecentlyUsedIdleClient() {
|
|
2908
|
+
let candidate = null;
|
|
2909
|
+
for (const [key, managed] of this.clients) {
|
|
2910
|
+
if (managed.refCount > 0 || managed.pendingWaiters > 0 || managed.isInitializing)
|
|
2911
|
+
continue;
|
|
2912
|
+
if (candidate === null || managed.lastUsedAt < candidate.managed.lastUsedAt) {
|
|
2913
|
+
candidate = { key, managed };
|
|
2914
|
+
}
|
|
2915
|
+
}
|
|
2916
|
+
return candidate;
|
|
2917
|
+
}
|
|
2818
2918
|
async tryDeleteIfOrphaned(key, managed) {
|
|
2819
2919
|
if (managed.refCount === 0 && managed.pendingWaiters === 0 && !managed.isInitializing && this.clients.get(key) === managed) {
|
|
2820
2920
|
this.clients.delete(key);
|
|
2821
|
-
await
|
|
2921
|
+
await this.tombstoneStop(key, managed.client);
|
|
2822
2922
|
}
|
|
2823
2923
|
}
|
|
2824
2924
|
async getClient(root, server, signal) {
|
|
@@ -2827,12 +2927,22 @@ class LspManager {
|
|
|
2827
2927
|
}
|
|
2828
2928
|
signal?.throwIfAborted();
|
|
2829
2929
|
const key = this.getKey(root, server.id);
|
|
2930
|
+
for (;; ) {
|
|
2931
|
+
const pendingStop = this.pendingStops.get(key);
|
|
2932
|
+
if (pendingStop === undefined)
|
|
2933
|
+
break;
|
|
2934
|
+
await awaitWithSignal(pendingStop, signal);
|
|
2935
|
+
signal?.throwIfAborted();
|
|
2936
|
+
}
|
|
2937
|
+
if (this.disposed) {
|
|
2938
|
+
throw new Error("LspManager has been disposed");
|
|
2939
|
+
}
|
|
2830
2940
|
let managed = this.clients.get(key);
|
|
2831
2941
|
if (managed) {
|
|
2832
2942
|
const t = this.now();
|
|
2833
2943
|
if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
|
|
2834
|
-
await stopClientBestEffort(managed.client);
|
|
2835
2944
|
this.clients.delete(key);
|
|
2945
|
+
await this.tombstoneStop(key, managed.client);
|
|
2836
2946
|
managed = undefined;
|
|
2837
2947
|
}
|
|
2838
2948
|
}
|
|
@@ -2853,14 +2963,20 @@ class LspManager {
|
|
|
2853
2963
|
signal.throwIfAborted();
|
|
2854
2964
|
}
|
|
2855
2965
|
if (!managed.client.isAlive()) {
|
|
2856
|
-
|
|
2857
|
-
this.clients.
|
|
2966
|
+
this.recordDeadGeneration(key);
|
|
2967
|
+
if (this.clients.get(key) === managed) {
|
|
2968
|
+
this.clients.delete(key);
|
|
2969
|
+
}
|
|
2970
|
+
await this.tombstoneStop(key, managed.client);
|
|
2858
2971
|
return this.getClient(root, server, signal);
|
|
2859
2972
|
}
|
|
2973
|
+
this.markHealthyGeneration(key);
|
|
2860
2974
|
managed.refCount++;
|
|
2861
2975
|
managed.lastUsedAt = this.now();
|
|
2862
2976
|
return managed.client;
|
|
2863
2977
|
}
|
|
2978
|
+
this.evictForAdmission();
|
|
2979
|
+
this.ensureRespawnAllowed(key, root, server.id);
|
|
2864
2980
|
const client = this.clientFactory(root, server);
|
|
2865
2981
|
const initStartedAt = this.now();
|
|
2866
2982
|
const initPromise = (async () => {
|
|
@@ -2884,7 +3000,7 @@ class LspManager {
|
|
|
2884
3000
|
if (this.clients.get(key) === newManaged) {
|
|
2885
3001
|
this.clients.delete(key);
|
|
2886
3002
|
}
|
|
2887
|
-
await
|
|
3003
|
+
await this.tombstoneStop(key, client);
|
|
2888
3004
|
throw err;
|
|
2889
3005
|
}
|
|
2890
3006
|
newManaged.pendingWaiters--;
|
|
@@ -2895,6 +3011,15 @@ class LspManager {
|
|
|
2895
3011
|
await this.tryDeleteIfOrphaned(key, newManaged);
|
|
2896
3012
|
signal.throwIfAborted();
|
|
2897
3013
|
}
|
|
3014
|
+
if (!client.isAlive()) {
|
|
3015
|
+
this.recordDeadGeneration(key);
|
|
3016
|
+
if (this.clients.get(key) === newManaged) {
|
|
3017
|
+
this.clients.delete(key);
|
|
3018
|
+
}
|
|
3019
|
+
await this.tombstoneStop(key, client);
|
|
3020
|
+
return this.getClient(root, server, signal);
|
|
3021
|
+
}
|
|
3022
|
+
this.markHealthyGeneration(key);
|
|
2898
3023
|
newManaged.refCount++;
|
|
2899
3024
|
newManaged.lastUsedAt = this.now();
|
|
2900
3025
|
return client;
|
|
@@ -2915,14 +3040,20 @@ class LspManager {
|
|
|
2915
3040
|
if (client && managed.client !== client)
|
|
2916
3041
|
return;
|
|
2917
3042
|
this.clients.delete(key);
|
|
2918
|
-
|
|
3043
|
+
this.tombstoneStop(key, managed.client);
|
|
2919
3044
|
}
|
|
2920
3045
|
warmupClient(root, server) {
|
|
2921
3046
|
if (this.disposed)
|
|
2922
3047
|
return;
|
|
2923
3048
|
const key = this.getKey(root, server.id);
|
|
2924
|
-
if (this.clients.has(key))
|
|
3049
|
+
if (this.clients.has(key) || this.pendingStops.has(key))
|
|
2925
3050
|
return;
|
|
3051
|
+
this.evictForAdmission();
|
|
3052
|
+
try {
|
|
3053
|
+
this.ensureRespawnAllowed(key, root, server.id);
|
|
3054
|
+
} catch {
|
|
3055
|
+
return;
|
|
3056
|
+
}
|
|
2926
3057
|
const client = this.clientFactory(root, server);
|
|
2927
3058
|
const initStartedAt = this.now();
|
|
2928
3059
|
const initPromise = (async () => {
|
|
@@ -2948,7 +3079,7 @@ class LspManager {
|
|
|
2948
3079
|
if (this.clients.get(key) === managed) {
|
|
2949
3080
|
this.clients.delete(key);
|
|
2950
3081
|
}
|
|
2951
|
-
|
|
3082
|
+
this.tombstoneStop(key, client);
|
|
2952
3083
|
});
|
|
2953
3084
|
}
|
|
2954
3085
|
isServerInitializing(root, serverId) {
|
|
@@ -2992,8 +3123,11 @@ class LspManager {
|
|
|
2992
3123
|
for (const managed of this.clients.values()) {
|
|
2993
3124
|
stopPromises.push(stopClientBestEffort(managed.client));
|
|
2994
3125
|
}
|
|
3126
|
+
const tombstonedStops = [...this.pendingStops.values()];
|
|
2995
3127
|
this.clients.clear();
|
|
2996
|
-
|
|
3128
|
+
this.respawnBudgets.clear();
|
|
3129
|
+
await Promise.allSettled([...stopPromises, ...tombstonedStops]);
|
|
3130
|
+
this.pendingStops.clear();
|
|
2997
3131
|
}
|
|
2998
3132
|
}
|
|
2999
3133
|
var _defaultInstance = null;
|
|
@@ -3013,7 +3147,7 @@ async function disposeDefaultLspManager() {
|
|
|
3013
3147
|
// src/daemon-client.ts
|
|
3014
3148
|
import { connect } from "node:net";
|
|
3015
3149
|
import { homedir as homedir3 } from "node:os";
|
|
3016
|
-
import { join as
|
|
3150
|
+
import { join as join8 } from "node:path";
|
|
3017
3151
|
|
|
3018
3152
|
// ../lsp-core/src/request-context.ts
|
|
3019
3153
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
@@ -3022,18 +3156,17 @@ import { homedir } from "node:os";
|
|
|
3022
3156
|
import { basename as basename2, delimiter as delimiter2, dirname as dirname4, isAbsolute as isAbsolute2, join as join2, relative as relative4, resolve as resolve6 } from "node:path";
|
|
3023
3157
|
|
|
3024
3158
|
class LspRequestContextParseError extends Error {
|
|
3025
|
-
code;
|
|
3026
|
-
name = "LspRequestContextParseError";
|
|
3027
3159
|
constructor(code, message) {
|
|
3028
3160
|
super(message);
|
|
3029
3161
|
this.code = code;
|
|
3162
|
+
this.name = "LspRequestContextParseError";
|
|
3030
3163
|
}
|
|
3031
3164
|
}
|
|
3032
3165
|
|
|
3033
3166
|
class LspRequestContextUnavailableError extends Error {
|
|
3034
|
-
name = "LspRequestContextUnavailableError";
|
|
3035
3167
|
constructor() {
|
|
3036
3168
|
super("LSP request context is required. Standalone MCP startup must install one with runWithRequestContext(createStandaloneMcpRequestContext()).");
|
|
3169
|
+
this.name = "LspRequestContextUnavailableError";
|
|
3037
3170
|
}
|
|
3038
3171
|
}
|
|
3039
3172
|
var storage = new AsyncLocalStorage;
|
|
@@ -3053,7 +3186,7 @@ function contextCwd() {
|
|
|
3053
3186
|
}
|
|
3054
3187
|
function createStandaloneMcpRequestContext(input = {}) {
|
|
3055
3188
|
const env = input.env ?? process.env;
|
|
3056
|
-
const cwd = canonicalCwd(input.cwd ?? process.cwd());
|
|
3189
|
+
const cwd = canonicalCwd(input.cwd ?? env["LSP_TOOLS_MCP_CWD"] ?? process.cwd());
|
|
3057
3190
|
const home = input.homeDir ?? homedir();
|
|
3058
3191
|
const projectConfigPaths = translateProjectConfigEnv(env["LSP_TOOLS_MCP_PROJECT_CONFIG"], cwd);
|
|
3059
3192
|
const userConfigPath = translateHomeConfigEnv(env["LSP_TOOLS_MCP_USER_CONFIG"], home, ".codex/lsp-client.json");
|
|
@@ -3191,7 +3324,6 @@ function isPlainRecord(value) {
|
|
|
3191
3324
|
|
|
3192
3325
|
// src/daemon-request-error.ts
|
|
3193
3326
|
class DaemonRequestError extends Error {
|
|
3194
|
-
requestWritten;
|
|
3195
3327
|
constructor(message, requestWritten) {
|
|
3196
3328
|
super(message);
|
|
3197
3329
|
this.name = "DaemonRequestError";
|
|
@@ -3214,7 +3346,6 @@ class DaemonRequestCancelledError extends DaemonRequestError {
|
|
|
3214
3346
|
}
|
|
3215
3347
|
|
|
3216
3348
|
class DaemonRequestTimedOutError extends DaemonRequestError {
|
|
3217
|
-
timeoutMs;
|
|
3218
3349
|
constructor(requestWritten, timeoutMs) {
|
|
3219
3350
|
super("daemon request timed out", requestWritten);
|
|
3220
3351
|
this.name = "DaemonRequestTimedOutError";
|
|
@@ -3293,14 +3424,12 @@ var PROTOCOL_ERROR_CODE = -32002;
|
|
|
3293
3424
|
var AUTH_TOKEN_BYTES = 32;
|
|
3294
3425
|
|
|
3295
3426
|
class UnsafePrivateDirectoryError extends Error {
|
|
3296
|
-
path;
|
|
3297
|
-
reason;
|
|
3298
|
-
name = "UnsafePrivateDirectoryError";
|
|
3299
|
-
code = "unsafe_private_directory";
|
|
3300
3427
|
constructor(path, reason) {
|
|
3301
3428
|
super(`unsafe private directory ${path}: ${reason}`);
|
|
3302
3429
|
this.path = path;
|
|
3303
3430
|
this.reason = reason;
|
|
3431
|
+
this.name = "UnsafePrivateDirectoryError";
|
|
3432
|
+
this.code = "unsafe_private_directory";
|
|
3304
3433
|
}
|
|
3305
3434
|
}
|
|
3306
3435
|
function authEnvelope(token) {
|
|
@@ -3484,20 +3613,18 @@ var OMO_LSP_DAEMON_VERSION = "OMO_LSP_DAEMON_VERSION";
|
|
|
3484
3613
|
var DAEMON_VERSION_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._+-]{0,127}$/;
|
|
3485
3614
|
|
|
3486
3615
|
class InvalidRuntimeOverrideError extends Error {
|
|
3487
|
-
code = "invalid_runtime_override";
|
|
3488
|
-
reason;
|
|
3489
3616
|
constructor(reason, message) {
|
|
3490
3617
|
super(message);
|
|
3618
|
+
this.code = "invalid_runtime_override";
|
|
3491
3619
|
this.name = "InvalidRuntimeOverrideError";
|
|
3492
3620
|
this.reason = reason;
|
|
3493
3621
|
}
|
|
3494
3622
|
}
|
|
3495
3623
|
|
|
3496
3624
|
class InvalidDaemonVersionError extends Error {
|
|
3497
|
-
code = "invalid_daemon_version";
|
|
3498
|
-
version;
|
|
3499
3625
|
constructor(version) {
|
|
3500
3626
|
super("LSP daemon version must match [A-Za-z0-9][A-Za-z0-9._+-]{0,127}");
|
|
3627
|
+
this.code = "invalid_daemon_version";
|
|
3501
3628
|
this.name = "InvalidDaemonVersionError";
|
|
3502
3629
|
this.version = version;
|
|
3503
3630
|
}
|
|
@@ -3543,10 +3670,9 @@ var requireFromHere = createRequire(import.meta.url);
|
|
|
3543
3670
|
var MAX_SOCKET_PATH_LENGTH = 100;
|
|
3544
3671
|
|
|
3545
3672
|
class InvalidDaemonDirectoryError extends Error {
|
|
3546
|
-
code = "invalid_daemon_directory";
|
|
3547
|
-
directory;
|
|
3548
3673
|
constructor(directory) {
|
|
3549
3674
|
super(`${OMO_LSP_DAEMON_DIR} must be an absolute path`);
|
|
3675
|
+
this.code = "invalid_daemon_directory";
|
|
3550
3676
|
this.name = "InvalidDaemonDirectoryError";
|
|
3551
3677
|
this.directory = directory;
|
|
3552
3678
|
}
|
|
@@ -3741,7 +3867,8 @@ function spawnDaemonProcess(paths) {
|
|
|
3741
3867
|
try {
|
|
3742
3868
|
const child = spawn2(resolveDaemonNodeExecutable(), [paths.cliPath, "daemon"], {
|
|
3743
3869
|
detached: true,
|
|
3744
|
-
stdio: ["ignore", logFd, logFd]
|
|
3870
|
+
stdio: ["ignore", logFd, logFd],
|
|
3871
|
+
windowsHide: true
|
|
3745
3872
|
});
|
|
3746
3873
|
child.once("spawn", () => closeSync2(logFd));
|
|
3747
3874
|
child.once("error", (error) => {
|
|
@@ -4022,6 +4149,7 @@ async function runJsonRpcStdioServer(config) {
|
|
|
4022
4149
|
const idleTimer = createIdleTimer(idleTimeoutMs, log, () => {
|
|
4023
4150
|
isClosed = true;
|
|
4024
4151
|
config.onIdleTimeout?.();
|
|
4152
|
+
config.input.destroy();
|
|
4025
4153
|
});
|
|
4026
4154
|
const watchdog = createParentWatchdog(config.parentWatchdog, (parentPid, pollIntervalMs) => {
|
|
4027
4155
|
isClosed = true;
|
|
@@ -4118,7 +4246,11 @@ function createParentWatchdog(config, onDeadParent) {
|
|
|
4118
4246
|
const probeAlive = config.probeAlive ?? isProcessAlive;
|
|
4119
4247
|
let fired = false;
|
|
4120
4248
|
const timer = setInterval(() => {
|
|
4121
|
-
if (fired
|
|
4249
|
+
if (fired)
|
|
4250
|
+
return;
|
|
4251
|
+
const alive = probeAlive(parentPid);
|
|
4252
|
+
config.onPoll?.(alive);
|
|
4253
|
+
if (alive)
|
|
4122
4254
|
return;
|
|
4123
4255
|
fired = true;
|
|
4124
4256
|
onDeadParent(parentPid, pollIntervalMs);
|
|
@@ -4153,60 +4285,55 @@ function createIdleTimer(idleTimeoutMs, log, onTimeout) {
|
|
|
4153
4285
|
};
|
|
4154
4286
|
}
|
|
4155
4287
|
// ../lsp-core/src/lsp/client-wrapper.ts
|
|
4156
|
-
import { existsSync as
|
|
4157
|
-
import { dirname as
|
|
4288
|
+
import { existsSync as existsSync11, realpathSync as realpathSync5, statSync as statSync4 } from "node:fs";
|
|
4289
|
+
import { basename as basename3, dirname as dirname10, join as join5, resolve as resolve8 } from "node:path";
|
|
4158
4290
|
|
|
4159
|
-
// ../lsp-core/src/lsp/
|
|
4160
|
-
import { existsSync as existsSync7,
|
|
4161
|
-
import { dirname as dirname7 } from "node:path";
|
|
4162
|
-
|
|
4163
|
-
|
|
4164
|
-
|
|
4165
|
-
|
|
4166
|
-
|
|
4167
|
-
|
|
4168
|
-
|
|
4169
|
-
|
|
4170
|
-
|
|
4171
|
-
|
|
4172
|
-
|
|
4173
|
-
|
|
4291
|
+
// ../lsp-core/src/lsp/outside-context-workspace.ts
|
|
4292
|
+
import { existsSync as existsSync7, realpathSync as realpathSync4 } from "node:fs";
|
|
4293
|
+
import { dirname as dirname7, join as join3 } from "node:path";
|
|
4294
|
+
|
|
4295
|
+
// ../lsp-core/src/lsp/workspace-markers.ts
|
|
4296
|
+
var GIT_WORKSPACE_MARKER = ".git";
|
|
4297
|
+
var PROJECT_WORKSPACE_MARKERS = [
|
|
4298
|
+
"package.json",
|
|
4299
|
+
"pyproject.toml",
|
|
4300
|
+
"Cargo.toml",
|
|
4301
|
+
"go.mod",
|
|
4302
|
+
"pom.xml",
|
|
4303
|
+
"build.gradle"
|
|
4304
|
+
];
|
|
4305
|
+
var WORKSPACE_MARKERS = [GIT_WORKSPACE_MARKER, ...PROJECT_WORKSPACE_MARKERS];
|
|
4306
|
+
|
|
4307
|
+
// ../lsp-core/src/lsp/outside-context-workspace.ts
|
|
4308
|
+
function findWorkspaceRootOutsideContext(directory) {
|
|
4309
|
+
const marked = nearestMarkedAncestor(directory);
|
|
4310
|
+
if (marked !== undefined)
|
|
4311
|
+
return marked;
|
|
4312
|
+
return realpathSync4(nearestExistingAncestor(directory));
|
|
4313
|
+
}
|
|
4314
|
+
function nearestMarkedAncestor(directory) {
|
|
4315
|
+
let current = directory;
|
|
4316
|
+
for (;; ) {
|
|
4317
|
+
if (existsSync7(current) && WORKSPACE_MARKERS.some((marker) => existsSync7(join3(current, marker)))) {
|
|
4318
|
+
return realpathSync4(current);
|
|
4319
|
+
}
|
|
4320
|
+
const parent = dirname7(current);
|
|
4321
|
+
if (parent === current)
|
|
4322
|
+
return;
|
|
4323
|
+
current = parent;
|
|
4174
4324
|
}
|
|
4175
4325
|
}
|
|
4176
|
-
function
|
|
4177
|
-
|
|
4178
|
-
|
|
4179
|
-
|
|
4180
|
-
|
|
4181
|
-
|
|
4182
|
-
|
|
4183
|
-
}
|
|
4184
|
-
|
|
4185
|
-
return value === "declined" || value === "allowed";
|
|
4186
|
-
}
|
|
4187
|
-
function writeInstallDecisions(decisions) {
|
|
4188
|
-
const path2 = getInstallDecisionsPath();
|
|
4189
|
-
mkdirSync3(dirname7(path2), { recursive: true });
|
|
4190
|
-
const tmpPath = `${path2}.tmp`;
|
|
4191
|
-
writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
|
|
4192
|
-
`, "utf8");
|
|
4193
|
-
renameSync2(tmpPath, path2);
|
|
4194
|
-
}
|
|
4195
|
-
function isInstallDecisions(value) {
|
|
4196
|
-
return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
|
|
4197
|
-
}
|
|
4198
|
-
function isInstallDecisionRecord(value) {
|
|
4199
|
-
if (!isRecord5(value))
|
|
4200
|
-
return false;
|
|
4201
|
-
return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
|
|
4202
|
-
}
|
|
4203
|
-
function isRecord5(value) {
|
|
4204
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4326
|
+
function nearestExistingAncestor(directory) {
|
|
4327
|
+
let current = directory;
|
|
4328
|
+
while (!existsSync7(current)) {
|
|
4329
|
+
const parent = dirname7(current);
|
|
4330
|
+
if (parent === current)
|
|
4331
|
+
return current;
|
|
4332
|
+
current = parent;
|
|
4333
|
+
}
|
|
4334
|
+
return current;
|
|
4205
4335
|
}
|
|
4206
4336
|
|
|
4207
|
-
// ../lsp-core/src/lsp/config-loader.ts
|
|
4208
|
-
import { existsSync as existsSync8, readFileSync as readFileSync5 } from "node:fs";
|
|
4209
|
-
|
|
4210
4337
|
// ../lsp-core/src/lsp/server-definitions.ts
|
|
4211
4338
|
var LSP_INSTALL_HINTS = {
|
|
4212
4339
|
typescript: "npm install -g typescript-language-server typescript",
|
|
@@ -4252,6 +4379,26 @@ var LSP_INSTALL_HINTS = {
|
|
|
4252
4379
|
julials: `julia -e 'using Pkg; Pkg.add("LanguageServer")'`,
|
|
4253
4380
|
razor: "Razor runs through the Roslyn language server (cohosting). " + "Install: dotnet tool install -g roslyn-language-server --prerelease (requires v5.8.0+). See https://github.com/dotnet/razor"
|
|
4254
4381
|
};
|
|
4382
|
+
var LSP_LOCAL_INSTALL_HINTS = {
|
|
4383
|
+
typescript: "bun add -d typescript-language-server typescript",
|
|
4384
|
+
vue: "bun add -d @vue/language-server",
|
|
4385
|
+
eslint: "bun add -d vscode-langservers-extracted",
|
|
4386
|
+
oxlint: "bun add -d oxlint",
|
|
4387
|
+
biome: "bun add -d @biomejs/biome",
|
|
4388
|
+
svelte: "bun add -d svelte-language-server",
|
|
4389
|
+
astro: "bun add -d @astrojs/language-server",
|
|
4390
|
+
bash: "bun add -d bash-language-server",
|
|
4391
|
+
"bash-ls": "bun add -d bash-language-server",
|
|
4392
|
+
"yaml-ls": "bun add -d yaml-language-server",
|
|
4393
|
+
php: "bun add -d intelephense",
|
|
4394
|
+
prisma: "bun add -d prisma",
|
|
4395
|
+
dockerfile: "bun add -d dockerfile-language-server-nodejs",
|
|
4396
|
+
pyright: "uv add --dev pyright",
|
|
4397
|
+
basedpyright: "uv add --dev basedpyright",
|
|
4398
|
+
ruff: "uv add --dev ruff",
|
|
4399
|
+
ty: "uv add --dev ty",
|
|
4400
|
+
"ruby-lsp": "bundle add ruby-lsp --group development"
|
|
4401
|
+
};
|
|
4255
4402
|
var BUILTIN_SERVERS = {
|
|
4256
4403
|
typescript: {
|
|
4257
4404
|
command: ["typescript-language-server", "--stdio"],
|
|
@@ -4354,7 +4501,56 @@ var BUILTIN_SERVERS = {
|
|
|
4354
4501
|
}
|
|
4355
4502
|
};
|
|
4356
4503
|
|
|
4504
|
+
// ../lsp-core/src/lsp/server-install-state.ts
|
|
4505
|
+
import { existsSync as existsSync8, mkdirSync as mkdirSync3, readFileSync as readFileSync4, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
4506
|
+
import { dirname as dirname8 } from "node:path";
|
|
4507
|
+
function getInstallDecisionsPath() {
|
|
4508
|
+
return lspRequestContext().installDecisionsPath;
|
|
4509
|
+
}
|
|
4510
|
+
function loadInstallDecisions() {
|
|
4511
|
+
const path2 = getInstallDecisionsPath();
|
|
4512
|
+
if (!existsSync8(path2))
|
|
4513
|
+
return {};
|
|
4514
|
+
try {
|
|
4515
|
+
const parsed = JSON.parse(readFileSync4(path2, "utf8"));
|
|
4516
|
+
return isInstallDecisions(parsed) ? parsed : {};
|
|
4517
|
+
} catch {
|
|
4518
|
+
return {};
|
|
4519
|
+
}
|
|
4520
|
+
}
|
|
4521
|
+
function loadInstallDecision(serverId) {
|
|
4522
|
+
return loadInstallDecisions()[serverId];
|
|
4523
|
+
}
|
|
4524
|
+
function recordInstallDecision(serverId, decision, decidedAt = new Date().toISOString()) {
|
|
4525
|
+
const decisions = loadInstallDecisions();
|
|
4526
|
+
decisions[serverId] = { decision, decidedAt };
|
|
4527
|
+
writeInstallDecisions(decisions);
|
|
4528
|
+
}
|
|
4529
|
+
function isInstallDecision(value) {
|
|
4530
|
+
return value === "declined" || value === "allowed";
|
|
4531
|
+
}
|
|
4532
|
+
function writeInstallDecisions(decisions) {
|
|
4533
|
+
const path2 = getInstallDecisionsPath();
|
|
4534
|
+
mkdirSync3(dirname8(path2), { recursive: true });
|
|
4535
|
+
const tmpPath = `${path2}.tmp`;
|
|
4536
|
+
writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
|
|
4537
|
+
`, "utf8");
|
|
4538
|
+
renameSync2(tmpPath, path2);
|
|
4539
|
+
}
|
|
4540
|
+
function isInstallDecisions(value) {
|
|
4541
|
+
return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
|
|
4542
|
+
}
|
|
4543
|
+
function isInstallDecisionRecord(value) {
|
|
4544
|
+
if (!isRecord5(value))
|
|
4545
|
+
return false;
|
|
4546
|
+
return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
|
|
4547
|
+
}
|
|
4548
|
+
function isRecord5(value) {
|
|
4549
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4550
|
+
}
|
|
4551
|
+
|
|
4357
4552
|
// ../lsp-core/src/lsp/config-loader.ts
|
|
4553
|
+
import { existsSync as existsSync9, readFileSync as readFileSync5 } from "node:fs";
|
|
4358
4554
|
function getProjectConfigPaths() {
|
|
4359
4555
|
return lspRequestContext().projectConfigPaths;
|
|
4360
4556
|
}
|
|
@@ -4362,7 +4558,7 @@ function getUserConfigPath() {
|
|
|
4362
4558
|
return lspRequestContext().userConfigPath;
|
|
4363
4559
|
}
|
|
4364
4560
|
function loadJsonFile(path2) {
|
|
4365
|
-
if (!
|
|
4561
|
+
if (!existsSync9(path2))
|
|
4366
4562
|
return null;
|
|
4367
4563
|
try {
|
|
4368
4564
|
const parsed = JSON.parse(readFileSync5(path2, "utf-8"));
|
|
@@ -4550,54 +4746,155 @@ function getDisabledServerIds() {
|
|
|
4550
4746
|
}
|
|
4551
4747
|
|
|
4552
4748
|
// ../lsp-core/src/lsp/server-installation.ts
|
|
4553
|
-
import { existsSync as
|
|
4554
|
-
import { delimiter as delimiter3, join as
|
|
4555
|
-
|
|
4556
|
-
|
|
4557
|
-
|
|
4558
|
-
|
|
4559
|
-
|
|
4560
|
-
|
|
4561
|
-
|
|
4562
|
-
|
|
4563
|
-
|
|
4749
|
+
import { existsSync as existsSync10 } from "node:fs";
|
|
4750
|
+
import { delimiter as delimiter3, dirname as dirname9, isAbsolute as isAbsolute5, join as join4, resolve as resolve7 } from "node:path";
|
|
4751
|
+
var LOCAL_BIN_RULES = [
|
|
4752
|
+
{
|
|
4753
|
+
markers: ["package.json", "bun.lock", "bun.lockb", "package-lock.json", "yarn.lock", "pnpm-lock.yaml"],
|
|
4754
|
+
binDirs: [join4("node_modules", ".bin")]
|
|
4755
|
+
},
|
|
4756
|
+
{
|
|
4757
|
+
markers: [
|
|
4758
|
+
"pyproject.toml",
|
|
4759
|
+
"ty.toml",
|
|
4760
|
+
"requirements.txt",
|
|
4761
|
+
"setup.py",
|
|
4762
|
+
"setup.cfg",
|
|
4763
|
+
"Pipfile",
|
|
4764
|
+
"pyrightconfig.json",
|
|
4765
|
+
"ruff.toml",
|
|
4766
|
+
".ruff.toml"
|
|
4767
|
+
],
|
|
4768
|
+
binDirs: [
|
|
4769
|
+
join4(".venv", "bin"),
|
|
4770
|
+
join4(".venv", "Scripts"),
|
|
4771
|
+
join4("venv", "bin"),
|
|
4772
|
+
join4("venv", "Scripts"),
|
|
4773
|
+
join4(".env", "bin"),
|
|
4774
|
+
join4(".env", "Scripts")
|
|
4775
|
+
]
|
|
4776
|
+
},
|
|
4777
|
+
{
|
|
4778
|
+
markers: ["Gemfile", "Gemfile.lock"],
|
|
4779
|
+
binDirs: [join4("vendor", "bundle", "bin"), "bin"]
|
|
4780
|
+
},
|
|
4781
|
+
{
|
|
4782
|
+
markers: ["go.mod", "go.sum", "go.work"],
|
|
4783
|
+
binDirs: ["bin"]
|
|
4564
4784
|
}
|
|
4565
|
-
|
|
4566
|
-
|
|
4567
|
-
|
|
4568
|
-
|
|
4569
|
-
|
|
4570
|
-
|
|
4571
|
-
|
|
4572
|
-
|
|
4573
|
-
|
|
4785
|
+
];
|
|
4786
|
+
var resolutionCache = new Map;
|
|
4787
|
+
var probeCount = 0;
|
|
4788
|
+
function probe(path2) {
|
|
4789
|
+
probeCount += 1;
|
|
4790
|
+
return existsSync10(path2);
|
|
4791
|
+
}
|
|
4792
|
+
function executableSuffixes(platform, pathExt) {
|
|
4793
|
+
if (platform !== "win32")
|
|
4794
|
+
return [""];
|
|
4795
|
+
const configured = pathExt ?? process.env["PATHEXT"] ?? "";
|
|
4796
|
+
const systemExts = configured.split(";").filter((entry) => entry.length > 0).map((entry) => entry.toLowerCase());
|
|
4797
|
+
return [...new Set(["", ...systemExts, ".exe", ".cmd", ".bat", ".ps1"])];
|
|
4798
|
+
}
|
|
4799
|
+
function probeWithSuffixes(directory, command, suffixes) {
|
|
4800
|
+
for (const suffix of suffixes) {
|
|
4801
|
+
const candidate = join4(directory, command + suffix);
|
|
4802
|
+
if (probe(candidate))
|
|
4803
|
+
return candidate;
|
|
4804
|
+
}
|
|
4805
|
+
return null;
|
|
4806
|
+
}
|
|
4807
|
+
function resolveLocal(command, workingDirectory, suffixes, stopAt) {
|
|
4808
|
+
const boundary = stopAt === undefined ? undefined : resolve7(stopAt);
|
|
4809
|
+
let current = resolve7(workingDirectory);
|
|
4810
|
+
while (true) {
|
|
4811
|
+
for (const rule of LOCAL_BIN_RULES) {
|
|
4812
|
+
if (!rule.markers.some((marker) => probe(join4(current, marker))))
|
|
4813
|
+
continue;
|
|
4814
|
+
for (const binDir of rule.binDirs) {
|
|
4815
|
+
const found = probeWithSuffixes(join4(current, binDir), command, suffixes);
|
|
4816
|
+
if (found !== null)
|
|
4817
|
+
return found;
|
|
4818
|
+
}
|
|
4574
4819
|
}
|
|
4820
|
+
if (probe(join4(current, ".git")))
|
|
4821
|
+
return null;
|
|
4822
|
+
if (boundary !== undefined && current === boundary)
|
|
4823
|
+
return null;
|
|
4824
|
+
const parent = dirname9(current);
|
|
4825
|
+
if (parent === current)
|
|
4826
|
+
return null;
|
|
4827
|
+
current = parent;
|
|
4575
4828
|
}
|
|
4576
|
-
|
|
4577
|
-
|
|
4829
|
+
}
|
|
4830
|
+
function resolveFromPath(command, suffixes, platform, pathEnvOverride) {
|
|
4831
|
+
let pathEnv = pathEnvOverride ?? process.env["PATH"] ?? "";
|
|
4832
|
+
if (platform === "win32" && !pathEnv) {
|
|
4578
4833
|
pathEnv = process.env["Path"] ?? "";
|
|
4579
4834
|
}
|
|
4580
|
-
const
|
|
4581
|
-
|
|
4582
|
-
|
|
4583
|
-
|
|
4584
|
-
|
|
4585
|
-
|
|
4586
|
-
}
|
|
4835
|
+
for (const entry of pathEnv.split(delimiter3)) {
|
|
4836
|
+
if (entry.length === 0)
|
|
4837
|
+
continue;
|
|
4838
|
+
const found = probeWithSuffixes(entry, command, suffixes);
|
|
4839
|
+
if (found !== null)
|
|
4840
|
+
return found;
|
|
4587
4841
|
}
|
|
4588
|
-
|
|
4589
|
-
|
|
4590
|
-
|
|
4842
|
+
return null;
|
|
4843
|
+
}
|
|
4844
|
+
function resolveServerBinary(command, workingDirectory, options = {}) {
|
|
4845
|
+
if (command.length === 0)
|
|
4846
|
+
return null;
|
|
4847
|
+
const [cmd] = command;
|
|
4848
|
+
if (cmd === undefined || cmd.length === 0)
|
|
4849
|
+
return null;
|
|
4850
|
+
const platform = options.platform ?? process.platform;
|
|
4851
|
+
const suffixes = executableSuffixes(platform, options.pathExt);
|
|
4852
|
+
if (cmd.includes("/") || cmd.includes("\\")) {
|
|
4853
|
+
const explicit = isAbsolute5(cmd) ? cmd : resolve7(workingDirectory ?? process.cwd(), cmd);
|
|
4854
|
+
return probe(explicit) ? explicit : null;
|
|
4855
|
+
}
|
|
4856
|
+
const cacheKey = JSON.stringify([
|
|
4857
|
+
workingDirectory ?? "",
|
|
4858
|
+
cmd,
|
|
4859
|
+
platform,
|
|
4860
|
+
options.stopAt ?? "",
|
|
4861
|
+
options.pathExt ?? "",
|
|
4862
|
+
options.pathEnv ?? process.env["PATH"] ?? ""
|
|
4863
|
+
]);
|
|
4864
|
+
const cached = resolutionCache.get(cacheKey);
|
|
4865
|
+
if (cached !== undefined)
|
|
4866
|
+
return cached;
|
|
4867
|
+
let resolved = null;
|
|
4868
|
+
if (workingDirectory !== undefined && workingDirectory.length > 0) {
|
|
4869
|
+
resolved = resolveLocal(cmd, workingDirectory, suffixes, options.stopAt);
|
|
4870
|
+
}
|
|
4871
|
+
resolved ??= resolveFromPath(cmd, suffixes, platform, options.pathEnv);
|
|
4872
|
+
if (resolved === null && cmd === "node")
|
|
4873
|
+
resolved = cmd;
|
|
4874
|
+
resolutionCache.set(cacheKey, resolved);
|
|
4875
|
+
return resolved;
|
|
4876
|
+
}
|
|
4877
|
+
function isServerInstalled(command, workingDirectory, options = {}) {
|
|
4878
|
+
if (command.length === 0)
|
|
4879
|
+
return false;
|
|
4880
|
+
return resolveServerBinary(command, workingDirectory, options) !== null;
|
|
4591
4881
|
}
|
|
4592
4882
|
|
|
4593
4883
|
// ../lsp-core/src/lsp/server-resolution.ts
|
|
4884
|
+
function withResolvedCommand(command, binaryPath) {
|
|
4885
|
+
return [binaryPath, ...command.slice(1)];
|
|
4886
|
+
}
|
|
4594
4887
|
function findServerForExtension(ext) {
|
|
4595
4888
|
const servers = getMergedServers();
|
|
4889
|
+
const workingDirectory = contextCwd();
|
|
4596
4890
|
for (const server2 of servers) {
|
|
4597
|
-
if (server2.extensions.includes(ext)
|
|
4891
|
+
if (!server2.extensions.includes(ext))
|
|
4892
|
+
continue;
|
|
4893
|
+
const binaryPath = resolveServerBinary(server2.command, workingDirectory);
|
|
4894
|
+
if (binaryPath !== null) {
|
|
4598
4895
|
const resolvedServer = {
|
|
4599
4896
|
id: server2.id,
|
|
4600
|
-
command: server2.command,
|
|
4897
|
+
command: withResolvedCommand(server2.command, binaryPath),
|
|
4601
4898
|
extensions: server2.extensions,
|
|
4602
4899
|
priority: server2.priority
|
|
4603
4900
|
};
|
|
@@ -4644,6 +4941,7 @@ function findServerForExtension(ext) {
|
|
|
4644
4941
|
function getAllServers() {
|
|
4645
4942
|
const servers = getMergedServers();
|
|
4646
4943
|
const disabled = getDisabledServerIds();
|
|
4944
|
+
const workingDirectory = contextCwd();
|
|
4647
4945
|
const result = [];
|
|
4648
4946
|
const seen = new Set;
|
|
4649
4947
|
for (const server2 of servers) {
|
|
@@ -4651,7 +4949,7 @@ function getAllServers() {
|
|
|
4651
4949
|
continue;
|
|
4652
4950
|
result.push({
|
|
4653
4951
|
id: server2.id,
|
|
4654
|
-
installed: isServerInstalled(server2.command),
|
|
4952
|
+
installed: isServerInstalled(server2.command, workingDirectory),
|
|
4655
4953
|
extensions: server2.extensions,
|
|
4656
4954
|
disabled: false,
|
|
4657
4955
|
source: server2.source,
|
|
@@ -4665,7 +4963,7 @@ function getAllServers() {
|
|
|
4665
4963
|
const builtin = BUILTIN_SERVERS[id];
|
|
4666
4964
|
result.push({
|
|
4667
4965
|
id,
|
|
4668
|
-
installed: builtin ? isServerInstalled(builtin.command) : false,
|
|
4966
|
+
installed: builtin ? isServerInstalled(builtin.command, workingDirectory) : false,
|
|
4669
4967
|
extensions: builtin?.extensions ?? [],
|
|
4670
4968
|
disabled: true,
|
|
4671
4969
|
source: "disabled",
|
|
@@ -4676,7 +4974,6 @@ function getAllServers() {
|
|
|
4676
4974
|
}
|
|
4677
4975
|
|
|
4678
4976
|
// ../lsp-core/src/lsp/client-wrapper.ts
|
|
4679
|
-
var WORKSPACE_MARKERS = [".git", "package.json", "pyproject.toml", "Cargo.toml", "go.mod", "pom.xml", "build.gradle"];
|
|
4680
4977
|
function isDirectoryPath(filePath) {
|
|
4681
4978
|
try {
|
|
4682
4979
|
return statSync4(filePath).isDirectory();
|
|
@@ -4685,32 +4982,90 @@ function isDirectoryPath(filePath) {
|
|
|
4685
4982
|
}
|
|
4686
4983
|
}
|
|
4687
4984
|
function findWorkspaceRoot(filePath) {
|
|
4688
|
-
const
|
|
4985
|
+
const cwd = contextCwd();
|
|
4986
|
+
const abs = resolveReadablePathInsideContext(filePath);
|
|
4689
4987
|
let dir = abs;
|
|
4690
4988
|
if (!isDirectoryPath(dir)) {
|
|
4691
|
-
dir =
|
|
4692
|
-
}
|
|
4693
|
-
|
|
4694
|
-
|
|
4695
|
-
|
|
4696
|
-
|
|
4697
|
-
|
|
4989
|
+
dir = dirname10(dir);
|
|
4990
|
+
}
|
|
4991
|
+
if (!isPathInside(cwd, abs))
|
|
4992
|
+
return findWorkspaceRootOutsideContext(dir);
|
|
4993
|
+
const fallbackRoot = nearestExistingDirectoryInsideContext(dir, cwd) ?? cwd;
|
|
4994
|
+
let nearestPackageRoot;
|
|
4995
|
+
while (isPathInside(cwd, dir)) {
|
|
4996
|
+
const canonicalDir = existingDirectoryInsideContext(dir, cwd);
|
|
4997
|
+
if (canonicalDir !== undefined) {
|
|
4998
|
+
if (existsSync11(join5(dir, GIT_WORKSPACE_MARKER))) {
|
|
4999
|
+
return canonicalDir;
|
|
5000
|
+
}
|
|
5001
|
+
if (nearestPackageRoot === undefined && hasProjectWorkspaceMarker(dir)) {
|
|
5002
|
+
nearestPackageRoot = canonicalDir;
|
|
4698
5003
|
}
|
|
4699
5004
|
}
|
|
4700
|
-
|
|
4701
|
-
|
|
5005
|
+
if (dir === cwd)
|
|
5006
|
+
break;
|
|
5007
|
+
dir = dirname10(dir);
|
|
4702
5008
|
}
|
|
4703
|
-
return
|
|
5009
|
+
return nearestPackageRoot ?? fallbackRoot;
|
|
5010
|
+
}
|
|
5011
|
+
function hasProjectWorkspaceMarker(directory) {
|
|
5012
|
+
return PROJECT_WORKSPACE_MARKERS.some((marker) => existsSync11(join5(directory, marker)));
|
|
5013
|
+
}
|
|
5014
|
+
function resolveReadablePathInsideContext(filePath) {
|
|
5015
|
+
const cwd = contextCwd();
|
|
5016
|
+
const abs = resolve8(cwd, filePath);
|
|
5017
|
+
if (isPathInside(cwd, abs))
|
|
5018
|
+
return abs;
|
|
5019
|
+
const rebased = rebaseThroughCanonicalAncestor(abs, cwd);
|
|
5020
|
+
if (rebased !== undefined)
|
|
5021
|
+
return rebased;
|
|
5022
|
+
return canonicalizeExistingOrNearestAncestor(abs);
|
|
4704
5023
|
}
|
|
4705
5024
|
function resolvePathInsideContext(filePath) {
|
|
4706
5025
|
const cwd = contextCwd();
|
|
4707
|
-
const abs =
|
|
5026
|
+
const abs = resolveReadablePathInsideContext(filePath);
|
|
4708
5027
|
const canonical = canonicalizeExistingOrNearestAncestor(abs);
|
|
4709
5028
|
if (!isPathInside(cwd, canonical)) {
|
|
4710
5029
|
throw new LspInvalidPathError(`LSP file path must be inside request cwd: ${filePath}`);
|
|
4711
5030
|
}
|
|
4712
5031
|
return canonical;
|
|
4713
5032
|
}
|
|
5033
|
+
function rebaseThroughCanonicalAncestor(path2, cwd) {
|
|
5034
|
+
let current = path2;
|
|
5035
|
+
const suffix = [];
|
|
5036
|
+
while (true) {
|
|
5037
|
+
if (existsSync11(current)) {
|
|
5038
|
+
const canonical = realpathSync5(current);
|
|
5039
|
+
if (isPathInside(cwd, canonical))
|
|
5040
|
+
return suffix.length === 0 ? canonical : join5(canonical, ...suffix);
|
|
5041
|
+
}
|
|
5042
|
+
const parent = dirname10(current);
|
|
5043
|
+
if (parent === current)
|
|
5044
|
+
return;
|
|
5045
|
+
suffix.unshift(basename3(current));
|
|
5046
|
+
current = parent;
|
|
5047
|
+
}
|
|
5048
|
+
}
|
|
5049
|
+
function existingDirectoryInsideContext(directory, cwd) {
|
|
5050
|
+
if (!existsSync11(directory))
|
|
5051
|
+
return;
|
|
5052
|
+
const canonical = realpathSync5(directory);
|
|
5053
|
+
if (!statSync4(canonical).isDirectory())
|
|
5054
|
+
return;
|
|
5055
|
+
return isPathInside(cwd, canonical) ? canonical : undefined;
|
|
5056
|
+
}
|
|
5057
|
+
function nearestExistingDirectoryInsideContext(directory, cwd) {
|
|
5058
|
+
let current = directory;
|
|
5059
|
+
while (isPathInside(cwd, current)) {
|
|
5060
|
+
const canonical = existingDirectoryInsideContext(current, cwd);
|
|
5061
|
+
if (canonical !== undefined)
|
|
5062
|
+
return canonical;
|
|
5063
|
+
if (current === cwd)
|
|
5064
|
+
return;
|
|
5065
|
+
current = dirname10(current);
|
|
5066
|
+
}
|
|
5067
|
+
return;
|
|
5068
|
+
}
|
|
4714
5069
|
function formatServerLookupError(result) {
|
|
4715
5070
|
if (result.status === "not_installed") {
|
|
4716
5071
|
return formatNotInstalled(result);
|
|
@@ -4734,6 +5089,19 @@ function formatServerLookupError(result) {
|
|
|
4734
5089
|
].join(`
|
|
4735
5090
|
`);
|
|
4736
5091
|
}
|
|
5092
|
+
function formatInstallOptions(serverId, installHint) {
|
|
5093
|
+
const localHint = LSP_LOCAL_INSTALL_HINTS[serverId];
|
|
5094
|
+
if (localHint === undefined) {
|
|
5095
|
+
return ["To install, run:", ` ${installHint}`];
|
|
5096
|
+
}
|
|
5097
|
+
return [
|
|
5098
|
+
"To install in THIS repository (preferred — no global install needed):",
|
|
5099
|
+
` ${localHint}`,
|
|
5100
|
+
"",
|
|
5101
|
+
"Or install it globally:",
|
|
5102
|
+
` ${installHint}`
|
|
5103
|
+
];
|
|
5104
|
+
}
|
|
4737
5105
|
function formatNotInstalled(result) {
|
|
4738
5106
|
const { server: server2, installHint } = result;
|
|
4739
5107
|
const extensions = server2.extensions.join(", ");
|
|
@@ -4748,19 +5116,19 @@ function formatNotInstalled(result) {
|
|
|
4748
5116
|
`Command not found: ${server2.command[0]}`,
|
|
4749
5117
|
""
|
|
4750
5118
|
];
|
|
5119
|
+
const installOptions = formatInstallOptions(server2.id, installHint);
|
|
4751
5120
|
if (decision === "allowed") {
|
|
4752
5121
|
return [
|
|
4753
5122
|
...header,
|
|
4754
5123
|
"The user has pre-authorized LSP installation. Run the install command, then retry this tool:",
|
|
4755
|
-
|
|
5124
|
+
...installOptions.slice(1)
|
|
4756
5125
|
].join(`
|
|
4757
5126
|
`);
|
|
4758
5127
|
}
|
|
4759
5128
|
if (!context.capabilities.installDecisionTool) {
|
|
4760
5129
|
return [
|
|
4761
5130
|
...header,
|
|
4762
|
-
|
|
4763
|
-
` ${installHint}`,
|
|
5131
|
+
...installOptions,
|
|
4764
5132
|
"",
|
|
4765
5133
|
"ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
|
|
4766
5134
|
"Install-decision recording is unavailable in this harness; proceed without LSP if the user declines."
|
|
@@ -4769,8 +5137,7 @@ function formatNotInstalled(result) {
|
|
|
4769
5137
|
}
|
|
4770
5138
|
return [
|
|
4771
5139
|
...header,
|
|
4772
|
-
|
|
4773
|
-
` ${installHint}`,
|
|
5140
|
+
...installOptions,
|
|
4774
5141
|
"",
|
|
4775
5142
|
"ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
|
|
4776
5143
|
"- If the user agrees: run the install command above, then retry this tool.",
|
|
@@ -4781,7 +5148,7 @@ function formatNotInstalled(result) {
|
|
|
4781
5148
|
].join(`
|
|
4782
5149
|
`);
|
|
4783
5150
|
}
|
|
4784
|
-
var
|
|
5151
|
+
var READ_ONLY_TOOLS = new Set([
|
|
4785
5152
|
"diagnostics",
|
|
4786
5153
|
"definition",
|
|
4787
5154
|
"references",
|
|
@@ -4790,7 +5157,7 @@ var READ_ONLY_RETRY_TOOLS = new Set([
|
|
|
4790
5157
|
"prepareRename"
|
|
4791
5158
|
]);
|
|
4792
5159
|
async function withLspClient(filePath, fn, toolName, options = {}) {
|
|
4793
|
-
const absPath = resolvePathInsideContext(filePath);
|
|
5160
|
+
const absPath = READ_ONLY_TOOLS.has(toolName) ? resolveReadablePathInsideContext(filePath) : resolvePathInsideContext(filePath);
|
|
4794
5161
|
if (isDirectoryPath(absPath)) {
|
|
4795
5162
|
throw new LspInvalidPathError("Directory paths are not supported by this LSP tool. " + "Use lsp.diagnostics with a directory path for directory diagnostics.");
|
|
4796
5163
|
}
|
|
@@ -4805,9 +5172,9 @@ async function withLspClient(filePath, fn, toolName, options = {}) {
|
|
|
4805
5172
|
const acquireAndCall = async (allowRetry) => {
|
|
4806
5173
|
const client = await manager.getClient(root, server2, options.signal);
|
|
4807
5174
|
try {
|
|
4808
|
-
return await fn(client, root);
|
|
5175
|
+
return await fn(client, root, absPath);
|
|
4809
5176
|
} catch (err) {
|
|
4810
|
-
if (allowRetry &&
|
|
5177
|
+
if (allowRetry && READ_ONLY_TOOLS.has(toolName) && isLspDeadConnectionError(err)) {
|
|
4811
5178
|
manager.invalidateClient(root, server2.id, client);
|
|
4812
5179
|
return acquireAndCall(false);
|
|
4813
5180
|
}
|
|
@@ -4825,8 +5192,8 @@ async function withLspClient(filePath, fn, toolName, options = {}) {
|
|
|
4825
5192
|
}
|
|
4826
5193
|
|
|
4827
5194
|
// ../lsp-core/src/lsp/directory-diagnostics.ts
|
|
4828
|
-
import { existsSync as
|
|
4829
|
-
import { join as
|
|
5195
|
+
import { existsSync as existsSync12, lstatSync as lstatSync5, readdirSync as readdirSync3 } from "node:fs";
|
|
5196
|
+
import { join as join6, resolve as resolve9 } from "node:path";
|
|
4830
5197
|
|
|
4831
5198
|
// ../lsp-core/src/lsp/formatters.ts
|
|
4832
5199
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
@@ -4956,7 +5323,7 @@ function collectFilesWithExtension(dir, extension, maxFiles) {
|
|
|
4956
5323
|
for (const entry of entries) {
|
|
4957
5324
|
if (files.length >= maxFiles)
|
|
4958
5325
|
return;
|
|
4959
|
-
const fullPath =
|
|
5326
|
+
const fullPath = join6(currentDir, entry);
|
|
4960
5327
|
let stat;
|
|
4961
5328
|
try {
|
|
4962
5329
|
stat = lstatSync5(fullPath);
|
|
@@ -4981,8 +5348,8 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
|
|
|
4981
5348
|
if (!extension.startsWith(".")) {
|
|
4982
5349
|
throw new LspInvalidPathError(`Extension must start with a dot (e.g., ".ts", not "${extension}"). Use ".${extension}" instead.`);
|
|
4983
5350
|
}
|
|
4984
|
-
const absDir =
|
|
4985
|
-
if (!
|
|
5351
|
+
const absDir = resolve9(options.workspaceRoot ?? contextCwd(), directory);
|
|
5352
|
+
if (!existsSync12(absDir)) {
|
|
4986
5353
|
throw new LspInvalidPathError(`Directory does not exist: ${absDir}`);
|
|
4987
5354
|
}
|
|
4988
5355
|
const serverResult = options.server === undefined ? findServerForExtension(extension) : { status: "found", server: options.server };
|
|
@@ -5069,7 +5436,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
|
|
|
5069
5436
|
|
|
5070
5437
|
// ../lsp-core/src/lsp/infer-extension.ts
|
|
5071
5438
|
import { lstatSync as lstatSync6, readdirSync as readdirSync4 } from "node:fs";
|
|
5072
|
-
import { join as
|
|
5439
|
+
import { join as join7 } from "node:path";
|
|
5073
5440
|
var SKIP_DIRECTORIES2 = new Set(["node_modules", ".git", "dist", "build", ".next", "out"]);
|
|
5074
5441
|
var MAX_SCAN_ENTRIES = 500;
|
|
5075
5442
|
function inferExtensionFromDirectory(directory) {
|
|
@@ -5087,7 +5454,7 @@ function inferExtensionFromDirectory(directory) {
|
|
|
5087
5454
|
for (const entry of entries) {
|
|
5088
5455
|
if (scanned >= MAX_SCAN_ENTRIES)
|
|
5089
5456
|
return;
|
|
5090
|
-
const fullPath =
|
|
5457
|
+
const fullPath = join7(dir, entry);
|
|
5091
5458
|
let stat;
|
|
5092
5459
|
try {
|
|
5093
5460
|
stat = lstatSync6(fullPath);
|
|
@@ -5262,7 +5629,7 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
5262
5629
|
const filePath = requireString(params, "filePath");
|
|
5263
5630
|
const severity = severityFilter(params);
|
|
5264
5631
|
try {
|
|
5265
|
-
const absPath =
|
|
5632
|
+
const absPath = resolveReadablePathInsideContext(filePath);
|
|
5266
5633
|
if (isDirectoryPath(absPath)) {
|
|
5267
5634
|
const extension = inferExtensionFromDirectory(absPath);
|
|
5268
5635
|
if (!extension) {
|
|
@@ -5291,7 +5658,7 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
5291
5658
|
};
|
|
5292
5659
|
return text(output2.output, details2);
|
|
5293
5660
|
}
|
|
5294
|
-
const result = await withLspClient(filePath, async (client) => client.diagnostics(
|
|
5661
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.diagnostics(resolvedFilePath, signal), "diagnostics", clientOptions(signal));
|
|
5295
5662
|
if (result.transientError) {
|
|
5296
5663
|
const message = result.transientError.message;
|
|
5297
5664
|
const details2 = {
|
|
@@ -5338,6 +5705,96 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
5338
5705
|
throw error;
|
|
5339
5706
|
}
|
|
5340
5707
|
}
|
|
5708
|
+
// ../lsp-core/src/lsp/format-document.ts
|
|
5709
|
+
import { readFileSync as readFileSync6, renameSync as renameSync3, unlinkSync as unlinkSync2, writeFileSync as writeFileSync3 } from "node:fs";
|
|
5710
|
+
var DEFAULT_FORMATTING_OPTIONS = {
|
|
5711
|
+
tabSize: 4,
|
|
5712
|
+
insertSpaces: false,
|
|
5713
|
+
trimTrailingWhitespace: true,
|
|
5714
|
+
insertFinalNewline: true,
|
|
5715
|
+
trimFinalNewlines: true
|
|
5716
|
+
};
|
|
5717
|
+
var UNCHANGED = { status: "unchanged", linesAdded: 0, linesRemoved: 0 };
|
|
5718
|
+
async function formatDocumentWithClient(client, filePath, options = {}) {
|
|
5719
|
+
const edits = await client.formatDocument(filePath, options.formattingOptions ?? DEFAULT_FORMATTING_OPTIONS, options.signal);
|
|
5720
|
+
if (edits === null)
|
|
5721
|
+
return { status: "unavailable", reason: "capability_not_advertised" };
|
|
5722
|
+
if (edits.length === 0)
|
|
5723
|
+
return UNCHANGED;
|
|
5724
|
+
const before = readFileSync6(filePath, "utf-8");
|
|
5725
|
+
const normalized = normalizeTextEdits(before, edits, 0);
|
|
5726
|
+
if (normalized.text === before)
|
|
5727
|
+
return UNCHANGED;
|
|
5728
|
+
writeAtomically(filePath, normalized.text);
|
|
5729
|
+
await client.openFile(filePath);
|
|
5730
|
+
return {
|
|
5731
|
+
status: "formatted",
|
|
5732
|
+
...lineDelta(normalized.edits)
|
|
5733
|
+
};
|
|
5734
|
+
}
|
|
5735
|
+
function lineDelta(edits) {
|
|
5736
|
+
let linesAdded = 0;
|
|
5737
|
+
let linesRemoved = 0;
|
|
5738
|
+
for (const edit of edits) {
|
|
5739
|
+
linesRemoved += edit.range.end.line - edit.range.start.line + 1;
|
|
5740
|
+
linesAdded += edit.newText.split(`
|
|
5741
|
+
`).length;
|
|
5742
|
+
}
|
|
5743
|
+
return { linesAdded, linesRemoved };
|
|
5744
|
+
}
|
|
5745
|
+
function writeAtomically(filePath, content) {
|
|
5746
|
+
const tempPath = `${filePath}.omo-format.tmp`;
|
|
5747
|
+
writeFileSync3(tempPath, content, "utf-8");
|
|
5748
|
+
try {
|
|
5749
|
+
renameSync3(tempPath, filePath);
|
|
5750
|
+
} catch (error) {
|
|
5751
|
+
try {
|
|
5752
|
+
unlinkSync2(tempPath);
|
|
5753
|
+
} catch {}
|
|
5754
|
+
throw error;
|
|
5755
|
+
}
|
|
5756
|
+
}
|
|
5757
|
+
|
|
5758
|
+
// ../lsp-core/src/tools/format.ts
|
|
5759
|
+
async function executeLspFormat(params, signal) {
|
|
5760
|
+
const filePath = requireString(params, "filePath");
|
|
5761
|
+
try {
|
|
5762
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => formatDocumentWithClient(client, resolvedFilePath, signal === undefined ? {} : { signal }), "format", clientOptions(signal));
|
|
5763
|
+
return text(describeResult(filePath, result), formatDetails(filePath, result));
|
|
5764
|
+
} catch (error) {
|
|
5765
|
+
const missingDependency = missingDependencyResult(error, {
|
|
5766
|
+
filePath,
|
|
5767
|
+
status: "unavailable",
|
|
5768
|
+
reason: "server_unavailable",
|
|
5769
|
+
linesAdded: 0,
|
|
5770
|
+
linesRemoved: 0
|
|
5771
|
+
});
|
|
5772
|
+
if (missingDependency)
|
|
5773
|
+
return missingDependency;
|
|
5774
|
+
throw error;
|
|
5775
|
+
}
|
|
5776
|
+
}
|
|
5777
|
+
function formatDetails(filePath, result) {
|
|
5778
|
+
if (result.status === "unavailable") {
|
|
5779
|
+
return { filePath, status: "unavailable", reason: result.reason, linesAdded: 0, linesRemoved: 0 };
|
|
5780
|
+
}
|
|
5781
|
+
return {
|
|
5782
|
+
filePath,
|
|
5783
|
+
status: result.status,
|
|
5784
|
+
linesAdded: result.linesAdded,
|
|
5785
|
+
linesRemoved: result.linesRemoved
|
|
5786
|
+
};
|
|
5787
|
+
}
|
|
5788
|
+
function describeResult(filePath, result) {
|
|
5789
|
+
if (result.status === "unavailable") {
|
|
5790
|
+
return `Formatting unavailable for ${filePath}: the language server does not advertise documentFormattingProvider.`;
|
|
5791
|
+
}
|
|
5792
|
+
if (result.status === "unchanged") {
|
|
5793
|
+
return `Already formatted: ${filePath}`;
|
|
5794
|
+
}
|
|
5795
|
+
return `Formatted ${filePath} (+${result.linesAdded}/-${result.linesRemoved} lines)`;
|
|
5796
|
+
}
|
|
5797
|
+
|
|
5341
5798
|
// ../lsp-core/src/tools/install-decision.ts
|
|
5342
5799
|
async function executeLspInstallDecision(params) {
|
|
5343
5800
|
const serverId = requireString(params, "server_id");
|
|
@@ -5366,7 +5823,7 @@ async function executeLspGotoDefinition(params, signal) {
|
|
|
5366
5823
|
const line = requireNumber(params, "line");
|
|
5367
5824
|
const character = requireNumber(params, "character");
|
|
5368
5825
|
try {
|
|
5369
|
-
const result = await withLspClient(filePath, async (client) => client.definition(
|
|
5826
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.definition(resolvedFilePath, line, character, signal), "definition", clientOptions(signal));
|
|
5370
5827
|
const locations = !result ? [] : Array.isArray(result) ? result : [result];
|
|
5371
5828
|
const details = { filePath, line, character, locations };
|
|
5372
5829
|
if (locations.length === 0)
|
|
@@ -5391,7 +5848,7 @@ async function executeLspFindReferences(params, signal) {
|
|
|
5391
5848
|
const character = requireNumber(params, "character");
|
|
5392
5849
|
const includeDeclaration = optionalBoolean(params, "includeDeclaration") ?? true;
|
|
5393
5850
|
try {
|
|
5394
|
-
const result = await withLspClient(filePath, async (client) => client.references(
|
|
5851
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.references(resolvedFilePath, line, character, includeDeclaration, signal), "references", clientOptions(signal));
|
|
5395
5852
|
const references = Array.isArray(result) ? result : [];
|
|
5396
5853
|
const total = references.length;
|
|
5397
5854
|
const truncated = total > DEFAULT_MAX_REFERENCES;
|
|
@@ -5433,7 +5890,7 @@ async function executeLspPrepareRename(params, signal) {
|
|
|
5433
5890
|
const line = requireNumber(params, "line");
|
|
5434
5891
|
const character = requireNumber(params, "character");
|
|
5435
5892
|
try {
|
|
5436
|
-
const result = await withLspClient(filePath, async (client) => client.prepareRename(
|
|
5893
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.prepareRename(resolvedFilePath, line, character, signal), "prepareRename", clientOptions(signal));
|
|
5437
5894
|
const details = { filePath, line, character, result };
|
|
5438
5895
|
return text(formatPrepareRenameResult(result), details);
|
|
5439
5896
|
} catch (error) {
|
|
@@ -5454,7 +5911,7 @@ async function executeLspRename(params, signal) {
|
|
|
5454
5911
|
const character = requireNumber(params, "character");
|
|
5455
5912
|
const newName = requireString(params, "newName");
|
|
5456
5913
|
try {
|
|
5457
|
-
const result = await withLspClient(filePath, async (client) => client.rename(
|
|
5914
|
+
const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.rename(resolvedFilePath, line, character, newName, signal), "rename", clientOptions(signal));
|
|
5458
5915
|
const details = { filePath, line, character, newName, apply: result.apply, edit: result.edit };
|
|
5459
5916
|
return text(formatApplyResult(result.apply), details, !result.apply.success);
|
|
5460
5917
|
} catch (error) {
|
|
@@ -5534,7 +5991,7 @@ async function executeLspSymbols(params, signal) {
|
|
|
5534
5991
|
const symbols2 = await withLspClient(filePath, async (client) => client.workspaceSymbols(query, signal), "workspaceSymbols", clientOptions(signal));
|
|
5535
5992
|
return formatSymbolsResult(filePath, scope, symbols2, limit, query);
|
|
5536
5993
|
}
|
|
5537
|
-
const symbols = await withLspClient(filePath, async (client) => client.documentSymbols(
|
|
5994
|
+
const symbols = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => client.documentSymbols(resolvedFilePath, signal), "documentSymbols", clientOptions(signal));
|
|
5538
5995
|
return formatSymbolsResult(filePath, scope, symbols, limit);
|
|
5539
5996
|
} catch (error) {
|
|
5540
5997
|
const query = optionalString(params, "query");
|
|
@@ -5670,6 +6127,16 @@ var LSP_MCP_TOOLS = [
|
|
|
5670
6127
|
}, ["filePath", "line", "character", "newName"]),
|
|
5671
6128
|
execute: executeLspRename
|
|
5672
6129
|
},
|
|
6130
|
+
{
|
|
6131
|
+
name: "format",
|
|
6132
|
+
aliases: ["lsp_format"],
|
|
6133
|
+
title: "LSP Format",
|
|
6134
|
+
description: "Format a source file with its language server and write the returned edits to disk.",
|
|
6135
|
+
inputSchema: objectSchema({
|
|
6136
|
+
filePath: { type: "string", description: "Source file path to format." }
|
|
6137
|
+
}, ["filePath"]),
|
|
6138
|
+
execute: executeLspFormat
|
|
6139
|
+
},
|
|
5673
6140
|
{
|
|
5674
6141
|
name: "install_decision",
|
|
5675
6142
|
aliases: ["lsp_install_decision"],
|
|
@@ -5770,7 +6237,10 @@ function requestedProtocolVersion(params) {
|
|
|
5770
6237
|
var CONTEXT_KEY = "_context";
|
|
5771
6238
|
|
|
5772
6239
|
class InvalidDaemonRequestError extends Error {
|
|
5773
|
-
|
|
6240
|
+
constructor() {
|
|
6241
|
+
super(...arguments);
|
|
6242
|
+
this.name = "InvalidDaemonRequestError";
|
|
6243
|
+
}
|
|
5774
6244
|
}
|
|
5775
6245
|
function extractRequestContext(raw) {
|
|
5776
6246
|
if (!isPlainRecord(raw) || raw["method"] !== "tools/call")
|
|
@@ -5886,14 +6356,17 @@ async function callToolViaDaemon(name, args, options) {
|
|
|
5886
6356
|
function callDiagnosticsViaDaemon(filePath, options) {
|
|
5887
6357
|
return callToolViaDaemon("diagnostics", { filePath, severity: "error" }, options);
|
|
5888
6358
|
}
|
|
6359
|
+
function callFormatViaDaemon(filePath, options) {
|
|
6360
|
+
return callToolViaDaemon("format", { filePath }, options);
|
|
6361
|
+
}
|
|
5889
6362
|
function currentRequestContext(env = process.env) {
|
|
5890
6363
|
const cwd = process.cwd();
|
|
5891
6364
|
const home = env["HOME"] ?? homedir3();
|
|
5892
6365
|
return parseLspRequestContext({
|
|
5893
6366
|
cwd,
|
|
5894
|
-
projectConfigPaths: [
|
|
5895
|
-
userConfigPath:
|
|
5896
|
-
installDecisionsPath:
|
|
6367
|
+
projectConfigPaths: [join8(cwd, ".codex", "lsp-client.json")],
|
|
6368
|
+
userConfigPath: join8(home, ".codex", "lsp-client.json"),
|
|
6369
|
+
installDecisionsPath: join8(home, ".codex", "lsp-install-decisions.json"),
|
|
5897
6370
|
capabilities: { installDecisionTool: true }
|
|
5898
6371
|
});
|
|
5899
6372
|
}
|
|
@@ -5908,7 +6381,7 @@ function withContext(args, context) {
|
|
|
5908
6381
|
function ensureDaemonAvailable(paths, ensure, signal) {
|
|
5909
6382
|
if (!signal)
|
|
5910
6383
|
return ensure(paths);
|
|
5911
|
-
return new Promise((
|
|
6384
|
+
return new Promise((resolve10, reject) => {
|
|
5912
6385
|
let settled = false;
|
|
5913
6386
|
const finish = (run) => {
|
|
5914
6387
|
if (settled)
|
|
@@ -5923,11 +6396,11 @@ function ensureDaemonAvailable(paths, ensure, signal) {
|
|
|
5923
6396
|
return;
|
|
5924
6397
|
}
|
|
5925
6398
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
5926
|
-
Promise.resolve().then(() => ensure(paths, signal)).then(() => finish(() =>
|
|
6399
|
+
Promise.resolve().then(() => ensure(paths, signal)).then(() => finish(() => resolve10()), (error) => finish(() => reject(signal.aborted ? new DaemonRequestCancelledError(false) : error)));
|
|
5927
6400
|
});
|
|
5928
6401
|
}
|
|
5929
6402
|
function sendToolCall(paths, token, name, args, options) {
|
|
5930
|
-
return new Promise((
|
|
6403
|
+
return new Promise((resolve10, reject) => {
|
|
5931
6404
|
const socket = connect(paths.socket);
|
|
5932
6405
|
const requestId = allocateProxyRequestId();
|
|
5933
6406
|
let settled = false;
|
|
@@ -5980,7 +6453,7 @@ function sendToolCall(paths, token, name, args, options) {
|
|
|
5980
6453
|
}
|
|
5981
6454
|
const result = toToolResult(message, requestId);
|
|
5982
6455
|
if (result)
|
|
5983
|
-
finish(() =>
|
|
6456
|
+
finish(() => resolve10(result));
|
|
5984
6457
|
else
|
|
5985
6458
|
finish(() => reject(new DaemonRequestError("invalid daemon response", requestWritten)));
|
|
5986
6459
|
});
|
|
@@ -6025,8 +6498,8 @@ function isRetryableTool(name) {
|
|
|
6025
6498
|
return name !== "rename" && name !== "lsp_rename";
|
|
6026
6499
|
}
|
|
6027
6500
|
// src/proxy.ts
|
|
6028
|
-
import { existsSync as
|
|
6029
|
-
import { basename as
|
|
6501
|
+
import { existsSync as existsSync13, realpathSync as realpathSync6 } from "node:fs";
|
|
6502
|
+
import { basename as basename4, delimiter as delimiter4, dirname as dirname11, isAbsolute as isAbsolute6 } from "node:path";
|
|
6030
6503
|
var DEFAULT_STARTUP_TIMEOUT_MS = 1e4;
|
|
6031
6504
|
async function runMcpStdioProxy(options = {}) {
|
|
6032
6505
|
const input = options.input ?? process.stdin;
|
|
@@ -6149,34 +6622,34 @@ function canonicalizePathList(value) {
|
|
|
6149
6622
|
return value.split(delimiter4).map((entry) => canonicalizePath(entry) ?? entry).join(delimiter4);
|
|
6150
6623
|
}
|
|
6151
6624
|
function canonicalizePath(value) {
|
|
6152
|
-
if (value === undefined || !
|
|
6625
|
+
if (value === undefined || !isAbsolute6(value) || !existsSync13(value))
|
|
6153
6626
|
return value;
|
|
6154
|
-
return
|
|
6627
|
+
return realpathSync6(value);
|
|
6155
6628
|
}
|
|
6156
6629
|
function projectRootFromOpenCodeConfigPath(path2) {
|
|
6157
|
-
if (
|
|
6630
|
+
if (basename4(path2) !== "lsp.json" && basename4(path2) !== "lsp-client.json")
|
|
6158
6631
|
return;
|
|
6159
|
-
const configDir =
|
|
6160
|
-
const configDirName =
|
|
6632
|
+
const configDir = dirname11(path2);
|
|
6633
|
+
const configDirName = basename4(configDir);
|
|
6161
6634
|
if (configDirName !== ".opencode" && configDirName !== ".omo")
|
|
6162
6635
|
return;
|
|
6163
|
-
return
|
|
6636
|
+
return dirname11(configDir);
|
|
6164
6637
|
}
|
|
6165
6638
|
export {
|
|
6166
|
-
|
|
6167
|
-
runMcpStdioProxy,
|
|
6168
|
-
resolveDaemonRuntime,
|
|
6169
|
-
probeDaemon,
|
|
6170
|
-
ensureDaemonRunning,
|
|
6171
|
-
disposeDefaultLspManager,
|
|
6172
|
-
daemonPaths,
|
|
6173
|
-
currentRequestContext,
|
|
6174
|
-
callToolViaDaemon,
|
|
6175
|
-
callDiagnosticsViaDaemon,
|
|
6176
|
-
OMO_LSP_DAEMON_VERSION,
|
|
6177
|
-
OMO_LSP_DAEMON_DIR,
|
|
6178
|
-
OMO_LSP_DAEMON_CLI,
|
|
6179
|
-
InvalidRuntimeOverrideError,
|
|
6639
|
+
InvalidDaemonDirectoryError,
|
|
6180
6640
|
InvalidDaemonVersionError,
|
|
6181
|
-
|
|
6641
|
+
InvalidRuntimeOverrideError,
|
|
6642
|
+
OMO_LSP_DAEMON_CLI,
|
|
6643
|
+
OMO_LSP_DAEMON_DIR,
|
|
6644
|
+
OMO_LSP_DAEMON_VERSION,
|
|
6645
|
+
callDiagnosticsViaDaemon,
|
|
6646
|
+
callToolViaDaemon,
|
|
6647
|
+
currentRequestContext,
|
|
6648
|
+
daemonPaths,
|
|
6649
|
+
disposeDefaultLspManager,
|
|
6650
|
+
ensureDaemonRunning,
|
|
6651
|
+
probeDaemon,
|
|
6652
|
+
resolveDaemonRuntime,
|
|
6653
|
+
runMcpStdioProxy,
|
|
6654
|
+
validateDaemonVersion
|
|
6182
6655
|
};
|