oh-my-opencode 4.19.0 → 4.19.2
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 +6 -6
- package/README.ru.md +6 -6
- package/README.zh-cn.md +6 -6
- package/dist/agents/atlas/agent.d.ts +5 -3
- package/dist/agents/explore.d.ts +4 -2
- package/dist/agents/gpt-prompt-identity.d.ts +3 -0
- package/dist/agents/hephaestus/agent.d.ts +4 -2
- package/dist/agents/librarian.d.ts +4 -2
- package/dist/agents/metis.d.ts +4 -2
- package/dist/agents/momus.d.ts +3 -2
- package/dist/agents/multimodal-looker.d.ts +4 -2
- package/dist/agents/oracle.d.ts +4 -2
- package/dist/agents/sisyphus/claude-opus-5.d.ts +33 -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 +2 -0
- package/dist/agents/sisyphus-agent-factory.d.ts +5 -2
- package/dist/agents/sisyphus-junior/agent.d.ts +4 -1
- package/dist/agents/sisyphus-junior/gpt-5-5.d.ts +2 -2
- package/dist/agents/types.d.ts +2 -2
- package/dist/cli/index.js +23577 -19269
- package/dist/cli-node/index.js +23577 -19269
- package/dist/config/schema/agent-names.d.ts +26 -26
- package/dist/config/schema/agent-overrides.d.ts +400 -400
- package/dist/config/schema/browser-automation.d.ts +2 -2
- package/dist/config/schema/categories.d.ts +36 -36
- package/dist/config/schema/codegraph.d.ts +2 -0
- package/dist/config/schema/commands.d.ts +2 -2
- package/dist/config/schema/dynamic-context-pruning.d.ts +1 -1
- package/dist/config/schema/experimental.d.ts +1 -1
- package/dist/config/schema/fallback-models.d.ts +25 -25
- package/dist/config/schema/hooks.d.ts +43 -43
- package/dist/config/schema/internal/permission.d.ts +9 -9
- package/dist/config/schema/keyword-detector.d.ts +6 -6
- package/dist/config/schema/oh-my-opencode-config.d.ts +404 -402
- package/dist/config/schema/tmux.d.ts +6 -6
- package/dist/create-hooks.d.ts +35 -35
- package/dist/features/background-agent/spawner/tmux-callback-invoker.d.ts +11 -0
- package/dist/features/builtin-commands/templates/start-work.d.ts +1 -1
- package/dist/features/claude-tasks/types.d.ts +4 -4
- package/dist/features/team-mode/team-runtime/shutdown-helpers.d.ts +1 -1
- package/dist/features/team-mode/team-runtime/shutdown-test-fixtures.d.ts +4 -4
- package/dist/features/team-mode/tools/lifecycle-test-fixture.d.ts +42 -42
- package/dist/features/tmux-subagent/environment-eligibility.d.ts +2 -0
- package/dist/features/tmux-subagent/index.d.ts +1 -0
- package/dist/features/tmux-subagent/tracked-session-state.d.ts +1 -0
- package/dist/features/tui-sidebar/snapshot-schema.d.ts +6 -6
- package/dist/help/schema/acp.d.ts +3 -3
- package/dist/help/schema/doctor.d.ts +4 -4
- package/dist/help/schema/status.d.ts +3 -3
- package/dist/hooks/codegraph-bootstrap/hook.d.ts +3 -2
- package/dist/hooks/goal/types.d.ts +5 -5
- package/dist/hooks/non-interactive-env/constants.d.ts +4 -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/hooks/start-work/parse-user-request.d.ts +2 -0
- package/dist/hooks/start-work/worktree-block.d.ts +5 -0
- package/dist/index.js +27370 -21301
- package/dist/mcp/types.d.ts +3 -3
- package/dist/oh-my-opencode.schema.json +11 -0
- package/dist/plugin/chat-message/loop-commands.d.ts +1 -0
- package/dist/plugin/command-execute-before.d.ts +3 -3
- package/dist/plugin/hooks/create-core-hooks.d.ts +25 -25
- package/dist/shared/omo-process-sweep.d.ts +18 -0
- package/dist/shared/tmux/tmux-utils/environment.d.ts +1 -1
- package/dist/shared/tmux/tmux-utils.d.ts +1 -1
- package/dist/shared/typescript-native-source-parser.d.ts +7 -0
- package/dist/skills/coding-agent-sessions/SKILL.md +5 -2
- package/dist/skills/coding-agent-sessions/references/all-platforms.md +3 -1
- package/dist/skills/coding-agent-sessions/references/senpi.md +15 -5
- package/dist/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +46 -0
- package/dist/skills/coding-agent-sessions/scripts/agent_sessions/scanners.py +19 -10
- package/dist/skills/debugging/SKILL.md +2 -1
- package/dist/skills/debugging/references/methodology/03-flaky-triage.md +47 -0
- package/dist/skills/programming/SKILL.md +11 -1
- package/dist/skills/programming/references/logging.md +6 -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 +75 -11
- package/dist/skills/start-work/SKILL.md +12 -2
- package/dist/skills/ulw-plan/SKILL.md +21 -2
- package/dist/skills/ulw-plan/references/full-workflow.md +12 -1
- package/dist/skills/ulw-plan/references/intent-clear.md +1 -1
- package/dist/testing/create-plugin-module.d.ts +1 -0
- package/dist/tools/task/types.d.ts +10 -10
- package/dist/tui.js +23442 -19182
- 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 +62 -2
- 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 +72 -12
- 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/dist/cli.js +779 -385
- package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +302 -173
- 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 +23 -42
- 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 +17 -9
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker.ts +18 -25
- 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 +5 -0
- package/packages/omo-codex/plugin/components/codegraph/test/hook-store-upgrade.test.ts +176 -0
- package/packages/omo-codex/plugin/components/codegraph/test/hook.test.ts +6 -1
- 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/provisioned-node-guard.test.ts +6 -0
- 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 +2 -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 +42 -0
- package/packages/omo-codex/plugin/components/codegraph/test/serve.test.ts +122 -10
- 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 +101 -64
- 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 +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/directive.md +1 -1
- 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/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/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/plan.toml +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/directive.md +12 -7
- 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/ultrawork/SKILL.md +12 -7
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +21 -2
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +12 -1
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-clear.md +1 -1
- 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/directive.md +12 -7
- 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/SKILL.md +2 -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/shared/test/config-loader.test.ts +44 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/SKILL.md +5 -2
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/all-platforms.md +3 -1
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/senpi.md +15 -5
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +46 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/scanners.py +19 -10
- package/packages/omo-codex/plugin/skills/debugging/SKILL.md +2 -1
- package/packages/omo-codex/plugin/skills/debugging/references/methodology/03-flaky-triage.md +47 -0
- package/packages/omo-codex/plugin/skills/programming/SKILL.md +11 -1
- package/packages/omo-codex/plugin/skills/programming/references/logging.md +6 -1
- package/packages/omo-codex/plugin/skills/programming/scripts/typescript/check-no-excuse-rules.ts +75 -11
- package/packages/omo-codex/plugin/skills/start-work/SKILL.md +12 -2
- package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +12 -7
- package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +2 -1
- package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +8 -6
- package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +21 -2
- package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +12 -1
- package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-clear.md +1 -1
- package/packages/omo-codex/plugin/test/aggregate-agents.test.mjs +9 -9
- 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/sync-skills-orchestration.test.mjs +22 -0
- package/packages/omo-codex/scripts/install-dist/install-local.mjs +49 -5
- package/packages/omo-codex/scripts/install-marketplace-cache.test.mjs +4 -1
- package/packages/shared-skills/skills/coding-agent-sessions/SKILL.md +5 -2
- package/packages/shared-skills/skills/coding-agent-sessions/references/all-platforms.md +3 -1
- package/packages/shared-skills/skills/coding-agent-sessions/references/senpi.md +15 -5
- package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +46 -0
- package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/scanners.py +19 -10
- package/packages/shared-skills/skills/debugging/SKILL.md +2 -1
- package/packages/shared-skills/skills/debugging/references/methodology/03-flaky-triage.md +47 -0
- package/packages/shared-skills/skills/programming/SKILL.md +11 -1
- package/packages/shared-skills/skills/programming/references/logging.md +6 -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 +75 -11
- package/packages/shared-skills/skills/start-work/SKILL.md +12 -2
- package/packages/shared-skills/skills/ulw-plan/SKILL.md +21 -2
- package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +12 -1
- package/packages/shared-skills/skills/ulw-plan/references/intent-clear.md +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sisyphuslabs/codex-codegraph",
|
|
3
|
-
"version": "4.19.
|
|
3
|
+
"version": "4.19.2",
|
|
4
4
|
"description": "Codex plugin MCP wrapper for CodeGraph.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"private": true,
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"typescript": "^6.0.3"
|
|
26
26
|
},
|
|
27
27
|
"optionalDependencies": {
|
|
28
|
-
"@colbymchenry/codegraph": "1.
|
|
28
|
+
"@colbymchenry/codegraph": "1.4.1"
|
|
29
29
|
},
|
|
30
30
|
"engines": {
|
|
31
31
|
"node": ">=20.0.0"
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Readable } from "node:stream";
|
|
2
2
|
|
|
3
3
|
import type { CodexOmoConfig as SharedCodexOmoConfig } from "../../../shared/src/config-loader.ts";
|
|
4
|
+
import type { CODEGRAPH_PINNED_VERSION } from "../../../../../utils/src/codegraph/manifest.ts";
|
|
4
5
|
import type { SweepCodegraphZombiesOptions } from "../../../../../utils/src/codegraph/process-sweep.ts";
|
|
5
6
|
import type { CodegraphProvisionResult as SharedCodegraphProvisionResult } from "../../../../../utils/src/codegraph/provision.ts";
|
|
6
7
|
import type {
|
|
@@ -58,7 +59,7 @@ export interface CodegraphSessionStartOutcome {
|
|
|
58
59
|
|
|
59
60
|
export interface CodegraphSessionStartDeps {
|
|
60
61
|
readonly ensureGitignored: (projectRoot: string) => boolean;
|
|
61
|
-
readonly ensureProvisioned: (options: { readonly installDir?: string; readonly lockDir: string; readonly version:
|
|
62
|
+
readonly ensureProvisioned: (options: { readonly installDir?: string; readonly lockDir: string; readonly version: typeof CODEGRAPH_PINNED_VERSION }) => Promise<CodegraphProvisionResult>;
|
|
62
63
|
readonly prepareWorkspace: (projectRoot: string, options: { readonly homeDir: string }) => CodegraphWorkspacePreparation;
|
|
63
64
|
readonly resolveCommand: (options?: ResolveCodegraphCommandOptions) => CodegraphCommandResolution;
|
|
64
65
|
readonly runCommand: (
|
|
@@ -76,6 +77,7 @@ export interface SessionStartHookOptions {
|
|
|
76
77
|
readonly env?: Record<string, string | undefined>;
|
|
77
78
|
readonly spawnWorker?: (invocation: WorkerSpawnInvocation) => void;
|
|
78
79
|
readonly statusProbe?: (options: {
|
|
80
|
+
readonly daemon: boolean;
|
|
79
81
|
readonly env: Record<string, string | undefined>;
|
|
80
82
|
readonly homeDir: string;
|
|
81
83
|
readonly projectRoot: string;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
2
|
import { homedir } from "node:os";
|
|
3
|
-
import { join } from "node:path";
|
|
4
3
|
import {
|
|
5
4
|
cwd as processCwd,
|
|
6
5
|
env as processEnv,
|
|
@@ -13,7 +12,9 @@ import { fileURLToPath } from "node:url";
|
|
|
13
12
|
|
|
14
13
|
import { buildCodegraphChildEnv, buildCodegraphEnv } from "../../../../../utils/src/codegraph/env.ts";
|
|
15
14
|
import { buildCodegraphInitGuidanceForToolResult } from "../../../../../utils/src/codegraph/guidance.ts";
|
|
15
|
+
import { resolvePinnedCodegraphBin } from "../../../../../utils/src/codegraph/managed-runtime.ts";
|
|
16
16
|
import { resolveCodegraphCommand } from "../../../../../utils/src/codegraph/resolve.ts";
|
|
17
|
+
import { runProcessWithTreeTimeout } from "../../../../../utils/src/process-tree.ts";
|
|
17
18
|
import { shouldExcludeCodegraphProject } from "../../../../../utils/src/codegraph/workspace.ts";
|
|
18
19
|
import { getCodexOmoConfig } from "../../../shared/src/config-loader.ts";
|
|
19
20
|
import { pruneCodegraphProjectStoresBestEffort } from "./cache-gc.js";
|
|
@@ -66,13 +67,6 @@ export async function executeCodegraphSessionStartHook(options: SessionStartHook
|
|
|
66
67
|
const projectRoot = resolveProjectRoot(input, options.cwd ?? processCwd());
|
|
67
68
|
const homeDir = resolveHomeDir(env);
|
|
68
69
|
const config = options.config ?? getCodexOmoConfig({ cwd: projectRoot, env, homeDir });
|
|
69
|
-
pruneCodegraphProjectStoresBestEffort(homeDir, { debugLog: writeDebugLog });
|
|
70
|
-
await sweepCodegraphZombiesBestEffort({
|
|
71
|
-
env,
|
|
72
|
-
homeDir,
|
|
73
|
-
...(config.trustedCodegraphInstallDir === undefined ? {} : { trustedCodegraphInstallDir: config.trustedCodegraphInstallDir }),
|
|
74
|
-
log: writeDebugLog,
|
|
75
|
-
}, options.sweepZombies);
|
|
76
70
|
|
|
77
71
|
if (config.codegraph?.enabled === false) {
|
|
78
72
|
return { action: "skipped-disabled", exitCode: 0 };
|
|
@@ -86,7 +80,16 @@ export async function executeCodegraphSessionStartHook(options: SessionStartHook
|
|
|
86
80
|
return { action: "skipped-excluded", exitCode: 0 };
|
|
87
81
|
}
|
|
88
82
|
|
|
83
|
+
pruneCodegraphProjectStoresBestEffort(homeDir, { debugLog: writeDebugLog });
|
|
84
|
+
await sweepCodegraphZombiesBestEffort({
|
|
85
|
+
env,
|
|
86
|
+
homeDir,
|
|
87
|
+
...(config.trustedCodegraphInstallDir === undefined ? {} : { trustedCodegraphInstallDir: config.trustedCodegraphInstallDir }),
|
|
88
|
+
log: writeDebugLog,
|
|
89
|
+
}, options.sweepZombies);
|
|
90
|
+
|
|
89
91
|
const isInitialized = await (options.statusProbe ?? isCodegraphProjectInitialized)({
|
|
92
|
+
daemon: config.codegraph?.daemon !== false,
|
|
90
93
|
env,
|
|
91
94
|
homeDir,
|
|
92
95
|
projectRoot,
|
|
@@ -110,6 +113,7 @@ export async function executeCodegraphSessionStartHook(options: SessionStartHook
|
|
|
110
113
|
}
|
|
111
114
|
|
|
112
115
|
async function isCodegraphProjectInitialized(options: {
|
|
116
|
+
readonly daemon: boolean;
|
|
113
117
|
readonly env: Record<string, string | undefined>;
|
|
114
118
|
readonly homeDir: string;
|
|
115
119
|
readonly projectRoot: string;
|
|
@@ -124,7 +128,7 @@ async function isCodegraphProjectInitialized(options: {
|
|
|
124
128
|
|
|
125
129
|
const invocation = resolveCodegraphCommandInvocation(resolved.command, [...resolved.argsPrefix, "status", "--json"]);
|
|
126
130
|
const codegraphEnv = {
|
|
127
|
-
...buildCodegraphEnv({ homeDir: options.homeDir }),
|
|
131
|
+
...buildCodegraphEnv({ daemon: options.daemon, homeDir: options.homeDir }),
|
|
128
132
|
...(options.trustedCodegraphInstallDir === undefined ? {} : { CODEGRAPH_INSTALL_DIR: options.trustedCodegraphInstallDir }),
|
|
129
133
|
};
|
|
130
134
|
const status = await runStatusProbe(
|
|
@@ -143,27 +147,14 @@ function runStatusProbe(
|
|
|
143
147
|
args: readonly string[],
|
|
144
148
|
env: Record<string, string>,
|
|
145
149
|
): Promise<{ readonly exitCode: number; readonly stdout: string; readonly timedOut: boolean }> {
|
|
146
|
-
return
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
maxBuffer: 1024 * 1024,
|
|
155
|
-
timeout: STATUS_PROBE_TIMEOUT_MS,
|
|
156
|
-
windowsHide: true,
|
|
157
|
-
},
|
|
158
|
-
(error, stdout) => {
|
|
159
|
-
if (error === null) {
|
|
160
|
-
resolveProbe({ exitCode: 0, stdout: toOutputText(stdout), timedOut: false });
|
|
161
|
-
return;
|
|
162
|
-
}
|
|
163
|
-
resolveProbe({ exitCode: resolveExitCode(error), stdout: toOutputText(stdout), timedOut: error.killed === true });
|
|
164
|
-
},
|
|
165
|
-
);
|
|
166
|
-
});
|
|
150
|
+
return runProcessWithTreeTimeout({
|
|
151
|
+
args,
|
|
152
|
+
command,
|
|
153
|
+
cwd: projectRoot,
|
|
154
|
+
env,
|
|
155
|
+
maxBuffer: 1024 * 1024,
|
|
156
|
+
timeoutMs: STATUS_PROBE_TIMEOUT_MS,
|
|
157
|
+
}).then(({ exitCode, stdout, timedOut }) => ({ exitCode, stdout, timedOut }));
|
|
167
158
|
}
|
|
168
159
|
|
|
169
160
|
function codegraphStatusSaysInitialized(stdout: string): boolean {
|
|
@@ -178,8 +169,7 @@ function codegraphStatusSaysInitialized(stdout: string): boolean {
|
|
|
178
169
|
}
|
|
179
170
|
|
|
180
171
|
function provisionedBinFromInstallDir(installDir: string | undefined): string | null {
|
|
181
|
-
|
|
182
|
-
return join(installDir, "bin", process.platform === "win32" ? "codegraph.cmd" : "codegraph");
|
|
172
|
+
return resolvePinnedCodegraphBin(installDir);
|
|
183
173
|
}
|
|
184
174
|
|
|
185
175
|
export async function executeCodegraphPostToolUseHook(options: PostToolUseHookOptions = {}): Promise<PostToolUseHookResult> {
|
|
@@ -231,15 +221,6 @@ function resolveHomeDir(env: Record<string, string | undefined>): string {
|
|
|
231
221
|
return env["HOME"] ?? env["USERPROFILE"] ?? homedir();
|
|
232
222
|
}
|
|
233
223
|
|
|
234
|
-
function resolveExitCode(error: Error): number {
|
|
235
|
-
if ("code" in error && typeof error.code === "number") return error.code;
|
|
236
|
-
return 1;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
function toOutputText(value: string | Buffer): string {
|
|
240
|
-
return Buffer.isBuffer(value) ? value.toString("utf8") : value;
|
|
241
|
-
}
|
|
242
|
-
|
|
243
224
|
function resolveProjectRoot(input: unknown, fallback: string): string {
|
|
244
225
|
if (!isRecord(input)) return fallback;
|
|
245
226
|
const cwd = input["cwd"];
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { spawn } from "node:child_process";
|
|
1
|
+
import { spawn, type ChildProcess } from "node:child_process";
|
|
2
2
|
import type { Readable, Writable } from "node:stream";
|
|
3
3
|
|
|
4
4
|
import {
|
|
5
|
+
createParentWatchdog,
|
|
5
6
|
errorResponse,
|
|
6
7
|
isPlainRecord,
|
|
7
8
|
jsonRpcId,
|
|
@@ -35,6 +36,8 @@ const CODEGRAPH_NODE_INCLUDE_CODE_DESCRIPTION =
|
|
|
35
36
|
const CODEGRAPH_CONTAINER_OUTLINE_GUIDANCE =
|
|
36
37
|
"Container symbols intentionally return structural outlines with members. For source, request a specific member symbol or call codegraph_node in file mode with symbolsOnly=false plus offset/limit around the symbol location.";
|
|
37
38
|
|
|
39
|
+
const SIGKILL_ESCALATION_MS = 2_000;
|
|
40
|
+
|
|
38
41
|
export async function runBridgedCodegraphProcess(
|
|
39
42
|
command: string,
|
|
40
43
|
args: readonly string[],
|
|
@@ -63,22 +66,45 @@ export async function runBridgedCodegraphProcess(
|
|
|
63
66
|
resolveExit(signal === null ? 0 : 1);
|
|
64
67
|
});
|
|
65
68
|
});
|
|
66
|
-
const
|
|
67
|
-
|
|
69
|
+
const destroyChildPipes = (): void => {
|
|
70
|
+
childInput.destroy();
|
|
71
|
+
childOutput.destroy();
|
|
72
|
+
};
|
|
73
|
+
void childExit.then(destroyChildPipes, destroyChildPipes);
|
|
74
|
+
// Parent-liveness watchdog: when the parent dies while holding our stdio
|
|
75
|
+
// open, the client stream never sees EOF, so the only settle path is to
|
|
76
|
+
// drop the client input, close the child pipes, and terminate the child.
|
|
77
|
+
// The bridge then resolves through the normal child-exit path, and the
|
|
78
|
+
// destroyed input releases its read handle so the process can actually
|
|
79
|
+
// exit (same teardown pattern as runJsonRpcStdioServer's own watchdog).
|
|
80
|
+
// In daemon mode the child is the upstream lightweight proxy, so killing
|
|
81
|
+
// it on parent death is correct; the detached daemon is a separate process
|
|
82
|
+
// and is never touched.
|
|
83
|
+
let parentWatchdogFired = false;
|
|
84
|
+
const parentWatchdog = createParentWatchdog(options.parentWatchdog, () => {
|
|
85
|
+
parentWatchdogFired = true;
|
|
86
|
+
options.input.destroy();
|
|
87
|
+
destroyChildPipes();
|
|
88
|
+
terminateCodegraphChild(child);
|
|
68
89
|
});
|
|
90
|
+
const clientForwardingDone = forwardClientToCodegraph(
|
|
91
|
+
options.input,
|
|
92
|
+
childInput,
|
|
93
|
+
pendingResponses,
|
|
94
|
+
(mode) => {
|
|
95
|
+
defaultResponseMode = mode;
|
|
96
|
+
},
|
|
97
|
+
() => parentWatchdogFired,
|
|
98
|
+
);
|
|
69
99
|
const responseForwardingDone = forwardCodegraphToClient(
|
|
70
100
|
childOutput,
|
|
71
101
|
options.output,
|
|
72
102
|
pendingResponses,
|
|
73
103
|
() => defaultResponseMode,
|
|
104
|
+
() => parentWatchdogFired,
|
|
74
105
|
);
|
|
75
106
|
const bridgeDone = Promise.all([clientForwardingDone, responseForwardingDone]);
|
|
76
107
|
const childAndResponsesDone = Promise.all([childExit, responseForwardingDone]).then(([exitCode]) => exitCode);
|
|
77
|
-
const destroyChildPipes = (): void => {
|
|
78
|
-
childInput.destroy();
|
|
79
|
-
childOutput.destroy();
|
|
80
|
-
};
|
|
81
|
-
void childExit.then(destroyChildPipes, destroyChildPipes);
|
|
82
108
|
try {
|
|
83
109
|
return await Promise.race([childAndResponsesDone, bridgeDone.then(() => childExit)]);
|
|
84
110
|
} catch (error) {
|
|
@@ -86,32 +112,64 @@ export async function runBridgedCodegraphProcess(
|
|
|
86
112
|
if (child.exitCode === null && child.signalCode === null) child.kill("SIGKILL");
|
|
87
113
|
await childExit.catch(() => undefined);
|
|
88
114
|
throw error;
|
|
115
|
+
} finally {
|
|
116
|
+
parentWatchdog.clear();
|
|
89
117
|
}
|
|
90
118
|
}
|
|
91
119
|
|
|
120
|
+
function terminateCodegraphChild(child: ChildProcess): void {
|
|
121
|
+
if (child.exitCode !== null || child.signalCode !== null) return;
|
|
122
|
+
child.kill("SIGTERM");
|
|
123
|
+
const escalation = setTimeout(() => {
|
|
124
|
+
if (child.exitCode === null && child.signalCode === null) child.kill("SIGKILL");
|
|
125
|
+
}, SIGKILL_ESCALATION_MS);
|
|
126
|
+
escalation.unref();
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Stream errors raised by the watchdog's own teardown (input destroy, child
|
|
130
|
+
// pipe destroy) while a forwarder is parked on that stream.
|
|
131
|
+
function isWatchdogTeardownError(error: unknown): boolean {
|
|
132
|
+
if (!(error instanceof Error) || !("code" in error)) return false;
|
|
133
|
+
return (
|
|
134
|
+
error.code === "ERR_STREAM_PREMATURE_CLOSE" ||
|
|
135
|
+
error.code === "ERR_STREAM_DESTROYED" ||
|
|
136
|
+
error.code === "ERR_STREAM_WRITE_AFTER_END" ||
|
|
137
|
+
error.code === "EPIPE"
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
|
|
92
141
|
async function forwardClientToCodegraph(
|
|
93
142
|
input: Readable,
|
|
94
143
|
childInput: Writable,
|
|
95
144
|
pendingResponses: Map<string, PendingClientResponse>,
|
|
96
145
|
setDefaultResponseMode: (mode: StdioJsonRpcResponseMode) => void,
|
|
146
|
+
tolerateWatchdogClose: () => boolean,
|
|
97
147
|
): Promise<void> {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
148
|
+
try {
|
|
149
|
+
for await (const message of readStdioJsonRpcMessages(input)) {
|
|
150
|
+
if (message.kind === "parse_error") {
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
const responseMode = message.responseMode;
|
|
154
|
+
setDefaultResponseMode(responseMode);
|
|
155
|
+
const key = responseModeKey(message.payload);
|
|
156
|
+
if (key !== null) {
|
|
157
|
+
pendingResponses.set(key, {
|
|
158
|
+
method: jsonRpcMethod(message.payload),
|
|
159
|
+
responseMode,
|
|
160
|
+
toolName: jsonRpcToolName(message.payload),
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
await writeLine(childInput, JSON.stringify(message.payload));
|
|
111
164
|
}
|
|
112
|
-
|
|
165
|
+
childInput.end();
|
|
166
|
+
} catch (error) {
|
|
167
|
+
// The parent watchdog destroys the client input and child pipes while
|
|
168
|
+
// this forwarder is parked on a read or write; that teardown is
|
|
169
|
+
// self-inflicted, so settle quietly and let the child-exit path report
|
|
170
|
+
// the outcome.
|
|
171
|
+
if (!(tolerateWatchdogClose() && isWatchdogTeardownError(error))) throw error;
|
|
113
172
|
}
|
|
114
|
-
childInput.end();
|
|
115
173
|
}
|
|
116
174
|
|
|
117
175
|
async function forwardCodegraphToClient(
|
|
@@ -119,17 +177,25 @@ async function forwardCodegraphToClient(
|
|
|
119
177
|
output: Writable,
|
|
120
178
|
pendingResponses: Map<string, PendingClientResponse>,
|
|
121
179
|
defaultResponseMode: () => StdioJsonRpcResponseMode,
|
|
180
|
+
tolerateWatchdogClose: () => boolean,
|
|
122
181
|
): Promise<void> {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
182
|
+
try {
|
|
183
|
+
for await (const message of readStdioJsonRpcMessages(childOutput)) {
|
|
184
|
+
if (message.kind === "parse_error") {
|
|
185
|
+
await writeStdioJsonRpcResponse(output, errorResponse(null, -32700, "Parse error", message.message), defaultResponseMode());
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
const key = responseModeKey(message.payload);
|
|
189
|
+
const pendingResponse = key === null ? undefined : pendingResponses.get(key);
|
|
190
|
+
const responseMode = pendingResponse?.responseMode ?? defaultResponseMode();
|
|
191
|
+
if (key !== null) pendingResponses.delete(key);
|
|
192
|
+
await writeStdioJsonRpcResponse(output, clarifyCodegraphResponse(message.payload, pendingResponse), responseMode);
|
|
127
193
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
194
|
+
} catch (error) {
|
|
195
|
+
// The parent watchdog destroys the child pipes while this forwarder is
|
|
196
|
+
// parked on a read; that close is self-inflicted, so settle quietly and
|
|
197
|
+
// let the child-exit path report the outcome.
|
|
198
|
+
if (!(tolerateWatchdogClose() && isWatchdogTeardownError(error))) throw error;
|
|
133
199
|
}
|
|
134
200
|
}
|
|
135
201
|
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
runJsonRpcStdioServer,
|
|
8
8
|
successResponse,
|
|
9
9
|
type JsonRpcResponse,
|
|
10
|
+
type ParentWatchdogConfig,
|
|
10
11
|
} from "../../../../../mcp-stdio-core/src/index.ts";
|
|
11
12
|
|
|
12
13
|
export interface UnavailableCodegraphMcpOptions {
|
|
@@ -14,6 +15,9 @@ export interface UnavailableCodegraphMcpOptions {
|
|
|
14
15
|
readonly output: Writable;
|
|
15
16
|
readonly reason: string;
|
|
16
17
|
readonly serverVersion: string;
|
|
18
|
+
// Test seam: production callers leave this unset so the watchdog uses its
|
|
19
|
+
// defaults (parentPid = process.ppid, 30s poll).
|
|
20
|
+
readonly parentWatchdog?: ParentWatchdogConfig;
|
|
17
21
|
}
|
|
18
22
|
|
|
19
23
|
interface UnavailableCodegraphMcpHandlerOptions {
|
|
@@ -32,6 +36,7 @@ export async function runUnavailableCodegraphMcpServer(
|
|
|
32
36
|
},
|
|
33
37
|
input: options.input,
|
|
34
38
|
output: options.output,
|
|
39
|
+
parentWatchdog: options.parentWatchdog ?? {},
|
|
35
40
|
});
|
|
36
41
|
}
|
|
37
42
|
|
|
@@ -13,10 +13,12 @@ import type { Readable, Writable } from "node:stream";
|
|
|
13
13
|
import { fileURLToPath } from "node:url";
|
|
14
14
|
|
|
15
15
|
import {
|
|
16
|
-
CODEGRAPH_NO_DAEMON_ENV,
|
|
17
16
|
buildCodegraphChildEnv,
|
|
18
17
|
buildCodegraphEnv,
|
|
19
18
|
} from "../../../../../utils/src/codegraph/env.ts";
|
|
19
|
+
import { resolvePinnedCodegraphBin } from "../../../../../utils/src/codegraph/managed-runtime.ts";
|
|
20
|
+
import type { ParentWatchdogConfig } from "../../../../../mcp-stdio-core/src/index.ts";
|
|
21
|
+
import { CODEGRAPH_PINNED_VERSION } from "../../../../../utils/src/codegraph/manifest.ts";
|
|
20
22
|
import {
|
|
21
23
|
buildCodegraphNodeSkipHint,
|
|
22
24
|
evaluateCodegraphNodeSupport,
|
|
@@ -48,6 +50,7 @@ export interface CodegraphServeProcessOptions {
|
|
|
48
50
|
readonly output: Writable;
|
|
49
51
|
readonly stderr: CodegraphServeStderr;
|
|
50
52
|
readonly stdio: ServeStdio;
|
|
53
|
+
readonly parentWatchdog?: ParentWatchdogConfig;
|
|
51
54
|
}
|
|
52
55
|
|
|
53
56
|
export type CodegraphServeProcessRunner = (
|
|
@@ -64,7 +67,7 @@ export interface CodegraphServeStderr {
|
|
|
64
67
|
}
|
|
65
68
|
|
|
66
69
|
export interface RunCodegraphServeOptions {
|
|
67
|
-
readonly buildEnv?: (options: { readonly homeDir: string }) => Record<string, string>;
|
|
70
|
+
readonly buildEnv?: (options: { readonly daemon: boolean; readonly homeDir: string }) => Record<string, string>;
|
|
68
71
|
readonly commandExists?: (filePath: string) => boolean;
|
|
69
72
|
readonly config?: CodexOmoConfig;
|
|
70
73
|
readonly cwd?: string;
|
|
@@ -77,6 +80,10 @@ export interface RunCodegraphServeOptions {
|
|
|
77
80
|
readonly runProcess?: CodegraphServeProcessRunner;
|
|
78
81
|
readonly stderr?: CodegraphServeStderr;
|
|
79
82
|
readonly ensureProvisioned?: CodegraphProvisioner;
|
|
83
|
+
// Test seam: production callers leave this unset so the bridge and the
|
|
84
|
+
// unavailable facade use the watchdog defaults (parentPid = process.ppid,
|
|
85
|
+
// 30s poll).
|
|
86
|
+
readonly parentWatchdog?: ParentWatchdogConfig;
|
|
80
87
|
}
|
|
81
88
|
|
|
82
89
|
const CODEGRAPH_SKIP_HINT =
|
|
@@ -84,7 +91,7 @@ const CODEGRAPH_SKIP_HINT =
|
|
|
84
91
|
const CODEGRAPH_DISABLED_HINT =
|
|
85
92
|
"CodeGraph MCP skipped: disabled by OMO SOT config. Set [codex].codegraph.enabled=true to enable it.\n";
|
|
86
93
|
const CODEGRAPH_EXCLUDED_HINT = "CodeGraph MCP skipped: project excluded by OMO CodeGraph policy.\n";
|
|
87
|
-
const CODEGRAPH_VERSION =
|
|
94
|
+
const CODEGRAPH_VERSION = CODEGRAPH_PINNED_VERSION;
|
|
88
95
|
const PROJECT_CWD_ENV_KEYS = ["OMO_CODEGRAPH_PROJECT_CWD", SESSION_START_CWD_ENV, "PWD"] as const;
|
|
89
96
|
|
|
90
97
|
export async function runCodegraphServe(options: RunCodegraphServeOptions = {}): Promise<number> {
|
|
@@ -136,7 +143,7 @@ export async function runCodegraphServe(options: RunCodegraphServeOptions = {}):
|
|
|
136
143
|
}
|
|
137
144
|
|
|
138
145
|
const runProcess = options.runProcess ?? runBridgedCodegraphProcess;
|
|
139
|
-
const codegraphEnv = codegraphEnvForConfig(trustedInstallDir, homeDir, options.buildEnv);
|
|
146
|
+
const codegraphEnv = codegraphEnvForConfig(trustedInstallDir, homeDir, codegraphConfig.daemon !== false, options.buildEnv);
|
|
140
147
|
const mergedEnv = buildCodegraphChildEnv({ ambientEnv: env, codegraphEnv, runtimeEnv: env });
|
|
141
148
|
return runProcess(resolution.command, [...resolution.argsPrefix, "serve", "--mcp"], {
|
|
142
149
|
cwd: projectCwd,
|
|
@@ -145,6 +152,7 @@ export async function runCodegraphServe(options: RunCodegraphServeOptions = {}):
|
|
|
145
152
|
output: options.stdout ?? processStdout,
|
|
146
153
|
stderr: options.stderr ?? processStderr,
|
|
147
154
|
stdio: "pipe",
|
|
155
|
+
parentWatchdog: options.parentWatchdog ?? {},
|
|
148
156
|
});
|
|
149
157
|
}
|
|
150
158
|
|
|
@@ -155,6 +163,7 @@ async function runUnavailableMcp(reason: string, options: RunCodegraphServeOptio
|
|
|
155
163
|
output: options.stdout ?? processStdout,
|
|
156
164
|
reason,
|
|
157
165
|
serverVersion: CODEGRAPH_VERSION,
|
|
166
|
+
parentWatchdog: options.parentWatchdog ?? {},
|
|
158
167
|
});
|
|
159
168
|
return 0;
|
|
160
169
|
}
|
|
@@ -195,9 +204,10 @@ function looksLikePath(command: string): boolean {
|
|
|
195
204
|
function codegraphEnvForConfig(
|
|
196
205
|
trustedInstallDir: string | undefined,
|
|
197
206
|
homeDir: string,
|
|
198
|
-
|
|
207
|
+
daemon: boolean,
|
|
208
|
+
buildEnv: ((options: { readonly daemon: boolean; readonly homeDir: string }) => Record<string, string>) | undefined,
|
|
199
209
|
): Record<string, string> {
|
|
200
|
-
const env =
|
|
210
|
+
const env = buildEnv?.({ daemon, homeDir }) ?? buildCodegraphEnv({ daemon, homeDir });
|
|
201
211
|
return trustedInstallDir === undefined ? env : { ...env, CODEGRAPH_INSTALL_DIR: trustedInstallDir };
|
|
202
212
|
}
|
|
203
213
|
|
|
@@ -212,9 +222,7 @@ function resolveProjectCwd(env: Record<string, string | undefined>, fallback: st
|
|
|
212
222
|
}
|
|
213
223
|
|
|
214
224
|
function provisionedBinFromInstallDir(installDir: string | undefined): string | null {
|
|
215
|
-
|
|
216
|
-
const candidate = join(installDir, "bin", process.platform === "win32" ? "codegraph.cmd" : "codegraph");
|
|
217
|
-
return existsSync(candidate) ? candidate : null;
|
|
225
|
+
return resolvePinnedCodegraphBin(installDir);
|
|
218
226
|
}
|
|
219
227
|
|
|
220
228
|
export async function runCodegraphServeCli(): Promise<void> {
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { appendFileSync, existsSync, mkdirSync } from "node:fs";
|
|
1
|
+
import { appendFileSync, mkdirSync } from "node:fs";
|
|
3
2
|
import { homedir } from "node:os";
|
|
4
3
|
import { extname, join } from "node:path";
|
|
5
4
|
import { cwd as processCwd, env as processEnv, execPath as processExecPath, stderr as processStderr } from "node:process";
|
|
6
5
|
|
|
7
6
|
import { getCodexOmoConfig } from "../../../shared/src/config-loader.ts";
|
|
8
7
|
import { buildCodegraphChildEnv, buildCodegraphEnv } from "../../../../../utils/src/codegraph/env.ts";
|
|
8
|
+
import { resolvePinnedCodegraphBin } from "../../../../../utils/src/codegraph/managed-runtime.ts";
|
|
9
|
+
import { CODEGRAPH_PINNED_VERSION } from "../../../../../utils/src/codegraph/manifest.ts";
|
|
9
10
|
import { evaluateCodegraphNodeSupport, type CodegraphNodeSupport } from "../../../../../utils/src/codegraph/node-support.ts";
|
|
10
11
|
import { ensureCodegraphProvisioned } from "../../../../../utils/src/codegraph/provision.ts";
|
|
11
12
|
import {
|
|
@@ -14,6 +15,7 @@ import {
|
|
|
14
15
|
type CodegraphCommandResolution,
|
|
15
16
|
} from "../../../../../utils/src/codegraph/resolve.ts";
|
|
16
17
|
import { ensureCodegraphGitignored, prepareCodegraphWorkspace } from "../../../../../utils/src/codegraph/workspace.ts";
|
|
18
|
+
import { runProcessWithTreeTimeout } from "../../../../../utils/src/process-tree.ts";
|
|
17
19
|
import type {
|
|
18
20
|
CodegraphCommandResult,
|
|
19
21
|
CodegraphConfig,
|
|
@@ -25,7 +27,7 @@ import type {
|
|
|
25
27
|
|
|
26
28
|
export const SESSION_START_CWD_ENV = "OMO_CODEGRAPH_SESSION_START_CWD";
|
|
27
29
|
|
|
28
|
-
const CODEGRAPH_VERSION =
|
|
30
|
+
const CODEGRAPH_VERSION = CODEGRAPH_PINNED_VERSION;
|
|
29
31
|
const COMMAND_TIMEOUT_MS = 60_000;
|
|
30
32
|
const WINDOWS_CMD_EXTENSIONS = new Set([".bat", ".cmd"]);
|
|
31
33
|
const WINDOWS_NODE_SCRIPT_EXTENSIONS = new Set([".cjs", ".js", ".mjs"]);
|
|
@@ -127,7 +129,10 @@ async function resolveOrProvisionCommand(
|
|
|
127
129
|
}
|
|
128
130
|
|
|
129
131
|
function codegraphEnvForConfig(config: CodegraphBootstrapConfig, homeDir: string): Record<string, string> {
|
|
130
|
-
|
|
132
|
+
// The detached indexing worker must NEVER engage the upstream daemon, even
|
|
133
|
+
// when the user opted into daemon mode for interactive MCP sessions: a
|
|
134
|
+
// daemon-backed init/sync would outlive and race the worker's lifecycle.
|
|
135
|
+
const env = buildCodegraphEnv({ daemon: false, homeDir });
|
|
131
136
|
return config.trustedCodegraphInstallDir === undefined ? env : { ...env, CODEGRAPH_INSTALL_DIR: config.trustedCodegraphInstallDir };
|
|
132
137
|
}
|
|
133
138
|
|
|
@@ -160,15 +165,14 @@ function jsonSaysInitialized(value: unknown): boolean | undefined {
|
|
|
160
165
|
|
|
161
166
|
async function runCodegraphCommand(projectRoot: string, command: string, args: readonly string[], options: { readonly env: Record<string, string>; readonly timeoutMs: number }): Promise<CodegraphCommandResult> {
|
|
162
167
|
const invocation = resolveCodegraphCommandInvocation(command, args);
|
|
163
|
-
return
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
});
|
|
168
|
+
return runProcessWithTreeTimeout({
|
|
169
|
+
args: invocation.args,
|
|
170
|
+
command: invocation.command,
|
|
171
|
+
cwd: projectRoot,
|
|
172
|
+
env: buildCodegraphChildEnv({ ambientEnv: processEnv, codegraphEnv: options.env }),
|
|
173
|
+
maxBuffer: 1024 * 1024,
|
|
174
|
+
timeoutMs: options.timeoutMs,
|
|
175
|
+
}).then(({ exitCode, stderr, stdout, timedOut }) => ({ exitCode, stderr, stdout, timedOut }));
|
|
172
176
|
}
|
|
173
177
|
|
|
174
178
|
export function resolveCodegraphCommandInvocation(
|
|
@@ -199,18 +203,7 @@ function safeLogOutcome(logOutcome: (outcome: CodegraphSessionStartOutcome) => v
|
|
|
199
203
|
}
|
|
200
204
|
|
|
201
205
|
function provisionedBinFromInstallDir(installDir: string | undefined): string | null {
|
|
202
|
-
|
|
203
|
-
const candidate = join(installDir, "bin", process.platform === "win32" ? "codegraph.cmd" : "codegraph");
|
|
204
|
-
return existsSync(candidate) ? candidate : null;
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
function resolveExitCode(error: Error): number {
|
|
208
|
-
if ("code" in error && typeof error.code === "number") return error.code;
|
|
209
|
-
return 1;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
function toOutputText(value: string | Buffer): string {
|
|
213
|
-
return Buffer.isBuffer(value) ? value.toString("utf8") : value;
|
|
206
|
+
return resolvePinnedCodegraphBin(installDir);
|
|
214
207
|
}
|
|
215
208
|
|
|
216
209
|
function resolveHomeDir(env: Record<string, string | undefined>): string {
|
|
@@ -61,6 +61,7 @@ function writeSweepReport(stdout: HookStdout, result: SweepCodegraphZombiesResul
|
|
|
61
61
|
failed: result.failed,
|
|
62
62
|
killed: result.killed.map(formatProcess),
|
|
63
63
|
ownedRoots: result.ownedRoots,
|
|
64
|
+
spared: result.spared.map(formatProcess),
|
|
64
65
|
stampFile: result.stampFile,
|
|
65
66
|
})}\n`);
|
|
66
67
|
}
|
|
@@ -20,6 +20,7 @@ describe("CodeGraph SessionStart exclusion policy", () => {
|
|
|
20
20
|
// given
|
|
21
21
|
const stdout: string[] = [];
|
|
22
22
|
const spawned: WorkerSpawnInvocation[] = [];
|
|
23
|
+
let sweepCalls = 0;
|
|
23
24
|
const stateRoot = createAllowedWorkspace("codegraph-omo-state");
|
|
24
25
|
const workspace = join(stateRoot, ".omo", "ulw-research", "run", "clones", "repo");
|
|
25
26
|
mkdirSync(workspace, { recursive: true });
|
|
@@ -36,10 +37,14 @@ describe("CodeGraph SessionStart exclusion policy", () => {
|
|
|
36
37
|
statusProbe: () => {
|
|
37
38
|
throw new Error("excluded projects must not probe CodeGraph status");
|
|
38
39
|
},
|
|
40
|
+
sweepZombies: () => {
|
|
41
|
+
sweepCalls += 1;
|
|
42
|
+
},
|
|
39
43
|
});
|
|
40
44
|
|
|
41
45
|
// then
|
|
42
46
|
expect(result).toEqual({ action: "skipped-excluded", exitCode: 0 });
|
|
47
|
+
expect(sweepCalls).toBe(0);
|
|
43
48
|
expect(spawned).toEqual([]);
|
|
44
49
|
expect(stdout.join("")).toBe("");
|
|
45
50
|
} finally {
|