oh-my-opencode 4.18.2 → 4.19.1
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/omomomo.md +1 -1
- package/.agents/skills/omomomo/SKILL.md +1 -1
- package/.opencode/command/omomomo.md +1 -1
- package/README.ja.md +6 -6
- package/README.ko.md +6 -6
- package/README.md +8 -8
- package/README.ru.md +6 -6
- package/README.zh-cn.md +6 -6
- package/dist/agents/atlas/agent.d.ts +7 -6
- package/dist/agents/gpt-prompt-identity.d.ts +3 -0
- package/dist/agents/sisyphus/gpt-5-5.d.ts +1 -1
- package/dist/agents/sisyphus/gpt-task-system-guide.d.ts +1 -0
- package/dist/agents/sisyphus/index.d.ts +5 -0
- package/dist/agents/sisyphus/kimi-k3.d.ts +19 -0
- package/dist/agents/sisyphus-agent-factory.d.ts +1 -1
- package/dist/agents/sisyphus-junior/agent.d.ts +8 -4
- package/dist/agents/sisyphus-junior/gpt-5-5.d.ts +2 -2
- package/dist/agents/sisyphus-junior/index.d.ts +2 -0
- package/dist/agents/sisyphus-junior/kimi-k3.d.ts +12 -0
- package/dist/agents/types.d.ts +2 -2
- package/dist/cli/index.js +781 -215
- package/dist/cli-node/index.js +781 -215
- package/dist/config/index.d.ts +1 -1
- package/dist/config/schema/agent-overrides.d.ts +48 -48
- package/dist/config/schema/browser-automation.d.ts +1 -0
- package/dist/config/schema/categories.d.ts +6 -6
- package/dist/config/schema/codegraph.d.ts +2 -0
- package/dist/config/schema/commands.d.ts +1 -3
- package/dist/config/schema/default-mode.d.ts +1 -1
- package/dist/config/schema/fallback-models.d.ts +5 -5
- package/dist/config/schema/goal.d.ts +7 -0
- package/dist/config/schema/hooks.d.ts +1 -1
- package/dist/config/schema/oh-my-opencode-config.d.ts +56 -58
- package/dist/config/schema/ralph-loop.d.ts +1 -1
- package/dist/config/schema.d.ts +1 -1
- package/dist/create-hooks.d.ts +1 -1
- package/dist/features/builtin-commands/templates/goal.d.ts +1 -0
- package/dist/features/builtin-commands/templates/stop-continuation.d.ts +1 -1
- package/dist/features/builtin-commands/types.d.ts +1 -1
- package/dist/hooks/auto-slash-command/executor.d.ts +1 -0
- package/dist/hooks/codegraph-bootstrap/hook.d.ts +3 -2
- package/dist/hooks/goal/command-arguments.d.ts +13 -0
- package/dist/hooks/goal/controller.d.ts +26 -0
- package/dist/hooks/goal/index.d.ts +23 -0
- package/dist/hooks/goal/prompt.d.ts +3 -0
- package/dist/hooks/goal/store.d.ts +8 -0
- package/dist/hooks/goal/tools.d.ts +10 -0
- package/dist/hooks/goal/types.d.ts +93 -0
- package/dist/hooks/goal/validation.d.ts +4 -0
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/keyword-detector/hook.d.ts +1 -2
- package/dist/hooks/ralph-loop/types.d.ts +1 -1
- package/dist/hooks/sisyphus-junior-notepad/constants.d.ts +1 -1
- package/dist/hooks/start-work/notepad-scaffold.d.ts +10 -0
- package/dist/index.js +5398 -5109
- package/dist/oh-my-opencode.schema.json +34 -19
- package/dist/plugin/chat-message/loop-commands.d.ts +1 -1
- package/dist/plugin/chat-message/types.d.ts +23 -10
- package/dist/plugin/hooks/create-core-hooks.d.ts +1 -1
- package/dist/plugin/hooks/create-session-hooks.d.ts +3 -2
- package/dist/plugin/hooks/create-transform-hooks.d.ts +0 -2
- package/dist/plugin/stop-continuation.d.ts +2 -2
- package/dist/shared/omo-process-sweep.d.ts +18 -0
- package/dist/shared/system-directive.d.ts +0 -1
- package/dist/skills/programming/scripts/typescript/check-no-excuse-rules.test.ts +87 -0
- package/dist/skills/programming/scripts/typescript/check-no-excuse-rules.ts +35 -5
- package/dist/skills/ulw-plan/SKILL.md +31 -8
- package/dist/skills/ulw-plan/references/full-workflow.md +117 -6
- package/dist/skills/ulw-plan/scripts/scaffold-plan.mjs +46 -10
- package/dist/skills/ulw-research/SKILL.md +3 -3
- package/dist/testing/create-plugin-module.d.ts +1 -0
- package/dist/tools/delegate-task/types.d.ts +0 -1
- package/dist/tui.js +138 -80
- package/package.json +14 -14
- package/packages/git-bash-mcp/dist/cli.js +54 -8
- package/packages/lsp-core/src/lsp/client-diagnostics-freshness.integration.test.ts +60 -0
- package/packages/lsp-core/src/lsp/client.ts +14 -1
- package/packages/lsp-core/src/lsp/fixtures/diagnostics-freshness-contract-probe.ts +2 -2
- package/packages/lsp-core/src/mcp.ts +9 -0
- package/packages/lsp-daemon/dist/cli.js +319 -51
- package/packages/lsp-daemon/dist/client.js +136 -48
- package/packages/lsp-daemon/dist/daemon-client.d.ts +0 -10
- package/packages/lsp-daemon/dist/daemon-client.js +4 -34
- package/packages/lsp-daemon/dist/daemon-failure-result.d.ts +3 -0
- package/packages/lsp-daemon/dist/daemon-failure-result.js +38 -0
- package/packages/lsp-daemon/dist/daemon-request-error.d.ts +14 -0
- package/packages/lsp-daemon/dist/daemon-request-error.js +26 -0
- package/packages/lsp-daemon/dist/daemon-server.js +5 -1
- package/packages/lsp-daemon/dist/index.js +137 -48
- package/packages/lsp-daemon/dist/proxy.d.ts +2 -0
- package/packages/lsp-daemon/dist/proxy.js +1 -0
- package/packages/lsp-daemon/dist/version-reap.d.ts +26 -0
- package/packages/lsp-daemon/dist/version-reap.js +182 -0
- package/packages/lsp-tools-mcp/dist/cli.js +61 -10
- package/packages/lsp-tools-mcp/dist/lsp/manager.js +6 -1
- package/packages/lsp-tools-mcp/dist/mcp.js +61 -10
- package/packages/lsp-tools-mcp/dist/tools.js +6 -1
- package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +416 -25
- 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/setup.ts +22 -2
- package/packages/omo-codex/plugin/components/codegraph/AGENTS.md +7 -6
- package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +638 -267
- package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +178 -89
- package/packages/omo-codex/plugin/components/codegraph/package.json +2 -2
- package/packages/omo-codex/plugin/components/codegraph/src/hook-types.ts +3 -1
- package/packages/omo-codex/plugin/components/codegraph/src/hook.ts +3 -1
- package/packages/omo-codex/plugin/components/codegraph/src/mcp-bridge.ts +98 -32
- package/packages/omo-codex/plugin/components/codegraph/src/mcp-unavailable.ts +5 -0
- package/packages/omo-codex/plugin/components/codegraph/src/serve.ts +15 -6
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker.ts +6 -2
- package/packages/omo-codex/plugin/components/codegraph/src/sweep-cli.ts +1 -0
- package/packages/omo-codex/plugin/components/codegraph/test/hook-exclusion.test.ts +1 -1
- package/packages/omo-codex/plugin/components/codegraph/test/hook-store-upgrade.test.ts +148 -0
- package/packages/omo-codex/plugin/components/codegraph/test/mcp-bridge-fixtures.ts +31 -2
- package/packages/omo-codex/plugin/components/codegraph/test/package-runtime.test.ts +1 -1
- package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge-lifecycle.test.ts +65 -1
- package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge.test.ts +3 -7
- package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-facade.test.ts +1 -1
- package/packages/omo-codex/plugin/components/codegraph/test/serve-provision.test.ts +57 -3
- package/packages/omo-codex/plugin/components/codegraph/test/serve-unavailable.test.ts +41 -0
- package/packages/omo-codex/plugin/components/codegraph/test/serve.test.ts +109 -8
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-node-support.test.ts +2 -2
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-flow.test.ts +43 -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/AGENTS.md +1 -0
- package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +3 -3
- package/packages/omo-codex/plugin/components/lsp/dist/cli.js +80 -40
- 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/dist/cli.js +11 -0
- 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/rules/src/post-compact-budget.ts +11 -0
- package/packages/omo-codex/plugin/components/rules/test/post-compact-budget.test.ts +60 -0
- package/packages/omo-codex/plugin/components/start-work-continuation/AGENTS.md +8 -0
- package/packages/omo-codex/plugin/components/start-work-continuation/dist/cli.js +147 -60
- package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/start-work-continuation/package.json +1 -1
- package/packages/omo-codex/plugin/components/start-work-continuation/src/boulder-reader.ts +3 -71
- package/packages/omo-codex/plugin/components/start-work-continuation/src/plan-checklist.ts +171 -0
- package/packages/omo-codex/plugin/components/start-work-continuation/test/boulder-reader.test.ts +198 -23
- package/packages/omo-codex/plugin/components/start-work-continuation/test/cli.test.ts +4 -3
- package/packages/omo-codex/plugin/components/start-work-continuation/test/codex-hook.test.ts +6 -5
- package/packages/omo-codex/plugin/components/start-work-continuation/test/fixtures/plan-scaffold.md +15 -0
- 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 +10 -10
- package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-clone-fidelity-reviewer.toml +2 -2
- package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-code-reviewer.toml +2 -2
- package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-gate-reviewer.toml +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-high.toml +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-medium.toml +2 -2
- package/packages/omo-codex/plugin/components/ultrawork/agents/momus.toml +3 -3
- package/packages/omo-codex/plugin/components/ultrawork/agents/plan.toml +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +31 -8
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +117 -6
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/scripts/scaffold-plan.mjs +46 -10
- package/packages/omo-codex/plugin/components/ultrawork/src/codex-hook.ts +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook-trigger-policy.test.ts +42 -0
- package/packages/omo-codex/plugin/components/ulw-loop/README.md +6 -4
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-continuation.d.ts +21 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-continuation.js +64 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.js +15 -2
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-arg-parser.js +1 -1
- 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 +3 -3
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-steering.d.ts +3 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-steering.js +85 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-subcommands.d.ts +0 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-subcommands.js +13 -33
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +998 -593
- package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.js +1 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/constants.d.ts +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/constants.js +2 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/domain-types.d.ts +6 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/goal-status.d.ts +1 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/goal-status.js +3 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-crud.d.ts +1 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-crud.js +4 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.d.ts +1 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.js +10 -2
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-verdicts.js +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-batch.d.ts +15 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-batch.js +84 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-mutations.d.ts +5 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-mutations.js +81 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/steering.js +7 -59
- package/packages/omo-codex/plugin/components/ulw-loop/dist/stop-resume-hook.js +12 -4
- package/packages/omo-codex/plugin/components/ulw-loop/dist/validation-batch.d.ts +9 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/validation-batch.js +122 -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 +8 -6
- package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-continuation.ts +84 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint.ts +13 -2
- package/packages/omo-codex/plugin/components/ulw-loop/src/cli-arg-parser.ts +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/cli-commands.ts +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/cli-output.ts +3 -3
- package/packages/omo-codex/plugin/components/ulw-loop/src/cli-steering.ts +49 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/cli-subcommands.ts +13 -45
- package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-instruction.ts +1 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/constants.ts +2 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/domain-types.ts +7 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/goal-status.ts +4 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/plan-crud.ts +4 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/plan-io.ts +20 -2
- package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-verdicts.ts +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/steering-batch.ts +125 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/steering-mutations.ts +59 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/steering.ts +6 -58
- package/packages/omo-codex/plugin/components/ulw-loop/src/stop-resume-hook.ts +12 -4
- package/packages/omo-codex/plugin/components/ulw-loop/src/validation-batch.ts +122 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-continuation.test.ts +76 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/cli-checkpoint-continuation.test.ts +111 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/cli-steering-batch.test.ts +67 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/cli-validation-batch.test.ts +57 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/paths.test.ts +1 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/steering-batch.test.ts +152 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/stop-resume-hook.test.ts +29 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/validation-batch-checkpoint.test.ts +147 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/validation-batch.test.ts +73 -0
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +2 -2
- 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 +2 -2
- 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 +2 -2
- package/packages/omo-codex/plugin/hooks/stop-checking-start-work-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-start-work-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 +41 -41
- package/packages/omo-codex/plugin/package.json +1 -1
- package/packages/omo-codex/plugin/scripts/migrate-codex-config/multi-agent-v2-guard.mjs +32 -28
- package/packages/omo-codex/plugin/scripts/migrate-codex-config/subagent-limit-guard.mjs +17 -45
- package/packages/omo-codex/plugin/scripts/migrate-codex-config/toml-section-editor.mjs +455 -0
- package/packages/omo-codex/plugin/scripts/sync-skills.mjs +3 -18
- package/packages/omo-codex/plugin/shared/test/config-loader.test.ts +43 -0
- package/packages/omo-codex/plugin/skills/programming/scripts/typescript/check-no-excuse-rules.ts +35 -5
- package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +8 -6
- package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +31 -8
- package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +117 -6
- package/packages/omo-codex/plugin/skills/ulw-plan/scripts/scaffold-plan.mjs +46 -10
- package/packages/omo-codex/plugin/test/aggregate-agents.test.mjs +11 -11
- package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +26 -0
- package/packages/omo-codex/plugin/test/bootstrap-setup.test.mjs +41 -0
- package/packages/omo-codex/plugin/test/lcx-bug-skills.test.mjs +2 -2
- package/packages/omo-codex/plugin/test/migrate-codex-config.test.mjs +6 -6
- package/packages/omo-codex/plugin/test/multi-agent-v2-regression.test.mjs +3 -3
- package/packages/omo-codex/plugin/test/scaffold-plan.test.mjs +62 -0
- package/packages/omo-codex/plugin/test/subagent-limit-migration.test.mjs +271 -14
- package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +3 -18
- package/packages/omo-codex/plugin/test/sync-skills.test.mjs +0 -5
- package/packages/omo-codex/plugin/test/ulw-plan-review-state-contract.test.mjs +293 -0
- package/packages/omo-codex/scripts/install-config.test.mjs +10 -10
- package/packages/omo-codex/scripts/install-dist/install-local.mjs +401 -22
- package/packages/omo-codex/scripts/install-generated-bundle.test.mjs +39 -2
- package/packages/omo-codex/scripts/install-marketplace-cache.test.mjs +4 -1
- package/packages/shared-skills/skills/programming/scripts/typescript/check-no-excuse-rules.test.ts +87 -0
- package/packages/shared-skills/skills/programming/scripts/typescript/check-no-excuse-rules.ts +35 -5
- package/packages/shared-skills/skills/ulw-plan/SKILL.md +31 -8
- package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +117 -6
- package/packages/shared-skills/skills/ulw-plan/scripts/scaffold-plan.mjs +46 -10
- package/packages/shared-skills/skills/ulw-research/SKILL.md +3 -3
- package/dist/features/builtin-commands/templates/ralph-loop.d.ts +0 -3
- package/dist/skills/ultraresearch/SKILL.md +0 -10
- package/packages/shared-skills/skills/lcx-contribute-bug-fix/SKILL.md +0 -273
- package/packages/shared-skills/skills/lcx-contribute-bug-fix/agents/openai.yaml +0 -12
- package/packages/shared-skills/skills/lcx-contribute-bug-fix/scripts/create-pr-body.mjs +0 -107
- package/packages/shared-skills/skills/lcx-doctor/SKILL.md +0 -128
- package/packages/shared-skills/skills/lcx-doctor/agents/openai.yaml +0 -11
- package/packages/shared-skills/skills/lcx-report-bug/SKILL.md +0 -268
- package/packages/shared-skills/skills/lcx-report-bug/agents/openai.yaml +0 -11
- package/packages/shared-skills/skills/ultraresearch/SKILL.md +0 -10
- /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-contribute-bug-fix/SKILL.md +0 -0
- /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-contribute-bug-fix/agents/openai.yaml +0 -0
- /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-contribute-bug-fix/scripts/create-pr-body.mjs +0 -0
- /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-doctor/SKILL.md +0 -0
- /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-doctor/agents/openai.yaml +0 -0
- /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-report-bug/SKILL.md +0 -0
- /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-report-bug/agents/openai.yaml +0 -0
|
@@ -177,6 +177,81 @@ function isPlainRecord(value) {
|
|
|
177
177
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
178
178
|
}
|
|
179
179
|
|
|
180
|
+
// src/daemon-request-error.ts
|
|
181
|
+
class DaemonRequestError extends Error {
|
|
182
|
+
requestWritten;
|
|
183
|
+
constructor(message, requestWritten) {
|
|
184
|
+
super(message);
|
|
185
|
+
this.name = "DaemonRequestError";
|
|
186
|
+
this.requestWritten = requestWritten;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
class DaemonAuthenticationRejectedError extends DaemonRequestError {
|
|
191
|
+
constructor() {
|
|
192
|
+
super("daemon authentication failed before dispatch", true);
|
|
193
|
+
this.name = "DaemonAuthenticationRejectedError";
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
class DaemonRequestCancelledError extends DaemonRequestError {
|
|
198
|
+
constructor(requestWritten) {
|
|
199
|
+
super("daemon request cancelled", requestWritten);
|
|
200
|
+
this.name = "DaemonRequestCancelledError";
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
class DaemonRequestTimedOutError extends DaemonRequestError {
|
|
205
|
+
timeoutMs;
|
|
206
|
+
constructor(requestWritten, timeoutMs) {
|
|
207
|
+
super("daemon request timed out", requestWritten);
|
|
208
|
+
this.name = "DaemonRequestTimedOutError";
|
|
209
|
+
this.timeoutMs = timeoutMs;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// src/daemon-failure-result.ts
|
|
214
|
+
function daemonFailureResult(paths, error) {
|
|
215
|
+
if (error instanceof DaemonRequestCancelledError)
|
|
216
|
+
return daemonCancelledResult(paths);
|
|
217
|
+
if (error instanceof DaemonRequestTimedOutError)
|
|
218
|
+
return daemonTimedOutResult(paths, error.timeoutMs);
|
|
219
|
+
return daemonUnreachableResult(paths, error);
|
|
220
|
+
}
|
|
221
|
+
function daemonCancelledResult(paths) {
|
|
222
|
+
const text = [
|
|
223
|
+
"LSP daemon request cancelled: the caller aborted this request (for example, the turn was interrupted).",
|
|
224
|
+
"The daemon stays available; no LSP work was applied. Retry when you are ready.",
|
|
225
|
+
`Socket: ${paths.socket}`
|
|
226
|
+
].join(`
|
|
227
|
+
`);
|
|
228
|
+
return { content: [{ type: "text", text }], isError: true };
|
|
229
|
+
}
|
|
230
|
+
function daemonTimedOutResult(paths, timeoutMs) {
|
|
231
|
+
const text = [
|
|
232
|
+
`LSP daemon request timed out after ${timeoutMs}ms: the daemon did not respond in time.`,
|
|
233
|
+
"The daemon stays available but may be busy. Retry when you are ready.",
|
|
234
|
+
`Socket: ${paths.socket}`,
|
|
235
|
+
`Logs: ${paths.log}`
|
|
236
|
+
].join(`
|
|
237
|
+
`);
|
|
238
|
+
return { content: [{ type: "text", text }], isError: true };
|
|
239
|
+
}
|
|
240
|
+
function daemonUnreachableResult(paths, error) {
|
|
241
|
+
const text = [
|
|
242
|
+
`LSP daemon unreachable: ${errorText(error)}.`,
|
|
243
|
+
"The MCP server is a thin proxy and never runs language servers in-process.",
|
|
244
|
+
`Socket: ${paths.socket}`,
|
|
245
|
+
`Logs: ${paths.log}`,
|
|
246
|
+
"The daemon is auto-started on demand and will be retried on the next request."
|
|
247
|
+
].join(`
|
|
248
|
+
`);
|
|
249
|
+
return { content: [{ type: "text", text }], isError: true };
|
|
250
|
+
}
|
|
251
|
+
function errorText(error) {
|
|
252
|
+
return error instanceof Error ? error.message : String(error);
|
|
253
|
+
}
|
|
254
|
+
|
|
180
255
|
// src/ensure-daemon.ts
|
|
181
256
|
import { spawn } from "node:child_process";
|
|
182
257
|
import { closeSync as closeSync2, mkdirSync as mkdirSync2, openSync as openSync2 } from "node:fs";
|
|
@@ -904,16 +979,35 @@ function bufferFromChunk(chunk) {
|
|
|
904
979
|
|
|
905
980
|
// ../mcp-stdio-core/src/server.ts
|
|
906
981
|
var DEFAULT_IDLE_TIMEOUT_MS = 10 * 60000;
|
|
982
|
+
var DEFAULT_PARENT_POLL_INTERVAL_MS = 30000;
|
|
907
983
|
var noopLog = () => {};
|
|
984
|
+
function isProcessAlive(pid) {
|
|
985
|
+
try {
|
|
986
|
+
process.kill(pid, 0);
|
|
987
|
+
return true;
|
|
988
|
+
} catch (error) {
|
|
989
|
+
return !hasErrorCode(error, "ESRCH");
|
|
990
|
+
}
|
|
991
|
+
}
|
|
908
992
|
async function runJsonRpcStdioServer(config) {
|
|
909
993
|
const log = config.log ?? noopLog;
|
|
910
994
|
const idleTimeoutMs = config.idleTimeoutMs ?? DEFAULT_IDLE_TIMEOUT_MS;
|
|
911
|
-
|
|
995
|
+
let isClosed = false;
|
|
996
|
+
const idleTimer = createIdleTimer(idleTimeoutMs, log, () => {
|
|
997
|
+
isClosed = true;
|
|
998
|
+
config.onIdleTimeout?.();
|
|
999
|
+
});
|
|
1000
|
+
const watchdog = createParentWatchdog(config.parentWatchdog, (parentPid, pollIntervalMs) => {
|
|
1001
|
+
isClosed = true;
|
|
1002
|
+
log("parent_exit", { parent_pid: parentPid, poll_interval_ms: pollIntervalMs });
|
|
1003
|
+
config.onParentExit?.();
|
|
1004
|
+
config.input.destroy();
|
|
1005
|
+
});
|
|
912
1006
|
log("stdio_started", { cwd: process.cwd(), idle_timeout_ms: idleTimeoutMs });
|
|
913
1007
|
idleTimer.arm();
|
|
914
1008
|
try {
|
|
915
1009
|
for await (const message of readStdioJsonRpcMessages(config.input)) {
|
|
916
|
-
if (
|
|
1010
|
+
if (isClosed)
|
|
917
1011
|
break;
|
|
918
1012
|
idleTimer.arm();
|
|
919
1013
|
if (message.kind === "parse_error") {
|
|
@@ -924,8 +1018,12 @@ async function runJsonRpcStdioServer(config) {
|
|
|
924
1018
|
if (!await handleRequest(message, config, log))
|
|
925
1019
|
break;
|
|
926
1020
|
}
|
|
1021
|
+
} catch (error) {
|
|
1022
|
+
if (!(isClosed && hasErrorCode(error, "ERR_STREAM_PREMATURE_CLOSE")))
|
|
1023
|
+
throw error;
|
|
927
1024
|
} finally {
|
|
928
1025
|
idleTimer.clear();
|
|
1026
|
+
watchdog.clear();
|
|
929
1027
|
log("stdio_stopped");
|
|
930
1028
|
}
|
|
931
1029
|
}
|
|
@@ -981,9 +1079,33 @@ function isTerminalOutputError(error) {
|
|
|
981
1079
|
return false;
|
|
982
1080
|
return error.code === "EPIPE" || error.code === "ERR_STREAM_DESTROYED" || error.code === "ERR_STREAM_WRITE_AFTER_END";
|
|
983
1081
|
}
|
|
984
|
-
function
|
|
1082
|
+
function hasErrorCode(error, code) {
|
|
1083
|
+
return error instanceof Error && "code" in error && error.code === code;
|
|
1084
|
+
}
|
|
1085
|
+
function createParentWatchdog(config, onDeadParent) {
|
|
1086
|
+
if (config === undefined)
|
|
1087
|
+
return { clear: () => {} };
|
|
1088
|
+
const pollIntervalMs = config.pollIntervalMs ?? DEFAULT_PARENT_POLL_INTERVAL_MS;
|
|
1089
|
+
if (pollIntervalMs <= 0)
|
|
1090
|
+
return { clear: () => {} };
|
|
1091
|
+
const parentPid = config.parentPid ?? process.ppid;
|
|
1092
|
+
const probeAlive = config.probeAlive ?? isProcessAlive;
|
|
1093
|
+
let fired = false;
|
|
1094
|
+
const timer = setInterval(() => {
|
|
1095
|
+
if (fired || probeAlive(parentPid))
|
|
1096
|
+
return;
|
|
1097
|
+
fired = true;
|
|
1098
|
+
onDeadParent(parentPid, pollIntervalMs);
|
|
1099
|
+
}, pollIntervalMs);
|
|
1100
|
+
timer.unref();
|
|
1101
|
+
return {
|
|
1102
|
+
clear: () => {
|
|
1103
|
+
clearInterval(timer);
|
|
1104
|
+
}
|
|
1105
|
+
};
|
|
1106
|
+
}
|
|
1107
|
+
function createIdleTimer(idleTimeoutMs, log, onTimeout) {
|
|
985
1108
|
let timer = null;
|
|
986
|
-
let isClosed = false;
|
|
987
1109
|
return {
|
|
988
1110
|
arm: () => {
|
|
989
1111
|
if (timer !== null)
|
|
@@ -991,9 +1113,8 @@ function createIdleTimer(idleTimeoutMs, log, onIdleTimeout) {
|
|
|
991
1113
|
if (idleTimeoutMs <= 0)
|
|
992
1114
|
return;
|
|
993
1115
|
timer = setTimeout(() => {
|
|
994
|
-
isClosed = true;
|
|
995
1116
|
log("idle_timeout", { idle_timeout_ms: idleTimeoutMs });
|
|
996
|
-
|
|
1117
|
+
onTimeout();
|
|
997
1118
|
}, idleTimeoutMs);
|
|
998
1119
|
timer.unref();
|
|
999
1120
|
},
|
|
@@ -1002,8 +1123,7 @@ function createIdleTimer(idleTimeoutMs, log, onIdleTimeout) {
|
|
|
1002
1123
|
return;
|
|
1003
1124
|
clearTimeout(timer);
|
|
1004
1125
|
timer = null;
|
|
1005
|
-
}
|
|
1006
|
-
closed: () => isClosed
|
|
1126
|
+
}
|
|
1007
1127
|
};
|
|
1008
1128
|
}
|
|
1009
1129
|
// ../lsp-core/src/lsp/client-wrapper.ts
|
|
@@ -3625,8 +3745,13 @@ class LspClient extends LspClientConnection {
|
|
|
3625
3745
|
if (!pushFallbackOnly)
|
|
3626
3746
|
continue;
|
|
3627
3747
|
const remainingMs = deadlineAt - Date.now();
|
|
3628
|
-
if (remainingMs <= 0)
|
|
3748
|
+
if (remainingMs <= 0) {
|
|
3749
|
+
if (!this.isDiagnosticPullSupported() && snapshot.publishGeneration === 0) {
|
|
3750
|
+
const cached = this.documents.getPullCache(snapshot);
|
|
3751
|
+
return { items: cached === null ? [] : [...cached.diagnostics] };
|
|
3752
|
+
}
|
|
3629
3753
|
return this.freshnessTimeout(absPath);
|
|
3754
|
+
}
|
|
3630
3755
|
const waitMs = push.status === "wait" ? Math.min(push.waitMs, remainingMs) : remainingMs;
|
|
3631
3756
|
await waitForDiagnosticsActivity(this.documents.waitForDiagnosticsActivity(snapshot, waitMs), signal);
|
|
3632
3757
|
}
|
|
@@ -5715,29 +5840,6 @@ function parseContext(value) {
|
|
|
5715
5840
|
// src/daemon-client.ts
|
|
5716
5841
|
var DEFAULT_REQUEST_TIMEOUT_MS = 30000;
|
|
5717
5842
|
var nextProxyRequestId = 1;
|
|
5718
|
-
|
|
5719
|
-
class DaemonRequestError extends Error {
|
|
5720
|
-
requestWritten;
|
|
5721
|
-
constructor(message, requestWritten) {
|
|
5722
|
-
super(message);
|
|
5723
|
-
this.name = "DaemonRequestError";
|
|
5724
|
-
this.requestWritten = requestWritten;
|
|
5725
|
-
}
|
|
5726
|
-
}
|
|
5727
|
-
|
|
5728
|
-
class DaemonAuthenticationRejectedError extends DaemonRequestError {
|
|
5729
|
-
constructor() {
|
|
5730
|
-
super("daemon authentication failed before dispatch", true);
|
|
5731
|
-
this.name = "DaemonAuthenticationRejectedError";
|
|
5732
|
-
}
|
|
5733
|
-
}
|
|
5734
|
-
|
|
5735
|
-
class DaemonRequestCancelledError extends DaemonRequestError {
|
|
5736
|
-
constructor(requestWritten) {
|
|
5737
|
-
super("daemon request cancelled", requestWritten);
|
|
5738
|
-
this.name = "DaemonRequestCancelledError";
|
|
5739
|
-
}
|
|
5740
|
-
}
|
|
5741
5843
|
async function callToolViaDaemon(name, args, options) {
|
|
5742
5844
|
const context = requireContext(options.context);
|
|
5743
5845
|
const paths = options.paths ?? daemonPaths();
|
|
@@ -5766,7 +5868,7 @@ async function callToolViaDaemon(name, args, options) {
|
|
|
5766
5868
|
break;
|
|
5767
5869
|
}
|
|
5768
5870
|
}
|
|
5769
|
-
return
|
|
5871
|
+
return daemonFailureResult(paths, lastError);
|
|
5770
5872
|
}
|
|
5771
5873
|
function callDiagnosticsViaDaemon(filePath, options) {
|
|
5772
5874
|
return callToolViaDaemon("diagnostics", { filePath, severity: "error" }, options);
|
|
@@ -5811,17 +5913,6 @@ function ensureDaemonAvailable(paths, ensure, signal) {
|
|
|
5811
5913
|
Promise.resolve().then(() => ensure(paths, signal)).then(() => finish(() => resolve9()), (error) => finish(() => reject(signal.aborted ? new DaemonRequestCancelledError(false) : error)));
|
|
5812
5914
|
});
|
|
5813
5915
|
}
|
|
5814
|
-
function daemonUnreachableResult(paths, error) {
|
|
5815
|
-
const text2 = [
|
|
5816
|
-
`LSP daemon unreachable: ${errorText(error)}.`,
|
|
5817
|
-
"The MCP server is a thin proxy and never runs language servers in-process.",
|
|
5818
|
-
`Socket: ${paths.socket}`,
|
|
5819
|
-
`Logs: ${paths.log}`,
|
|
5820
|
-
"The daemon is auto-started on demand and will be retried on the next request."
|
|
5821
|
-
].join(`
|
|
5822
|
-
`);
|
|
5823
|
-
return { content: [{ type: "text", text: text2 }], isError: true };
|
|
5824
|
-
}
|
|
5825
5916
|
function sendToolCall(paths, token, name, args, options) {
|
|
5826
5917
|
return new Promise((resolve9, reject) => {
|
|
5827
5918
|
const socket = connect(paths.socket);
|
|
@@ -5861,7 +5952,7 @@ function sendToolCall(paths, token, name, args, options) {
|
|
|
5861
5952
|
};
|
|
5862
5953
|
const timer = setTimeout(() => {
|
|
5863
5954
|
sendCancel();
|
|
5864
|
-
finish(() => reject(new
|
|
5955
|
+
finish(() => reject(new DaemonRequestTimedOutError(requestWritten, options.timeoutMs)));
|
|
5865
5956
|
}, options.timeoutMs);
|
|
5866
5957
|
timer.unref();
|
|
5867
5958
|
if (options.signal?.aborted) {
|
|
@@ -5920,9 +6011,6 @@ function allocateProxyRequestId() {
|
|
|
5920
6011
|
function isRetryableTool(name) {
|
|
5921
6012
|
return name !== "rename" && name !== "lsp_rename";
|
|
5922
6013
|
}
|
|
5923
|
-
function errorText(error) {
|
|
5924
|
-
return error instanceof Error ? error.message : String(error);
|
|
5925
|
-
}
|
|
5926
6014
|
|
|
5927
6015
|
// src/client.ts
|
|
5928
6016
|
import { statSync as statSync5 } from "node:fs";
|
|
@@ -1,16 +1,6 @@
|
|
|
1
1
|
import { type LspRequestContext } from "@oh-my-opencode/lsp-core/request-context";
|
|
2
2
|
import type { ToolExecutionResult } from "@oh-my-opencode/lsp-core/tools";
|
|
3
3
|
import { type DaemonPaths } from "./paths.js";
|
|
4
|
-
export declare class DaemonRequestError extends Error {
|
|
5
|
-
readonly requestWritten: boolean;
|
|
6
|
-
constructor(message: string, requestWritten: boolean);
|
|
7
|
-
}
|
|
8
|
-
export declare class DaemonAuthenticationRejectedError extends DaemonRequestError {
|
|
9
|
-
constructor();
|
|
10
|
-
}
|
|
11
|
-
export declare class DaemonRequestCancelledError extends DaemonRequestError {
|
|
12
|
-
constructor(requestWritten: boolean);
|
|
13
|
-
}
|
|
14
4
|
export type DaemonToolContext = LspRequestContext;
|
|
15
5
|
export interface CallToolOptions {
|
|
16
6
|
context: DaemonToolContext;
|
|
@@ -3,6 +3,8 @@ import { homedir } from "node:os";
|
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import { parseLspRequestContext } from "@oh-my-opencode/lsp-core/request-context";
|
|
5
5
|
import { isPlainRecord } from "@oh-my-opencode/mcp-stdio-core/record";
|
|
6
|
+
import { daemonFailureResult } from "./daemon-failure-result.js";
|
|
7
|
+
import { DaemonAuthenticationRejectedError, DaemonRequestCancelledError, DaemonRequestError, DaemonRequestTimedOutError, } from "./daemon-request-error.js";
|
|
6
8
|
import { ensureDaemonRunning } from "./ensure-daemon.js";
|
|
7
9
|
import { authEnvelope, isAuthErrorResponse, readAuthToken } from "./ipc-protocol.js";
|
|
8
10
|
import { daemonPaths } from "./paths.js";
|
|
@@ -10,25 +12,6 @@ import { CONTEXT_KEY } from "./request-routing.js";
|
|
|
10
12
|
import { createLineDecoder, encodeJsonLine } from "./socket-jsonrpc.js";
|
|
11
13
|
const DEFAULT_REQUEST_TIMEOUT_MS = 30_000;
|
|
12
14
|
let nextProxyRequestId = 1;
|
|
13
|
-
export class DaemonRequestError extends Error {
|
|
14
|
-
constructor(message, requestWritten) {
|
|
15
|
-
super(message);
|
|
16
|
-
this.name = "DaemonRequestError";
|
|
17
|
-
this.requestWritten = requestWritten;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
export class DaemonAuthenticationRejectedError extends DaemonRequestError {
|
|
21
|
-
constructor() {
|
|
22
|
-
super("daemon authentication failed before dispatch", true);
|
|
23
|
-
this.name = "DaemonAuthenticationRejectedError";
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
export class DaemonRequestCancelledError extends DaemonRequestError {
|
|
27
|
-
constructor(requestWritten) {
|
|
28
|
-
super("daemon request cancelled", requestWritten);
|
|
29
|
-
this.name = "DaemonRequestCancelledError";
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
15
|
export async function callToolViaDaemon(name, args, options) {
|
|
33
16
|
const context = requireContext(options.context);
|
|
34
17
|
const paths = options.paths ?? daemonPaths();
|
|
@@ -59,7 +42,7 @@ export async function callToolViaDaemon(name, args, options) {
|
|
|
59
42
|
break;
|
|
60
43
|
}
|
|
61
44
|
}
|
|
62
|
-
return
|
|
45
|
+
return daemonFailureResult(paths, lastError);
|
|
63
46
|
}
|
|
64
47
|
export function callDiagnosticsViaDaemon(filePath, options) {
|
|
65
48
|
return callToolViaDaemon("diagnostics", { filePath, severity: "error" }, options);
|
|
@@ -106,16 +89,6 @@ function ensureDaemonAvailable(paths, ensure, signal) {
|
|
|
106
89
|
.then(() => finish(() => resolve()), (error) => finish(() => reject(signal.aborted ? new DaemonRequestCancelledError(false) : error)));
|
|
107
90
|
});
|
|
108
91
|
}
|
|
109
|
-
function daemonUnreachableResult(paths, error) {
|
|
110
|
-
const text = [
|
|
111
|
-
`LSP daemon unreachable: ${errorText(error)}.`,
|
|
112
|
-
"The MCP server is a thin proxy and never runs language servers in-process.",
|
|
113
|
-
`Socket: ${paths.socket}`,
|
|
114
|
-
`Logs: ${paths.log}`,
|
|
115
|
-
"The daemon is auto-started on demand and will be retried on the next request.",
|
|
116
|
-
].join("\n");
|
|
117
|
-
return { content: [{ type: "text", text }], isError: true };
|
|
118
|
-
}
|
|
119
92
|
function sendToolCall(paths, token, name, args, options) {
|
|
120
93
|
return new Promise((resolve, reject) => {
|
|
121
94
|
const socket = connect(paths.socket);
|
|
@@ -155,7 +128,7 @@ function sendToolCall(paths, token, name, args, options) {
|
|
|
155
128
|
};
|
|
156
129
|
const timer = setTimeout(() => {
|
|
157
130
|
sendCancel();
|
|
158
|
-
finish(() => reject(new
|
|
131
|
+
finish(() => reject(new DaemonRequestTimedOutError(requestWritten, options.timeoutMs)));
|
|
159
132
|
}, options.timeoutMs);
|
|
160
133
|
timer.unref();
|
|
161
134
|
if (options.signal?.aborted) {
|
|
@@ -214,6 +187,3 @@ function allocateProxyRequestId() {
|
|
|
214
187
|
function isRetryableTool(name) {
|
|
215
188
|
return name !== "rename" && name !== "lsp_rename";
|
|
216
189
|
}
|
|
217
|
-
function errorText(error) {
|
|
218
|
-
return error instanceof Error ? error.message : String(error);
|
|
219
|
-
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { DaemonRequestCancelledError, DaemonRequestTimedOutError } from "./daemon-request-error.js";
|
|
2
|
+
export function daemonFailureResult(paths, error) {
|
|
3
|
+
if (error instanceof DaemonRequestCancelledError)
|
|
4
|
+
return daemonCancelledResult(paths);
|
|
5
|
+
if (error instanceof DaemonRequestTimedOutError)
|
|
6
|
+
return daemonTimedOutResult(paths, error.timeoutMs);
|
|
7
|
+
return daemonUnreachableResult(paths, error);
|
|
8
|
+
}
|
|
9
|
+
function daemonCancelledResult(paths) {
|
|
10
|
+
const text = [
|
|
11
|
+
"LSP daemon request cancelled: the caller aborted this request (for example, the turn was interrupted).",
|
|
12
|
+
"The daemon stays available; no LSP work was applied. Retry when you are ready.",
|
|
13
|
+
`Socket: ${paths.socket}`,
|
|
14
|
+
].join("\n");
|
|
15
|
+
return { content: [{ type: "text", text }], isError: true };
|
|
16
|
+
}
|
|
17
|
+
function daemonTimedOutResult(paths, timeoutMs) {
|
|
18
|
+
const text = [
|
|
19
|
+
`LSP daemon request timed out after ${timeoutMs}ms: the daemon did not respond in time.`,
|
|
20
|
+
"The daemon stays available but may be busy. Retry when you are ready.",
|
|
21
|
+
`Socket: ${paths.socket}`,
|
|
22
|
+
`Logs: ${paths.log}`,
|
|
23
|
+
].join("\n");
|
|
24
|
+
return { content: [{ type: "text", text }], isError: true };
|
|
25
|
+
}
|
|
26
|
+
function daemonUnreachableResult(paths, error) {
|
|
27
|
+
const text = [
|
|
28
|
+
`LSP daemon unreachable: ${errorText(error)}.`,
|
|
29
|
+
"The MCP server is a thin proxy and never runs language servers in-process.",
|
|
30
|
+
`Socket: ${paths.socket}`,
|
|
31
|
+
`Logs: ${paths.log}`,
|
|
32
|
+
"The daemon is auto-started on demand and will be retried on the next request.",
|
|
33
|
+
].join("\n");
|
|
34
|
+
return { content: [{ type: "text", text }], isError: true };
|
|
35
|
+
}
|
|
36
|
+
function errorText(error) {
|
|
37
|
+
return error instanceof Error ? error.message : String(error);
|
|
38
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare class DaemonRequestError extends Error {
|
|
2
|
+
readonly requestWritten: boolean;
|
|
3
|
+
constructor(message: string, requestWritten: boolean);
|
|
4
|
+
}
|
|
5
|
+
export declare class DaemonAuthenticationRejectedError extends DaemonRequestError {
|
|
6
|
+
constructor();
|
|
7
|
+
}
|
|
8
|
+
export declare class DaemonRequestCancelledError extends DaemonRequestError {
|
|
9
|
+
constructor(requestWritten: boolean);
|
|
10
|
+
}
|
|
11
|
+
export declare class DaemonRequestTimedOutError extends DaemonRequestError {
|
|
12
|
+
readonly timeoutMs: number;
|
|
13
|
+
constructor(requestWritten: boolean, timeoutMs: number);
|
|
14
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export class DaemonRequestError extends Error {
|
|
2
|
+
constructor(message, requestWritten) {
|
|
3
|
+
super(message);
|
|
4
|
+
this.name = "DaemonRequestError";
|
|
5
|
+
this.requestWritten = requestWritten;
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
export class DaemonAuthenticationRejectedError extends DaemonRequestError {
|
|
9
|
+
constructor() {
|
|
10
|
+
super("daemon authentication failed before dispatch", true);
|
|
11
|
+
this.name = "DaemonAuthenticationRejectedError";
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export class DaemonRequestCancelledError extends DaemonRequestError {
|
|
15
|
+
constructor(requestWritten) {
|
|
16
|
+
super("daemon request cancelled", requestWritten);
|
|
17
|
+
this.name = "DaemonRequestCancelledError";
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export class DaemonRequestTimedOutError extends DaemonRequestError {
|
|
21
|
+
constructor(requestWritten, timeoutMs) {
|
|
22
|
+
super("daemon request timed out", requestWritten);
|
|
23
|
+
this.name = "DaemonRequestTimedOutError";
|
|
24
|
+
this.timeoutMs = timeoutMs;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { chmodSync } from "node:fs";
|
|
2
2
|
import { createServer } from "node:net";
|
|
3
3
|
import { disposeDefaultLspManager, getLspManager } from "@oh-my-opencode/lsp-core/lsp/manager";
|
|
4
|
-
import { setPrivateFileMode } from "./ipc-protocol.js";
|
|
5
4
|
import { pingDaemon } from "./ensure-daemon.js";
|
|
5
|
+
import { setPrivateFileMode } from "./ipc-protocol.js";
|
|
6
6
|
import { acquireStartupLease, DaemonStartupDeferredError, endpointIdentity, removeDaemonMetadataForOwner, writeDaemonOwner, } from "./ownership.js";
|
|
7
7
|
import { handleDaemonMessage } from "./request-routing.js";
|
|
8
8
|
import { createLineDecoder, encodeJsonLine } from "./socket-jsonrpc.js";
|
|
9
|
+
import { reapStaleDaemonVersions } from "./version-reap.js";
|
|
9
10
|
export { DaemonAlreadyRunningError, DaemonStartupDeferredError } from "./ownership.js";
|
|
10
11
|
const DEFAULT_IDLE_SHUTDOWN_MS = 30 * 60_000;
|
|
11
12
|
const DEFAULT_IDLE_CHECK_INTERVAL_MS = 60_000;
|
|
@@ -53,6 +54,9 @@ export async function startDaemonServer(paths, options = {}) {
|
|
|
53
54
|
throw error;
|
|
54
55
|
}
|
|
55
56
|
lease.lock.release();
|
|
57
|
+
// Best-effort cross-version reap: the daemon now owns its version, so older
|
|
58
|
+
// sibling versions may be reaped. Never block or crash startup on failure.
|
|
59
|
+
void reapStaleDaemonVersions(paths).catch((error) => logServerError(error));
|
|
56
60
|
let closed = false;
|
|
57
61
|
const close = async () => {
|
|
58
62
|
if (closed)
|