oh-my-opencode 5.0.0-beta.30 → 5.0.0-beta.32
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/dist/cli/index.js +178 -37
- package/dist/cli-node/index.js +178 -37
- package/dist/config/schema/background-task.d.ts +1 -0
- package/dist/config/schema/oh-my-opencode-config.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/monitor/manager-internals.d.ts +1 -1
- package/dist/features/monitor/output-injector-types.d.ts +1 -1
- package/dist/features/task-toast-manager/manager.d.ts +0 -24
- 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/claude-code-hooks/session-hook-state.d.ts +1 -0
- package/dist/hooks/claude-code-hooks/stop.d.ts +2 -0
- package/dist/hooks/claude-code-hooks/todo.d.ts +0 -1
- package/dist/hooks/claude-code-hooks/transcript.d.ts +2 -0
- package/dist/hooks/fsync-skip-warning/index.d.ts +4 -0
- package/dist/hooks/hashline-edit-diff-enhancer/hook.d.ts +1 -0
- package/dist/hooks/hashline-edit-diff-enhancer/pending-captures.d.ts +13 -0
- package/dist/hooks/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/index.js +681 -273
- package/dist/oh-my-opencode.schema.json +5 -0
- package/dist/plugin-dispose.d.ts +3 -0
- package/dist/shared/agent-tool-restrictions.d.ts +0 -1
- package/dist/skills/ultimate-browsing/references/insane-search/README.md +9 -2
- 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/types.d.ts +1 -0
- package/dist/tools/session-manager/directory-filter.d.ts +2 -0
- package/dist/tui.js +148 -9
- package/package.json +16 -15
- package/packages/git-bash-mcp/dist/cli.js +1 -0
- package/packages/lsp-core/src/lsp/client-diagnostics-freshness.integration.test.ts +47 -19
- package/packages/lsp-core/src/lsp/client-diagnostics-pull-timeout.test.ts +64 -0
- package/packages/lsp-core/src/lsp/client-wrapper.test.ts +97 -0
- package/packages/lsp-core/src/lsp/client-wrapper.ts +21 -6
- package/packages/lsp-core/src/lsp/client.ts +6 -3
- package/packages/lsp-core/src/lsp/constants.ts +5 -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/manager-lifecycle.test.ts +262 -0
- package/packages/lsp-core/src/lsp/manager.ts +106 -13
- 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 +7 -2
- 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-markers.ts +18 -1
- package/packages/lsp-core/src/mcp.ts +3 -0
- package/packages/lsp-core/src/tools/parameters.test.ts +51 -0
- package/packages/lsp-daemon/dist/cli.js +155 -34
- package/packages/lsp-daemon/dist/client.js +155 -34
- package/packages/lsp-daemon/dist/index.js +155 -34
- package/packages/lsp-daemon/dist/proxy.js +3 -0
- package/packages/lsp-tools-mcp/dist/cli.js +155 -34
- package/packages/lsp-tools-mcp/dist/lsp/manager.js +134 -28
- package/packages/lsp-tools-mcp/dist/mcp.js +155 -34
- package/packages/lsp-tools-mcp/dist/tools.js +154 -34
- package/packages/lsp-tools-mcp/package.json +1 -1
- package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
- 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/codegraph/dist/cli.js +17 -2
- package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +17 -2
- package/packages/omo-codex/plugin/components/codegraph/package.json +1 -1
- package/packages/omo-codex/plugin/components/codegraph/src/mcp-unavailable.ts +12 -0
- package/packages/omo-codex/plugin/components/codegraph/test/serve-unavailable-idle.test.ts +47 -0
- package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/package.json +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 +1 -1
- 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 +1 -1
- package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +3 -3
- package/packages/omo-codex/plugin/components/lsp/dist/cli.js +152 -34
- package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
- package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
- package/packages/omo-codex/plugin/components/rules/package.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/AGENTS.md +5 -4
- 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 +1 -2
- package/packages/omo-codex/plugin/components/ultrawork/scripts/sync-directive.mjs +30 -14
- 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/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/ulw-execute-continuation/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/ulw-execute-continuation/package.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/AGENTS.md +5 -2
- package/packages/omo-codex/plugin/components/ulw-loop/README.md +1 -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 +14 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-reconciliation.js +10 -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 +113 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.js +9 -5
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-commands.js +2 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.d.ts +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.js +1 -0
- 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 +856 -347
- 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 +14 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/domain-types.d.ts +17 -9
- 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 +2 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-aggregate.js +53 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-artifacts.d.ts +9 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-artifacts.js +85 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-fields.js +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.d.ts +4 -2
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.js +41 -102
- 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/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 +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +17 -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 +25 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-template.ts +127 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint.ts +10 -12
- package/packages/omo-codex/plugin/components/ulw-loop/src/cli-commands.ts +2 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/cli-output.ts +1 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/cli-subcommands.ts +2 -0
- 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 +23 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/domain-types.ts +19 -9
- 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 +57 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-artifacts.ts +103 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-fields.ts +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate.ts +54 -123
- 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/surface.ts +95 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-final.test.ts +107 -1
- package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-template.test.ts +92 -0
- 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 +35 -0
- 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/quality-gate-aggregate.test.ts +101 -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.test.ts +5 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/spawn-guard.test.ts +318 -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 +9 -3
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
- package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +1 -1
- 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 +1 -1
- 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/package-lock.json +13 -13
- package/packages/omo-codex/plugin/package.json +1 -1
- package/packages/omo-codex/plugin/scripts/sync-skills.mjs +31 -2
- package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/README.md +9 -2
- package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +17 -0
- package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +11 -1
- package/packages/omo-codex/plugin/test/sync-skills.test.mjs +13 -0
- package/packages/omo-codex/plugin/test/ultrawork-skill-pointer.test.mjs +5 -2
- package/packages/omo-codex/scripts/install-dist/install-local.mjs +2 -2
- package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/README.md +9 -2
- 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/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/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/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/ultrawork/directive.md +0 -483
- package/packages/omo-codex/plugin/components/ultrawork/skills/ultrawork/SKILL.md +0 -490
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
runJsonRpcStdioServer,
|
|
8
8
|
successResponse,
|
|
9
9
|
type JsonRpcResponse,
|
|
10
|
+
type McpLifecycleLog,
|
|
10
11
|
type ParentWatchdogConfig,
|
|
11
12
|
} from "../../../../../mcp-stdio-core/src/index.ts";
|
|
12
13
|
|
|
@@ -18,6 +19,9 @@ export interface UnavailableCodegraphMcpOptions {
|
|
|
18
19
|
// Test seam: production callers leave this unset so the watchdog uses its
|
|
19
20
|
// defaults (parentPid = process.ppid, 30s poll).
|
|
20
21
|
readonly parentWatchdog?: ParentWatchdogConfig;
|
|
22
|
+
// Test seam: surfaces the mcp-stdio-core lifecycle log so tests can pin the
|
|
23
|
+
// resolved idle timeout without waiting a real timeout out.
|
|
24
|
+
readonly lifecycleLog?: McpLifecycleLog;
|
|
21
25
|
}
|
|
22
26
|
|
|
23
27
|
interface UnavailableCodegraphMcpHandlerOptions {
|
|
@@ -36,7 +40,15 @@ export async function runUnavailableCodegraphMcpServer(
|
|
|
36
40
|
},
|
|
37
41
|
input: options.input,
|
|
38
42
|
output: options.output,
|
|
43
|
+
// Idle stays disabled: the codex host never respawns an exited stdio
|
|
44
|
+
// MCP server (codex-rs auto-reconnects only its own codex_apps server),
|
|
45
|
+
// and since #6548 the default idle timer actually destroys stdin — so an
|
|
46
|
+
// inherited 10-minute default would silently kill this stub mid-session
|
|
47
|
+
// and turn later codegraph tool calls into dead-connection errors.
|
|
48
|
+
idleTimeoutMs: 0,
|
|
39
49
|
parentWatchdog: options.parentWatchdog ?? {},
|
|
50
|
+
// Conditional spread keeps this assignable under exactOptionalPropertyTypes.
|
|
51
|
+
...(options.lifecycleLog === undefined ? {} : { log: options.lifecycleLog }),
|
|
40
52
|
});
|
|
41
53
|
}
|
|
42
54
|
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { describe, expect, it } from "bun:test";
|
|
2
|
+
import { PassThrough } from "node:stream";
|
|
3
|
+
|
|
4
|
+
import { runUnavailableCodegraphMcpServer } from "../src/mcp-unavailable.ts";
|
|
5
|
+
|
|
6
|
+
describe("unavailable codegraph MCP idle teardown", () => {
|
|
7
|
+
it("#given the codex host (no respawn for exited stdio servers) #when the unavailable stub starts #then the idle timeout is disabled", async () => {
|
|
8
|
+
// given — codex never respawns a user-configured stdio MCP server
|
|
9
|
+
// (codex-rs reconnects only its own codex_apps server), so if the stub
|
|
10
|
+
// inherited the mcp-stdio-core default idle timeout it would destroy its
|
|
11
|
+
// own stdin after 10 idle minutes and every later codegraph tool call in
|
|
12
|
+
// a long-lived session would fail on a dead connection instead of
|
|
13
|
+
// answering with the skip reason.
|
|
14
|
+
const stdin = new PassThrough();
|
|
15
|
+
const stdout = new PassThrough();
|
|
16
|
+
stdout.resume();
|
|
17
|
+
const lifecycle: Array<{ readonly event: string; readonly data?: unknown }> = [];
|
|
18
|
+
|
|
19
|
+
try {
|
|
20
|
+
// when
|
|
21
|
+
const served = runUnavailableCodegraphMcpServer({
|
|
22
|
+
input: stdin,
|
|
23
|
+
output: stdout,
|
|
24
|
+
reason: "CodeGraph MCP skipped: test reason",
|
|
25
|
+
serverVersion: "0.0.0-test",
|
|
26
|
+
lifecycleLog: (event, data) => {
|
|
27
|
+
lifecycle.push({ event, data });
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
const outcome = await Promise.race([
|
|
31
|
+
served.then(() => "settled" as const),
|
|
32
|
+
Bun.sleep(500).then(() => "parked" as const),
|
|
33
|
+
]);
|
|
34
|
+
|
|
35
|
+
// then — the server must park on the held-open pipe (no idle timer
|
|
36
|
+
// tore it down) and must have started with the timeout disabled.
|
|
37
|
+
expect(outcome).toBe("parked");
|
|
38
|
+
expect(lifecycle).toContainEqual({
|
|
39
|
+
event: "stdio_started",
|
|
40
|
+
data: expect.objectContaining({ idle_timeout_ms: 0 }),
|
|
41
|
+
});
|
|
42
|
+
} finally {
|
|
43
|
+
stdin.destroy();
|
|
44
|
+
stdout.destroy();
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
});
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"type": "command",
|
|
9
9
|
"command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook pre-tool-use",
|
|
10
10
|
"timeout": 5,
|
|
11
|
-
"statusMessage": "(OmO 5.0.0-beta.
|
|
11
|
+
"statusMessage": "(OmO 5.0.0-beta.32) Recommending Git Bash MCP"
|
|
12
12
|
}
|
|
13
13
|
]
|
|
14
14
|
}
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"type": "command",
|
|
21
21
|
"command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook post-compact",
|
|
22
22
|
"timeout": 5,
|
|
23
|
-
"statusMessage": "(OmO 5.0.0-beta.
|
|
23
|
+
"statusMessage": "(OmO 5.0.0-beta.32) Resetting Git Bash MCP Reminder"
|
|
24
24
|
}
|
|
25
25
|
]
|
|
26
26
|
}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"type": "command",
|
|
9
9
|
"command": "node \"${PLUGIN_ROOT}/components/lazycodex-executor-verify/dist/cli.js\" hook subagent-stop",
|
|
10
10
|
"timeout": 10,
|
|
11
|
-
"statusMessage": "(OmO 5.0.0-beta.
|
|
11
|
+
"statusMessage": "(OmO 5.0.0-beta.32) Verifying LazyCodex Executor Evidence"
|
|
12
12
|
}
|
|
13
13
|
]
|
|
14
14
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@code-yeongyu/codex-lazycodex-executor-verify",
|
|
3
|
-
"version": "5.0.0-beta.
|
|
3
|
+
"version": "5.0.0-beta.32",
|
|
4
4
|
"description": "Codex SubagentStop evidence verifier for LazyCodex executor completions.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"packageManager": "npm@11.12.1",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"version": "5.0.0-beta.
|
|
4
|
-
"inputDigest": "sha256:
|
|
3
|
+
"version": "5.0.0-beta.32",
|
|
4
|
+
"inputDigest": "sha256:7ebeb55787bcfcf32f5cdd2782c145f22c9aa8c595b7dedde0228036267ccfee",
|
|
5
5
|
"outputs": [
|
|
6
6
|
{
|
|
7
7
|
"path": "cli.d.ts",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
},
|
|
10
10
|
{
|
|
11
11
|
"path": "cli.js",
|
|
12
|
-
"sha256": "
|
|
12
|
+
"sha256": "89f0a2360dc1977cc00f2cdb661ff6929a7b90131728488502834a372840db3c"
|
|
13
13
|
},
|
|
14
14
|
{
|
|
15
15
|
"path": "codex-hook-cli.d.ts",
|
|
@@ -745,6 +745,16 @@ class LspProcessSpawnError extends Error {
|
|
|
745
745
|
this.name = "LspProcessSpawnError";
|
|
746
746
|
}
|
|
747
747
|
}
|
|
748
|
+
|
|
749
|
+
class LspClientRespawnBudgetExceededError extends Error {
|
|
750
|
+
constructor(serverId, root, retryLimit) {
|
|
751
|
+
super(`LSP server ${serverId} at ${root} failed to stay alive; respawn budget exhausted ` + `(${retryLimit} consecutive dead generations). Retrying after the cooldown may succeed.`);
|
|
752
|
+
this.serverId = serverId;
|
|
753
|
+
this.root = root;
|
|
754
|
+
this.retryLimit = retryLimit;
|
|
755
|
+
this.name = "LspClientRespawnBudgetExceededError";
|
|
756
|
+
}
|
|
757
|
+
}
|
|
748
758
|
function isLspDeadConnectionError(err) {
|
|
749
759
|
return err instanceof LspConnectionClosedError || err instanceof LspProcessExitedError;
|
|
750
760
|
}
|
|
@@ -756,6 +766,11 @@ function reportBestEffortCleanupError(operation, error, logger = writeCleanupErr
|
|
|
756
766
|
const message = error instanceof Error ? error.message : String(error);
|
|
757
767
|
logger(`[lsp] ignored ${operation} failure during cleanup: ${message}`);
|
|
758
768
|
}
|
|
769
|
+
var realTimerProvider = {
|
|
770
|
+
now: () => Date.now(),
|
|
771
|
+
setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
|
|
772
|
+
clearTimeout: (handle) => clearTimeout(handle)
|
|
773
|
+
};
|
|
759
774
|
var DEFAULT_MAX_REFERENCES = 200;
|
|
760
775
|
var DEFAULT_MAX_SYMBOLS = 200;
|
|
761
776
|
var DEFAULT_MAX_DIAGNOSTICS = 200;
|
|
@@ -767,6 +782,8 @@ var MAX_RESIDENT_CLIENTS = 6;
|
|
|
767
782
|
var REAPER_INTERVAL_MS = 60000;
|
|
768
783
|
var STOP_HARD_KILL_TIMEOUT_MS = 5000;
|
|
769
784
|
var STOP_SIGKILL_GRACE_MS = 1000;
|
|
785
|
+
var CLIENT_RESPAWN_RETRY_LIMIT = 2;
|
|
786
|
+
var CLIENT_RESPAWN_COOLDOWN_MS = 60000;
|
|
770
787
|
var HEADER_SEPARATOR2 = `\r
|
|
771
788
|
\r
|
|
772
789
|
`;
|
|
@@ -1282,6 +1299,7 @@ class LspClientTransport {
|
|
|
1282
1299
|
this.documentFormattingSupported = false;
|
|
1283
1300
|
this.requestTimeoutMs = timeouts.requestTimeoutMs ?? REQUEST_TIMEOUT_MS;
|
|
1284
1301
|
this.initializeTimeoutMs = timeouts.initializeTimeoutMs ?? INIT_TIMEOUT_MS;
|
|
1302
|
+
this.timerProvider = timeouts.timerProvider ?? realTimerProvider;
|
|
1285
1303
|
}
|
|
1286
1304
|
pid() {
|
|
1287
1305
|
return this.proc?.pid;
|
|
@@ -1382,7 +1400,7 @@ class LspClientTransport {
|
|
|
1382
1400
|
const options = args[1];
|
|
1383
1401
|
const timeoutMs = options?.timeoutMs ?? this.requestTimeoutMs;
|
|
1384
1402
|
const timeoutController = new AbortController;
|
|
1385
|
-
const timeoutHandle = setTimeout(() => {
|
|
1403
|
+
const timeoutHandle = this.timerProvider.setTimeout(() => {
|
|
1386
1404
|
const stderrTail = this.stderrBuffer.slice(-5).join(`
|
|
1387
1405
|
`);
|
|
1388
1406
|
timeoutController.abort(new LspRequestTimeoutError(method, stderrTail || undefined));
|
|
@@ -1401,7 +1419,7 @@ class LspClientTransport {
|
|
|
1401
1419
|
}
|
|
1402
1420
|
throw error;
|
|
1403
1421
|
} finally {
|
|
1404
|
-
clearTimeout(timeoutHandle);
|
|
1422
|
+
this.timerProvider.clearTimeout(timeoutHandle);
|
|
1405
1423
|
combinedSignal.dispose();
|
|
1406
1424
|
}
|
|
1407
1425
|
}
|
|
@@ -1771,6 +1789,17 @@ function canonicalPath(filePath) {
|
|
|
1771
1789
|
return absolute;
|
|
1772
1790
|
}
|
|
1773
1791
|
}
|
|
1792
|
+
function normalizeDocumentUri(uri) {
|
|
1793
|
+
let decoded = uri;
|
|
1794
|
+
try {
|
|
1795
|
+
decoded = decodeURIComponent(uri);
|
|
1796
|
+
} catch {
|
|
1797
|
+
decoded = uri;
|
|
1798
|
+
}
|
|
1799
|
+
if (process.platform !== "win32")
|
|
1800
|
+
return decoded;
|
|
1801
|
+
return decoded.replace(/^(file:\/\/\/)([a-z]):/, (_match, prefix, drive) => `${prefix}${drive.toUpperCase()}:`);
|
|
1802
|
+
}
|
|
1774
1803
|
function isSameOrDescendant(candidate, parent) {
|
|
1775
1804
|
const suffix = relative2(parent, candidate);
|
|
1776
1805
|
return suffix === "" || !suffix.startsWith("..") && suffix !== "..";
|
|
@@ -1787,7 +1816,12 @@ class WorkspaceDocumentState {
|
|
|
1787
1816
|
this.openDocuments = new Map;
|
|
1788
1817
|
this.openByUri = new Map;
|
|
1789
1818
|
this.openPromises = new Map;
|
|
1790
|
-
this.
|
|
1819
|
+
this.timerProvider = options.timerProvider ?? {
|
|
1820
|
+
now: options.now ?? (() => Date.now()),
|
|
1821
|
+
setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
|
|
1822
|
+
clearTimeout: (handle) => clearTimeout(handle)
|
|
1823
|
+
};
|
|
1824
|
+
this.now = () => this.timerProvider.now();
|
|
1791
1825
|
this.versionlessPublishQuiescenceMs = options.versionlessPublishQuiescenceMs ?? DEFAULT_VERSIONLESS_PUBLISH_QUIESCENCE_MS;
|
|
1792
1826
|
}
|
|
1793
1827
|
async openFile(filePath) {
|
|
@@ -1809,7 +1843,7 @@ class WorkspaceDocumentState {
|
|
|
1809
1843
|
return this.openDocuments.get(canonicalPath(filePath))?.version;
|
|
1810
1844
|
}
|
|
1811
1845
|
getStoredDiagnostics(uri) {
|
|
1812
|
-
const state = this.openByUri.get(uri);
|
|
1846
|
+
const state = this.openByUri.get(normalizeDocumentUri(uri));
|
|
1813
1847
|
if (!state)
|
|
1814
1848
|
return [];
|
|
1815
1849
|
return state.lastPublish?.diagnostics ?? state.pullCache?.diagnostics ?? [];
|
|
@@ -1831,13 +1865,13 @@ class WorkspaceDocumentState {
|
|
|
1831
1865
|
return state !== undefined && state.uri === snapshot.uri && state.version === snapshot.version && state.generation === snapshot.documentGeneration;
|
|
1832
1866
|
}
|
|
1833
1867
|
getPullCache(snapshot) {
|
|
1834
|
-
const state = this.openByUri.get(snapshot.uri);
|
|
1868
|
+
const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
|
|
1835
1869
|
if (!state?.pullCache || state.pullCache.documentVersion !== snapshot.version)
|
|
1836
1870
|
return null;
|
|
1837
1871
|
return state.pullCache;
|
|
1838
1872
|
}
|
|
1839
1873
|
recordPullDiagnostics(snapshot, report) {
|
|
1840
|
-
const state = this.openByUri.get(snapshot.uri);
|
|
1874
|
+
const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
|
|
1841
1875
|
if (!state)
|
|
1842
1876
|
return;
|
|
1843
1877
|
state.pullCache = {
|
|
@@ -1847,7 +1881,7 @@ class WorkspaceDocumentState {
|
|
|
1847
1881
|
};
|
|
1848
1882
|
}
|
|
1849
1883
|
recordPublishedDiagnostics(params) {
|
|
1850
|
-
const state = this.openByUri.get(params.uri);
|
|
1884
|
+
const state = this.openByUri.get(normalizeDocumentUri(params.uri));
|
|
1851
1885
|
if (!state)
|
|
1852
1886
|
return;
|
|
1853
1887
|
state.publishGeneration += 1;
|
|
@@ -1861,7 +1895,7 @@ class WorkspaceDocumentState {
|
|
|
1861
1895
|
this.notifyWaiters(state);
|
|
1862
1896
|
}
|
|
1863
1897
|
resolvePushDiagnostics(snapshot) {
|
|
1864
|
-
const state = this.openByUri.get(snapshot.uri);
|
|
1898
|
+
const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
|
|
1865
1899
|
if (!state?.lastPublish)
|
|
1866
1900
|
return { status: "missing" };
|
|
1867
1901
|
const publish = state.lastPublish;
|
|
@@ -1875,7 +1909,7 @@ class WorkspaceDocumentState {
|
|
|
1875
1909
|
return waitMs === 0 ? { status: "ready", diagnostics: publish.diagnostics } : { status: "wait", waitMs };
|
|
1876
1910
|
}
|
|
1877
1911
|
waitForDiagnosticsActivity(snapshot, timeoutMs) {
|
|
1878
|
-
const state = this.openByUri.get(snapshot.uri);
|
|
1912
|
+
const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
|
|
1879
1913
|
if (!state || timeoutMs <= 0)
|
|
1880
1914
|
return Promise.resolve();
|
|
1881
1915
|
return new Promise((resolveActivity) => {
|
|
@@ -1884,11 +1918,11 @@ class WorkspaceDocumentState {
|
|
|
1884
1918
|
if (settled)
|
|
1885
1919
|
return;
|
|
1886
1920
|
settled = true;
|
|
1887
|
-
clearTimeout(timer);
|
|
1921
|
+
this.timerProvider.clearTimeout(timer);
|
|
1888
1922
|
state.waiters.delete(finish);
|
|
1889
1923
|
resolveActivity();
|
|
1890
1924
|
};
|
|
1891
|
-
const timer = setTimeout(finish, timeoutMs);
|
|
1925
|
+
const timer = this.timerProvider.setTimeout(finish, timeoutMs);
|
|
1892
1926
|
if (typeof timer.unref === "function")
|
|
1893
1927
|
timer.unref();
|
|
1894
1928
|
state.waiters.add(finish);
|
|
@@ -1996,7 +2030,7 @@ class WorkspaceDocumentState {
|
|
|
1996
2030
|
waiters: new Set
|
|
1997
2031
|
};
|
|
1998
2032
|
this.openDocuments.set(path2, state);
|
|
1999
|
-
this.openByUri.set(state.uri, state);
|
|
2033
|
+
this.openByUri.set(normalizeDocumentUri(state.uri), state);
|
|
2000
2034
|
this.notifyWaiters(state);
|
|
2001
2035
|
await this.sendNotification("textDocument/didOpen", {
|
|
2002
2036
|
textDocument: { uri: state.uri, languageId: state.languageId, version: state.version, text }
|
|
@@ -2021,7 +2055,7 @@ class WorkspaceDocumentState {
|
|
|
2021
2055
|
}
|
|
2022
2056
|
async closeDocument(state) {
|
|
2023
2057
|
this.openDocuments.delete(state.path);
|
|
2024
|
-
this.openByUri.delete(state.uri);
|
|
2058
|
+
this.openByUri.delete(normalizeDocumentUri(state.uri));
|
|
2025
2059
|
this.clearDiagnostics(state.uri);
|
|
2026
2060
|
this.notifyWaiters(state);
|
|
2027
2061
|
await this.sendNotification("textDocument/didClose", { textDocument: { uri: state.uri } });
|
|
@@ -3071,6 +3105,7 @@ class LspClient extends LspClientConnection {
|
|
|
3071
3105
|
this.diagnosticPullErrors = [];
|
|
3072
3106
|
this.diagnosticsFreshnessTimeoutMs = options.diagnosticsFreshnessTimeoutMs ?? DIAGNOSTICS_FRESHNESS_TIMEOUT_MS;
|
|
3073
3107
|
this.documents = new WorkspaceDocumentState((method, params) => this.sendNotification(method, params), (uri) => this.diagnosticsStore.delete(uri), {
|
|
3108
|
+
timerProvider: this.timerProvider,
|
|
3074
3109
|
versionlessPublishQuiescenceMs: options.versionlessPublishQuiescenceMs ?? VERSIONLESS_PUBLISH_QUIESCENCE_MS
|
|
3075
3110
|
});
|
|
3076
3111
|
this.workspaceMutations = new WorkspaceMutationController(root, this.documents);
|
|
@@ -3174,7 +3209,7 @@ class LspClient extends LspClientConnection {
|
|
|
3174
3209
|
const absPath = this.resolveWorkspacePath(filePath);
|
|
3175
3210
|
const uri = pathToFileURL3(absPath).href;
|
|
3176
3211
|
await this.openFile(absPath);
|
|
3177
|
-
const deadlineAt =
|
|
3212
|
+
const deadlineAt = this.timerProvider.now() + this.diagnosticsFreshnessTimeoutMs;
|
|
3178
3213
|
for (;; ) {
|
|
3179
3214
|
signal?.throwIfAborted();
|
|
3180
3215
|
const snapshot = this.documents.captureDiagnosticSnapshot(absPath);
|
|
@@ -3187,7 +3222,7 @@ class LspClient extends LspClientConnection {
|
|
|
3187
3222
|
if (!pushFallbackOnly) {
|
|
3188
3223
|
const cached = this.documents.getPullCache(snapshot);
|
|
3189
3224
|
try {
|
|
3190
|
-
const remainingMs2 = deadlineAt -
|
|
3225
|
+
const remainingMs2 = deadlineAt - this.timerProvider.now();
|
|
3191
3226
|
if (remainingMs2 <= 0)
|
|
3192
3227
|
return this.freshnessTimeout(absPath);
|
|
3193
3228
|
const result = await this.sendRequest("textDocument/diagnostic", {
|
|
@@ -3222,7 +3257,7 @@ class LspClient extends LspClientConnection {
|
|
|
3222
3257
|
}
|
|
3223
3258
|
if (!pushFallbackOnly)
|
|
3224
3259
|
continue;
|
|
3225
|
-
const remainingMs = deadlineAt -
|
|
3260
|
+
const remainingMs = deadlineAt - this.timerProvider.now();
|
|
3226
3261
|
if (remainingMs <= 0) {
|
|
3227
3262
|
if (!this.isDiagnosticPullSupported() && snapshot.publishGeneration === 0) {
|
|
3228
3263
|
const cached = this.documents.getPullCache(snapshot);
|
|
@@ -3378,6 +3413,8 @@ function awaitWithSignal2(promise, signal) {
|
|
|
3378
3413
|
class LspManager {
|
|
3379
3414
|
constructor(options = {}) {
|
|
3380
3415
|
this.clients = new Map;
|
|
3416
|
+
this.pendingStops = new Map;
|
|
3417
|
+
this.respawnBudgets = new Map;
|
|
3381
3418
|
this.reaperHandle = null;
|
|
3382
3419
|
this.signalDisposer = null;
|
|
3383
3420
|
this.disposed = false;
|
|
@@ -3403,17 +3440,52 @@ class LspManager {
|
|
|
3403
3440
|
getKey(root, serverId) {
|
|
3404
3441
|
return `${root}::${serverId}`;
|
|
3405
3442
|
}
|
|
3443
|
+
tombstoneStop(key, client) {
|
|
3444
|
+
const stop = stopClientBestEffort(client);
|
|
3445
|
+
this.pendingStops.set(key, stop);
|
|
3446
|
+
stop.finally(() => {
|
|
3447
|
+
if (this.pendingStops.get(key) === stop) {
|
|
3448
|
+
this.pendingStops.delete(key);
|
|
3449
|
+
}
|
|
3450
|
+
});
|
|
3451
|
+
return stop;
|
|
3452
|
+
}
|
|
3453
|
+
recordDeadGeneration(key) {
|
|
3454
|
+
let budget = this.respawnBudgets.get(key);
|
|
3455
|
+
if (budget === undefined) {
|
|
3456
|
+
budget = { deadGenerations: 0, exhaustedAt: null };
|
|
3457
|
+
this.respawnBudgets.set(key, budget);
|
|
3458
|
+
}
|
|
3459
|
+
budget.deadGenerations += 1;
|
|
3460
|
+
}
|
|
3461
|
+
markHealthyGeneration(key) {
|
|
3462
|
+
this.respawnBudgets.delete(key);
|
|
3463
|
+
}
|
|
3464
|
+
ensureRespawnAllowed(key, root, serverId) {
|
|
3465
|
+
const budget = this.respawnBudgets.get(key);
|
|
3466
|
+
if (budget === undefined || budget.deadGenerations < CLIENT_RESPAWN_RETRY_LIMIT)
|
|
3467
|
+
return;
|
|
3468
|
+
if (budget.exhaustedAt === null) {
|
|
3469
|
+
budget.exhaustedAt = this.now();
|
|
3470
|
+
throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
|
|
3471
|
+
}
|
|
3472
|
+
if (this.now() - budget.exhaustedAt < CLIENT_RESPAWN_COOLDOWN_MS) {
|
|
3473
|
+
throw new LspClientRespawnBudgetExceededError(serverId, root, CLIENT_RESPAWN_RETRY_LIMIT);
|
|
3474
|
+
}
|
|
3475
|
+
budget.deadGenerations = 0;
|
|
3476
|
+
budget.exhaustedAt = null;
|
|
3477
|
+
}
|
|
3406
3478
|
reapStale() {
|
|
3407
3479
|
const t = this.now();
|
|
3408
3480
|
for (const [key, managed] of this.clients) {
|
|
3409
3481
|
if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
|
|
3410
|
-
stopClientBestEffort(managed.client);
|
|
3411
3482
|
this.clients.delete(key);
|
|
3483
|
+
this.tombstoneStop(key, managed.client);
|
|
3412
3484
|
continue;
|
|
3413
3485
|
}
|
|
3414
3486
|
if (!managed.isInitializing && managed.refCount === 0 && managed.pendingWaiters === 0 && t - managed.lastUsedAt > this.idleTimeoutMs) {
|
|
3415
|
-
stopClientBestEffort(managed.client);
|
|
3416
3487
|
this.clients.delete(key);
|
|
3488
|
+
this.tombstoneStop(key, managed.client);
|
|
3417
3489
|
}
|
|
3418
3490
|
}
|
|
3419
3491
|
}
|
|
@@ -3423,7 +3495,7 @@ class LspManager {
|
|
|
3423
3495
|
if (!victim)
|
|
3424
3496
|
return;
|
|
3425
3497
|
this.clients.delete(victim.key);
|
|
3426
|
-
|
|
3498
|
+
this.tombstoneStop(victim.key, victim.managed.client);
|
|
3427
3499
|
}
|
|
3428
3500
|
}
|
|
3429
3501
|
leastRecentlyUsedIdleClient() {
|
|
@@ -3440,7 +3512,7 @@ class LspManager {
|
|
|
3440
3512
|
async tryDeleteIfOrphaned(key, managed) {
|
|
3441
3513
|
if (managed.refCount === 0 && managed.pendingWaiters === 0 && !managed.isInitializing && this.clients.get(key) === managed) {
|
|
3442
3514
|
this.clients.delete(key);
|
|
3443
|
-
await
|
|
3515
|
+
await this.tombstoneStop(key, managed.client);
|
|
3444
3516
|
}
|
|
3445
3517
|
}
|
|
3446
3518
|
async getClient(root, server2, signal) {
|
|
@@ -3449,12 +3521,22 @@ class LspManager {
|
|
|
3449
3521
|
}
|
|
3450
3522
|
signal?.throwIfAborted();
|
|
3451
3523
|
const key = this.getKey(root, server2.id);
|
|
3524
|
+
for (;; ) {
|
|
3525
|
+
const pendingStop = this.pendingStops.get(key);
|
|
3526
|
+
if (pendingStop === undefined)
|
|
3527
|
+
break;
|
|
3528
|
+
await awaitWithSignal2(pendingStop, signal);
|
|
3529
|
+
signal?.throwIfAborted();
|
|
3530
|
+
}
|
|
3531
|
+
if (this.disposed) {
|
|
3532
|
+
throw new Error("LspManager has been disposed");
|
|
3533
|
+
}
|
|
3452
3534
|
let managed = this.clients.get(key);
|
|
3453
3535
|
if (managed) {
|
|
3454
3536
|
const t = this.now();
|
|
3455
3537
|
if (managed.isInitializing && managed.initializingSince !== null && t - managed.initializingSince > this.initTimeoutMs) {
|
|
3456
|
-
await stopClientBestEffort(managed.client);
|
|
3457
3538
|
this.clients.delete(key);
|
|
3539
|
+
await this.tombstoneStop(key, managed.client);
|
|
3458
3540
|
managed = undefined;
|
|
3459
3541
|
}
|
|
3460
3542
|
}
|
|
@@ -3475,15 +3557,20 @@ class LspManager {
|
|
|
3475
3557
|
signal.throwIfAborted();
|
|
3476
3558
|
}
|
|
3477
3559
|
if (!managed.client.isAlive()) {
|
|
3478
|
-
|
|
3479
|
-
this.clients.
|
|
3560
|
+
this.recordDeadGeneration(key);
|
|
3561
|
+
if (this.clients.get(key) === managed) {
|
|
3562
|
+
this.clients.delete(key);
|
|
3563
|
+
}
|
|
3564
|
+
await this.tombstoneStop(key, managed.client);
|
|
3480
3565
|
return this.getClient(root, server2, signal);
|
|
3481
3566
|
}
|
|
3567
|
+
this.markHealthyGeneration(key);
|
|
3482
3568
|
managed.refCount++;
|
|
3483
3569
|
managed.lastUsedAt = this.now();
|
|
3484
3570
|
return managed.client;
|
|
3485
3571
|
}
|
|
3486
3572
|
this.evictForAdmission();
|
|
3573
|
+
this.ensureRespawnAllowed(key, root, server2.id);
|
|
3487
3574
|
const client = this.clientFactory(root, server2);
|
|
3488
3575
|
const initStartedAt = this.now();
|
|
3489
3576
|
const initPromise = (async () => {
|
|
@@ -3507,7 +3594,7 @@ class LspManager {
|
|
|
3507
3594
|
if (this.clients.get(key) === newManaged) {
|
|
3508
3595
|
this.clients.delete(key);
|
|
3509
3596
|
}
|
|
3510
|
-
await
|
|
3597
|
+
await this.tombstoneStop(key, client);
|
|
3511
3598
|
throw err;
|
|
3512
3599
|
}
|
|
3513
3600
|
newManaged.pendingWaiters--;
|
|
@@ -3518,6 +3605,15 @@ class LspManager {
|
|
|
3518
3605
|
await this.tryDeleteIfOrphaned(key, newManaged);
|
|
3519
3606
|
signal.throwIfAborted();
|
|
3520
3607
|
}
|
|
3608
|
+
if (!client.isAlive()) {
|
|
3609
|
+
this.recordDeadGeneration(key);
|
|
3610
|
+
if (this.clients.get(key) === newManaged) {
|
|
3611
|
+
this.clients.delete(key);
|
|
3612
|
+
}
|
|
3613
|
+
await this.tombstoneStop(key, client);
|
|
3614
|
+
return this.getClient(root, server2, signal);
|
|
3615
|
+
}
|
|
3616
|
+
this.markHealthyGeneration(key);
|
|
3521
3617
|
newManaged.refCount++;
|
|
3522
3618
|
newManaged.lastUsedAt = this.now();
|
|
3523
3619
|
return client;
|
|
@@ -3538,15 +3634,20 @@ class LspManager {
|
|
|
3538
3634
|
if (client && managed.client !== client)
|
|
3539
3635
|
return;
|
|
3540
3636
|
this.clients.delete(key);
|
|
3541
|
-
|
|
3637
|
+
this.tombstoneStop(key, managed.client);
|
|
3542
3638
|
}
|
|
3543
3639
|
warmupClient(root, server2) {
|
|
3544
3640
|
if (this.disposed)
|
|
3545
3641
|
return;
|
|
3546
3642
|
const key = this.getKey(root, server2.id);
|
|
3547
|
-
if (this.clients.has(key))
|
|
3643
|
+
if (this.clients.has(key) || this.pendingStops.has(key))
|
|
3548
3644
|
return;
|
|
3549
3645
|
this.evictForAdmission();
|
|
3646
|
+
try {
|
|
3647
|
+
this.ensureRespawnAllowed(key, root, server2.id);
|
|
3648
|
+
} catch {
|
|
3649
|
+
return;
|
|
3650
|
+
}
|
|
3550
3651
|
const client = this.clientFactory(root, server2);
|
|
3551
3652
|
const initStartedAt = this.now();
|
|
3552
3653
|
const initPromise = (async () => {
|
|
@@ -3572,7 +3673,7 @@ class LspManager {
|
|
|
3572
3673
|
if (this.clients.get(key) === managed) {
|
|
3573
3674
|
this.clients.delete(key);
|
|
3574
3675
|
}
|
|
3575
|
-
|
|
3676
|
+
this.tombstoneStop(key, client);
|
|
3576
3677
|
});
|
|
3577
3678
|
}
|
|
3578
3679
|
isServerInitializing(root, serverId) {
|
|
@@ -3616,8 +3717,11 @@ class LspManager {
|
|
|
3616
3717
|
for (const managed of this.clients.values()) {
|
|
3617
3718
|
stopPromises.push(stopClientBestEffort(managed.client));
|
|
3618
3719
|
}
|
|
3720
|
+
const tombstonedStops = [...this.pendingStops.values()];
|
|
3619
3721
|
this.clients.clear();
|
|
3620
|
-
|
|
3722
|
+
this.respawnBudgets.clear();
|
|
3723
|
+
await Promise.allSettled([...stopPromises, ...tombstonedStops]);
|
|
3724
|
+
this.pendingStops.clear();
|
|
3621
3725
|
}
|
|
3622
3726
|
}
|
|
3623
3727
|
var _defaultInstance = null;
|
|
@@ -3627,7 +3731,16 @@ function getLspManager() {
|
|
|
3627
3731
|
}
|
|
3628
3732
|
return _defaultInstance;
|
|
3629
3733
|
}
|
|
3630
|
-
var
|
|
3734
|
+
var GIT_WORKSPACE_MARKER = ".git";
|
|
3735
|
+
var PROJECT_WORKSPACE_MARKERS = [
|
|
3736
|
+
"package.json",
|
|
3737
|
+
"pyproject.toml",
|
|
3738
|
+
"Cargo.toml",
|
|
3739
|
+
"go.mod",
|
|
3740
|
+
"pom.xml",
|
|
3741
|
+
"build.gradle"
|
|
3742
|
+
];
|
|
3743
|
+
var WORKSPACE_MARKERS = [GIT_WORKSPACE_MARKER, ...PROJECT_WORKSPACE_MARKERS];
|
|
3631
3744
|
function findWorkspaceRootOutsideContext(directory) {
|
|
3632
3745
|
const marked = nearestMarkedAncestor(directory);
|
|
3633
3746
|
if (marked !== undefined)
|
|
@@ -4297,20 +4410,25 @@ function findWorkspaceRoot(filePath) {
|
|
|
4297
4410
|
if (!isPathInside(cwd, abs))
|
|
4298
4411
|
return findWorkspaceRootOutsideContext(dir);
|
|
4299
4412
|
const fallbackRoot = nearestExistingDirectoryInsideContext(dir, cwd) ?? cwd;
|
|
4413
|
+
let nearestPackageRoot;
|
|
4300
4414
|
while (isPathInside(cwd, dir)) {
|
|
4301
4415
|
const canonicalDir = existingDirectoryInsideContext(dir, cwd);
|
|
4302
4416
|
if (canonicalDir !== undefined) {
|
|
4303
|
-
|
|
4304
|
-
|
|
4305
|
-
|
|
4306
|
-
|
|
4417
|
+
if (existsSync11(join5(dir, GIT_WORKSPACE_MARKER))) {
|
|
4418
|
+
return canonicalDir;
|
|
4419
|
+
}
|
|
4420
|
+
if (nearestPackageRoot === undefined && hasProjectWorkspaceMarker(dir)) {
|
|
4421
|
+
nearestPackageRoot = canonicalDir;
|
|
4307
4422
|
}
|
|
4308
4423
|
}
|
|
4309
4424
|
if (dir === cwd)
|
|
4310
4425
|
break;
|
|
4311
4426
|
dir = dirname10(dir);
|
|
4312
4427
|
}
|
|
4313
|
-
return fallbackRoot;
|
|
4428
|
+
return nearestPackageRoot ?? fallbackRoot;
|
|
4429
|
+
}
|
|
4430
|
+
function hasProjectWorkspaceMarker(directory) {
|
|
4431
|
+
return PROJECT_WORKSPACE_MARKERS.some((marker) => existsSync11(join5(directory, marker)));
|
|
4314
4432
|
}
|
|
4315
4433
|
function resolveReadablePathInsideContext(filePath) {
|
|
4316
4434
|
const cwd = contextCwd();
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"type": "command",
|
|
9
9
|
"command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook post-tool-use",
|
|
10
10
|
"timeout": 60,
|
|
11
|
-
"statusMessage": "(OmO 5.0.0-beta.
|
|
11
|
+
"statusMessage": "(OmO 5.0.0-beta.32) Checking LSP Diagnostics"
|
|
12
12
|
}
|
|
13
13
|
]
|
|
14
14
|
}
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"type": "command",
|
|
22
22
|
"command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook post-compact",
|
|
23
23
|
"timeout": 5,
|
|
24
|
-
"statusMessage": "(OmO 5.0.0-beta.
|
|
24
|
+
"statusMessage": "(OmO 5.0.0-beta.32) Resetting LSP Diagnostics Cache"
|
|
25
25
|
}
|
|
26
26
|
]
|
|
27
27
|
}
|