oh-my-opencode 4.13.0 → 4.14.0
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/skills/codex-qa/SKILL.md +15 -0
- package/.agents/skills/codex-qa/references/logging-debug.md +12 -0
- package/.agents/skills/opencode-qa/SKILL.md +17 -0
- package/.agents/skills/opencode-qa/references/tui-tmux.md +17 -0
- package/.agents/skills/work-with-pr/SKILL.md +18 -10
- package/.opencode/skills/work-with-pr/SKILL.md +18 -10
- package/README.md +2 -2
- package/dist/cli/doctor/checks/telemetry.d.ts +2 -0
- package/dist/cli/doctor/framework/constants.d.ts +1 -0
- package/dist/cli/doctor/framework/doctor-target.d.ts +1 -1
- package/dist/cli/index.js +24651 -16452
- package/dist/cli-node/index.js +24651 -16452
- package/dist/config/schema/oh-my-opencode-config.d.ts +1 -0
- package/dist/features/team-mode/test-support/async-test-helpers.d.ts +19 -0
- package/dist/hooks/atlas/final-wave-approval-gate.d.ts +1 -0
- package/dist/hooks/atlas/subagent-completion-reminder.d.ts +30 -0
- package/dist/hooks/atlas/types.d.ts +2 -0
- package/dist/hooks/atlas/verification-reminders.d.ts +3 -0
- package/dist/hooks/team-session-events/team-idle-wake-hint.d.ts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +33232 -19559
- package/dist/mcp/context7.d.ts +9 -8
- package/dist/oh-my-opencode.schema.json +4 -0
- package/dist/shared/posthog.d.ts +17 -10
- package/dist/shared/telemetry-product-identity.d.ts +2 -0
- package/dist/skills/coding-agent-sessions/SKILL.md +128 -0
- package/dist/skills/coding-agent-sessions/agents/openai.yaml +4 -0
- package/dist/skills/coding-agent-sessions/references/all-platforms.md +71 -0
- package/dist/skills/coding-agent-sessions/references/claude.md +32 -0
- package/dist/skills/coding-agent-sessions/references/codex.md +30 -0
- package/dist/skills/coding-agent-sessions/references/opencode.md +43 -0
- package/dist/skills/coding-agent-sessions/references/senpi.md +17 -0
- package/dist/skills/coding-agent-sessions/scripts/agent_sessions/__init__.py +1 -0
- package/dist/skills/coding-agent-sessions/scripts/agent_sessions/claude.py +66 -0
- package/dist/skills/coding-agent-sessions/scripts/agent_sessions/cli.py +283 -0
- package/dist/skills/coding-agent-sessions/scripts/agent_sessions/codex.py +105 -0
- package/dist/skills/coding-agent-sessions/scripts/agent_sessions/file_scanners.py +275 -0
- package/dist/skills/coding-agent-sessions/scripts/agent_sessions/jsonio.py +55 -0
- package/dist/skills/coding-agent-sessions/scripts/agent_sessions/kiro_scanner.py +91 -0
- package/dist/skills/coding-agent-sessions/scripts/agent_sessions/opencode.py +289 -0
- package/dist/skills/coding-agent-sessions/scripts/agent_sessions/scanners.py +92 -0
- package/dist/skills/coding-agent-sessions/scripts/agent_sessions/sqlite_optional_scanners.py +203 -0
- package/dist/skills/coding-agent-sessions/scripts/agent_sessions/sqlite_scanners.py +177 -0
- package/dist/skills/coding-agent-sessions/scripts/agent_sessions/timeparse.py +51 -0
- package/dist/skills/coding-agent-sessions/scripts/agent_sessions/transcript.py +149 -0
- package/dist/skills/coding-agent-sessions/scripts/agent_sessions/types.py +57 -0
- package/dist/skills/coding-agent-sessions/scripts/find-agent-sessions.py +19 -0
- package/dist/skills/frontend/ATTRIBUTION.md +52 -8
- package/dist/skills/frontend/SKILL.md +29 -8
- package/dist/skills/frontend/references/design/README.md +29 -12
- package/dist/skills/frontend/references/design/_INDEX.md +3 -3
- package/dist/skills/frontend/references/design/design-system-architecture.md +22 -19
- package/dist/skills/frontend/references/designpowers/EVIDENCE.md +89 -0
- package/dist/skills/frontend/references/designpowers/README.md +48 -0
- package/dist/skills/frontend/references/designpowers/UPSTREAM.md +80 -0
- package/dist/skills/frontend/references/designpowers/lane-a-direction.md +64 -0
- package/dist/skills/frontend/references/designpowers/lane-b-execution.md +65 -0
- package/dist/skills/frontend/references/designpowers/lane-c-review.md +65 -0
- package/dist/skills/frontend/references/designpowers/lane-d-memory.md +83 -0
- package/dist/skills/frontend/references/designpowers/orchestration.md +80 -0
- package/dist/skills/frontend/references/designpowers/routing.md +79 -0
- package/dist/skills/frontend/references/designpowers/vendor/LICENSE +21 -0
- package/dist/skills/frontend/references/designpowers/vendor/agents/accessibility-reviewer.md +83 -0
- package/dist/skills/frontend/references/designpowers/vendor/agents/content-writer.md +132 -0
- package/dist/skills/frontend/references/designpowers/vendor/agents/design-builder.md +109 -0
- package/dist/skills/frontend/references/designpowers/vendor/agents/design-critic.md +89 -0
- package/dist/skills/frontend/references/designpowers/vendor/agents/design-lead.md +113 -0
- package/dist/skills/frontend/references/designpowers/vendor/agents/design-scout.md +78 -0
- package/dist/skills/frontend/references/designpowers/vendor/agents/design-strategist.md +121 -0
- package/dist/skills/frontend/references/designpowers/vendor/agents/heuristic-evaluator.md +268 -0
- package/dist/skills/frontend/references/designpowers/vendor/agents/inspiration-scout.md +107 -0
- package/dist/skills/frontend/references/designpowers/vendor/agents/motion-designer.md +120 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/accessible-content/SKILL.md +101 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/adaptive-interfaces/SKILL.md +109 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/cognitive-accessibility/SKILL.md +107 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/design-debate/SKILL.md +199 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/design-debt-tracker/SKILL.md +174 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/design-handoff/SKILL.md +125 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/design-md/SKILL.md +106 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/design-retrospective/SKILL.md +266 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/design-review/SKILL.md +123 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/design-system-alignment/SKILL.md +120 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/designpowers-critique/SKILL.md +164 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/heuristic-evaluation/SKILL.md +85 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/inclusive-personas/SKILL.md +98 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/inspiration-scouting/SKILL.md +165 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/interaction-design/SKILL.md +122 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/motion-choreography/SKILL.md +81 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/research-planning/SKILL.md +96 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/responsive-patterns/SKILL.md +77 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/synthetic-user-testing/SKILL.md +192 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/taste-feedback/SKILL.md +165 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/taste-report/SKILL.md +78 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/token-architecture/SKILL.md +75 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/ui-composition/SKILL.md +117 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/usability-testing/SKILL.md +78 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/verification-before-shipping/SKILL.md +125 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/voice-and-tone/SKILL.md +79 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/writing-design-plans/SKILL.md +119 -0
- package/dist/skills/frontend/references/ui-ux-db/scripts/core.py +0 -0
- package/dist/skills/git-master/SKILL.md +4 -0
- package/dist/skills/review-work/SKILL.md +3 -3
- package/dist/skills/start-work/SKILL.md +7 -5
- package/dist/skills/ultraresearch/SKILL.md +4 -252
- package/dist/skills/ulw-plan/SKILL.md +8 -6
- package/dist/skills/ulw-plan/references/full-workflow.md +11 -6
- package/dist/skills/ulw-plan/references/intent-clear.md +3 -3
- package/dist/skills/ulw-plan/references/intent-unclear.md +1 -1
- package/dist/skills/{ultraresearch → ulw-research}/ATTRIBUTION.md +1 -1
- package/dist/skills/ulw-research/SKILL.md +260 -0
- package/dist/skills/visual-qa/SKILL.md +105 -14
- package/dist/skills/visual-qa/scripts/skill-prompt-contract.test.ts +120 -1
- package/dist/testing/create-plugin-module.d.ts +2 -0
- package/dist/tui.js +23917 -16117
- package/docs/reference/github-attachment-upload.md +51 -0
- package/docs/reference/web-terminal-visual-qa.md +81 -0
- package/package.json +20 -14
- package/packages/lsp-core/src/lsp/process.ts +4 -1
- package/packages/lsp-core/src/mcp.ts +1 -0
- package/packages/lsp-daemon/dist/cli.js +5 -1
- package/packages/lsp-daemon/dist/index.js +5 -1
- package/packages/lsp-daemon/dist/proxy.js +1 -0
- package/packages/lsp-tools-mcp/dist/cli.js +5 -1
- package/packages/lsp-tools-mcp/dist/lsp/manager.js +4 -1
- package/packages/lsp-tools-mcp/dist/mcp.js +5 -1
- package/packages/lsp-tools-mcp/dist/tools.js +4 -1
- package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +323 -62
- package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/scripts/bootstrap.ps1 +37 -68
- package/packages/omo-codex/plugin/components/bootstrap/scripts/node-dispatch.ps1 +75 -0
- package/packages/omo-codex/plugin/components/bootstrap/src/cli.ts +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/src/setup.ts +2 -18
- package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +575 -334
- package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +204 -39
- package/packages/omo-codex/plugin/components/codegraph/package.json +2 -2
- package/packages/omo-codex/plugin/components/codegraph/src/hook-types.ts +7 -1
- package/packages/omo-codex/plugin/components/codegraph/src/hook.ts +103 -3
- package/packages/omo-codex/plugin/components/codegraph/src/mcp-bridge.ts +114 -0
- package/packages/omo-codex/plugin/components/codegraph/src/serve-invocation.ts +29 -0
- package/packages/omo-codex/plugin/components/codegraph/src/serve.ts +31 -57
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker.ts +7 -4
- package/packages/omo-codex/plugin/components/codegraph/test/hook.test.ts +43 -9
- package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge.test.ts +146 -0
- package/packages/omo-codex/plugin/components/codegraph/test/serve.test.ts +12 -7
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-flow.test.ts +71 -1
- package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
- package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
- package/packages/omo-codex/plugin/components/lsp/dist/cli.js +4 -1
- package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
- package/packages/omo-codex/plugin/components/rules/dist/cli.js +2 -2
- package/packages/omo-codex/plugin/components/rules/package.json +1 -1
- package/packages/omo-codex/plugin/components/rules/src/sparkshell-awareness.ts +2 -2
- package/packages/omo-codex/plugin/components/rules/test/sparkshell-awareness.test.ts +11 -2
- package/packages/omo-codex/plugin/components/start-work-continuation/directive.md +6 -6
- package/packages/omo-codex/plugin/components/start-work-continuation/package.json +1 -1
- package/packages/omo-codex/plugin/components/start-work-continuation/test/codex-hook.test.ts +23 -0
- package/packages/omo-codex/plugin/components/teammode/dist/cli.js +22 -4
- package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/skills/teammode/SKILL.md +40 -2
- package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team-guide.mjs +32 -5
- package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team.mjs +7 -3
- package/packages/omo-codex/plugin/components/teammode/src/codex-hook.ts +19 -4
- package/packages/omo-codex/plugin/components/teammode/test/thread-title-hook.test.ts +32 -2
- package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/README.md +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/agents/explorer.toml +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/agents/plan.toml +2 -2
- package/packages/omo-codex/plugin/components/ultrawork/directive.md +23 -7
- package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +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 +6 -4
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +11 -6
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-clear.md +3 -3
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-unclear.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 +24 -0
- package/packages/omo-codex/plugin/components/ultrawork/test/package-smoke.test.ts +6 -1
- package/packages/omo-codex/plugin/components/ulw-loop/AGENTS.md +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/README.md +25 -21
- package/packages/omo-codex/plugin/components/ulw-loop/biome.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/directive.md +381 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-steering.js +14 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +145 -14
- package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-hook.d.ts +6 -3
- package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-hook.js +16 -6
- package/packages/omo-codex/plugin/components/ulw-loop/dist/ultrawork-directive.d.ts +5 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/ultrawork-directive.js +104 -0
- package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/package.json +2 -1
- package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +19 -11
- package/packages/omo-codex/plugin/components/ulw-loop/src/cli-steering.ts +14 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/cli.ts +4 -2
- package/packages/omo-codex/plugin/components/ulw-loop/src/codex-hook.ts +28 -6
- package/packages/omo-codex/plugin/components/ulw-loop/src/ultrawork-directive.ts +113 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/cli-entrypoint.test.ts +33 -2
- package/packages/omo-codex/plugin/components/ulw-loop/test/cli-steering-kind-guidance.test.ts +31 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/codex-hook.test.ts +13 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts +36 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/skill-contract.test.ts +12 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/ultrawork-directive.test.ts +64 -0
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +2 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +2 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +2 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +2 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +2 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +2 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +2 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +2 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +2 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +2 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +2 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +2 -1
- package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +2 -1
- package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +2 -1
- package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +2 -1
- package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +2 -1
- package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +2 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +2 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +2 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +2 -1
- package/packages/omo-codex/plugin/package-lock.json +13 -13
- package/packages/omo-codex/plugin/package.json +1 -1
- package/packages/omo-codex/plugin/scripts/auto-update.mjs +9 -5
- package/packages/omo-codex/plugin/scripts/materialize-shared-upstreams.mjs +1 -0
- package/packages/omo-codex/plugin/scripts/migrate-codex-config/context7-placeholder-guard.mjs +131 -0
- package/packages/omo-codex/plugin/scripts/migrate-codex-config/multi-agent-mode-guard.mjs +60 -0
- package/packages/omo-codex/plugin/scripts/migrate-codex-config/multi-agent-v2-guard.mjs +3 -10
- package/packages/omo-codex/plugin/scripts/migrate-codex-config/root-settings.mjs +31 -1
- package/packages/omo-codex/plugin/scripts/migrate-codex-config/subagent-limit-guard.mjs +73 -0
- package/packages/omo-codex/plugin/scripts/migrate-codex-config.mjs +20 -3
- package/packages/omo-codex/plugin/scripts/sync-skills.mjs +30 -8
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/SKILL.md +128 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/agents/openai.yaml +4 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/all-platforms.md +71 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/claude.md +32 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/codex.md +30 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/opencode.md +43 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/senpi.md +17 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/__init__.py +1 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/claude.py +66 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/cli.py +283 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/codex.py +105 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/file_scanners.py +275 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/jsonio.py +55 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/kiro_scanner.py +91 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/opencode.py +289 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/scanners.py +92 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/sqlite_optional_scanners.py +203 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/sqlite_scanners.py +177 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/timeparse.py +51 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/transcript.py +149 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/types.py +57 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/find-agent-sessions.py +19 -0
- package/packages/omo-codex/plugin/skills/frontend/ATTRIBUTION.md +52 -8
- package/packages/omo-codex/plugin/skills/frontend/SKILL.md +29 -8
- package/packages/omo-codex/plugin/skills/frontend/references/design/README.md +29 -12
- package/packages/omo-codex/plugin/skills/frontend/references/design/_INDEX.md +3 -3
- package/packages/omo-codex/plugin/skills/frontend/references/design/design-system-architecture.md +22 -19
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/EVIDENCE.md +89 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/README.md +48 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/UPSTREAM.md +80 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-a-direction.md +64 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-b-execution.md +65 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-c-review.md +65 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-d-memory.md +83 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/orchestration.md +80 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/routing.md +79 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/LICENSE +21 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/agents/accessibility-reviewer.md +83 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/agents/content-writer.md +132 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/agents/design-builder.md +109 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/agents/design-critic.md +89 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/agents/design-lead.md +113 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/agents/design-scout.md +78 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/agents/design-strategist.md +121 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/agents/heuristic-evaluator.md +268 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/agents/inspiration-scout.md +107 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/agents/motion-designer.md +120 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/accessible-content/SKILL.md +101 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/adaptive-interfaces/SKILL.md +109 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/cognitive-accessibility/SKILL.md +107 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/design-debate/SKILL.md +199 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/design-debt-tracker/SKILL.md +174 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/design-handoff/SKILL.md +125 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/design-md/SKILL.md +106 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/design-retrospective/SKILL.md +266 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/design-review/SKILL.md +123 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/design-system-alignment/SKILL.md +120 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/designpowers-critique/SKILL.md +164 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/heuristic-evaluation/SKILL.md +85 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/inclusive-personas/SKILL.md +98 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/inspiration-scouting/SKILL.md +165 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/interaction-design/SKILL.md +122 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/motion-choreography/SKILL.md +81 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/research-planning/SKILL.md +96 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/responsive-patterns/SKILL.md +77 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/synthetic-user-testing/SKILL.md +192 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/taste-feedback/SKILL.md +165 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/taste-report/SKILL.md +78 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/token-architecture/SKILL.md +75 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/ui-composition/SKILL.md +117 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/usability-testing/SKILL.md +78 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/verification-before-shipping/SKILL.md +125 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/voice-and-tone/SKILL.md +79 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/writing-design-plans/SKILL.md +119 -0
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/scripts/core.py +0 -0
- package/packages/omo-codex/plugin/skills/git-master/SKILL.md +4 -0
- package/packages/omo-codex/plugin/skills/init-deep/SKILL.md +4 -0
- package/packages/omo-codex/plugin/skills/refactor/SKILL.md +4 -0
- package/packages/omo-codex/plugin/skills/remove-ai-slops/SKILL.md +4 -0
- package/packages/omo-codex/plugin/skills/review-work/SKILL.md +12 -4
- package/packages/omo-codex/plugin/skills/start-work/SKILL.md +14 -8
- package/packages/omo-codex/plugin/skills/teammode/SKILL.md +40 -2
- package/packages/omo-codex/plugin/skills/teammode/scripts/team-guide.mjs +32 -5
- package/packages/omo-codex/plugin/skills/teammode/scripts/team.mjs +7 -3
- package/packages/omo-codex/plugin/skills/ultraresearch/SKILL.md +4 -250
- package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +19 -11
- package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +6 -4
- package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +11 -6
- package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-clear.md +3 -3
- package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-unclear.md +1 -1
- package/packages/{shared-skills/skills/ultraresearch → omo-codex/plugin/skills/ulw-research}/ATTRIBUTION.md +1 -1
- package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +262 -0
- package/packages/omo-codex/plugin/skills/ulw-research/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +109 -14
- package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +23 -0
- package/packages/omo-codex/plugin/test/aggregate-manifest.test.mjs +1 -0
- package/packages/omo-codex/plugin/test/auto-update-release-notes.test.mjs +1 -0
- package/packages/omo-codex/plugin/test/auto-update-restart-notice.test.mjs +24 -1
- package/packages/omo-codex/plugin/test/bootstrap-binlinks.test.mjs +23 -5
- package/packages/omo-codex/plugin/test/bootstrap-hooks.test.mjs +38 -0
- package/packages/omo-codex/plugin/test/bootstrap-ps-guard.test.mjs +25 -0
- package/packages/omo-codex/plugin/test/bootstrap-setup.test.mjs +1 -7
- package/packages/omo-codex/plugin/test/migrate-codex-config.test.mjs +206 -6
- package/packages/omo-codex/plugin/test/subagent-limit-migration.test.mjs +44 -0
- package/packages/omo-codex/plugin/test/sync-skills-orchestration.test.mjs +50 -1
- package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +10 -7
- package/packages/omo-codex/plugin/test/sync-skills.test.mjs +28 -2
- package/packages/omo-codex/plugin/test/teammode-communication.test.mjs +20 -0
- package/packages/omo-codex/plugin/test/teammode-thread-links.test.mjs +117 -0
- package/packages/omo-codex/plugin/test/teammode-worktree.test.mjs +5 -2
- package/packages/omo-codex/plugin/test/ulw-research-skill-contract.test.mjs +285 -0
- package/packages/omo-codex/scripts/install-bin-links.test.mjs +6 -1
- package/packages/omo-codex/scripts/install-cache-copy.test.mjs +51 -0
- package/packages/omo-codex/scripts/install-config.test.mjs +198 -17
- package/packages/omo-codex/scripts/install-dist/install-local.mjs +701 -282
- package/packages/omo-codex/scripts/install-local-git-bash-preflight.test.mjs +24 -15
- package/packages/omo-codex/scripts/install-local.test.mjs +5 -1
- package/packages/omo-codex/scripts/install-mcp-context7-runtime.test.mjs +84 -0
- package/packages/shared-skills/skills/coding-agent-sessions/SKILL.md +128 -0
- package/packages/shared-skills/skills/coding-agent-sessions/agents/openai.yaml +4 -0
- package/packages/shared-skills/skills/coding-agent-sessions/references/all-platforms.md +71 -0
- package/packages/shared-skills/skills/coding-agent-sessions/references/claude.md +32 -0
- package/packages/shared-skills/skills/coding-agent-sessions/references/codex.md +30 -0
- package/packages/shared-skills/skills/coding-agent-sessions/references/opencode.md +43 -0
- package/packages/shared-skills/skills/coding-agent-sessions/references/senpi.md +17 -0
- package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/__init__.py +1 -0
- package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/claude.py +66 -0
- package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/cli.py +283 -0
- package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/codex.py +105 -0
- package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/file_scanners.py +275 -0
- package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/jsonio.py +55 -0
- package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/kiro_scanner.py +91 -0
- package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/opencode.py +289 -0
- package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/scanners.py +92 -0
- package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/sqlite_optional_scanners.py +203 -0
- package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/sqlite_scanners.py +177 -0
- package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/timeparse.py +51 -0
- package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/transcript.py +149 -0
- package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/types.py +57 -0
- package/packages/shared-skills/skills/coding-agent-sessions/scripts/find-agent-sessions.py +19 -0
- package/packages/shared-skills/skills/frontend/ATTRIBUTION.md +52 -8
- package/packages/shared-skills/skills/frontend/SKILL.md +29 -8
- package/packages/shared-skills/skills/frontend/references/design/README.md +29 -12
- package/packages/shared-skills/skills/frontend/references/design/_INDEX.md +3 -3
- package/packages/shared-skills/skills/frontend/references/design/design-system-architecture.md +22 -19
- package/packages/shared-skills/skills/frontend/references/designpowers/EVIDENCE.md +89 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/README.md +48 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/UPSTREAM.md +80 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/lane-a-direction.md +64 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/lane-b-execution.md +65 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/lane-c-review.md +65 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/lane-d-memory.md +83 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/orchestration.md +80 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/routing.md +79 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/LICENSE +21 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/agents/accessibility-reviewer.md +83 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/agents/content-writer.md +132 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/agents/design-builder.md +109 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/agents/design-critic.md +89 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/agents/design-lead.md +113 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/agents/design-scout.md +78 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/agents/design-strategist.md +121 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/agents/heuristic-evaluator.md +268 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/agents/inspiration-scout.md +107 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/agents/motion-designer.md +120 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/accessible-content/SKILL.md +101 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/adaptive-interfaces/SKILL.md +109 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/cognitive-accessibility/SKILL.md +107 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/design-debate/SKILL.md +199 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/design-debt-tracker/SKILL.md +174 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/design-handoff/SKILL.md +125 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/design-md/SKILL.md +106 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/design-retrospective/SKILL.md +266 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/design-review/SKILL.md +123 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/design-system-alignment/SKILL.md +120 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/designpowers-critique/SKILL.md +164 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/heuristic-evaluation/SKILL.md +85 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/inclusive-personas/SKILL.md +98 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/inspiration-scouting/SKILL.md +165 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/interaction-design/SKILL.md +122 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/motion-choreography/SKILL.md +81 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/research-planning/SKILL.md +96 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/responsive-patterns/SKILL.md +77 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/synthetic-user-testing/SKILL.md +192 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/taste-feedback/SKILL.md +165 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/taste-report/SKILL.md +78 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/token-architecture/SKILL.md +75 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/ui-composition/SKILL.md +117 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/usability-testing/SKILL.md +78 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/verification-before-shipping/SKILL.md +125 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/voice-and-tone/SKILL.md +79 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/writing-design-plans/SKILL.md +119 -0
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/scripts/core.py +0 -0
- package/packages/shared-skills/skills/git-master/SKILL.md +4 -0
- package/packages/shared-skills/skills/review-work/SKILL.md +3 -3
- package/packages/shared-skills/skills/start-work/SKILL.md +7 -5
- package/packages/shared-skills/skills/ultraresearch/SKILL.md +4 -252
- package/packages/shared-skills/skills/ulw-plan/SKILL.md +8 -6
- package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +11 -6
- package/packages/shared-skills/skills/ulw-plan/references/intent-clear.md +3 -3
- package/packages/shared-skills/skills/ulw-plan/references/intent-unclear.md +1 -1
- package/packages/{omo-codex/plugin/skills/ultraresearch → shared-skills/skills/ulw-research}/ATTRIBUTION.md +1 -1
- package/packages/shared-skills/skills/ulw-research/SKILL.md +260 -0
- package/packages/shared-skills/skills/visual-qa/SKILL.md +105 -14
- package/packages/shared-skills/skills/visual-qa/scripts/skill-prompt-contract.test.ts +120 -1
- package/script/qa/web-terminal-redaction.d.mts +13 -0
- package/script/qa/web-terminal-redaction.mjs +43 -0
- package/script/qa/web-terminal-renderer.mjs +218 -0
- package/script/qa/web-terminal-visual-qa.mjs +264 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/scripts/tests/test_cookie_domain_filter.py +0 -110
- package/packages/omo-codex/plugin/skills/ultimate-browsing/scripts/tests/test_extract_cookies.py +0 -245
- package/packages/omo-codex/plugin/test/ultraresearch-skill-contract.test.mjs +0 -204
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { spawn } from "node:child_process";
|
|
3
2
|
import { existsSync, realpathSync } from "node:fs";
|
|
4
3
|
import { homedir } from "node:os";
|
|
5
|
-
import { basename,
|
|
4
|
+
import { basename, join, resolve } from "node:path";
|
|
6
5
|
import {
|
|
7
6
|
cwd as processCwd,
|
|
8
7
|
env as processEnv,
|
|
9
|
-
execPath as processExecPath,
|
|
10
8
|
stdin as processStdin,
|
|
11
9
|
stderr as processStderr,
|
|
12
10
|
stdout as processStdout,
|
|
@@ -14,7 +12,7 @@ import {
|
|
|
14
12
|
import type { Readable, Writable } from "node:stream";
|
|
15
13
|
import { fileURLToPath } from "node:url";
|
|
16
14
|
|
|
17
|
-
import { buildCodegraphEnv } from "../../../../../utils/src/codegraph/env.ts";
|
|
15
|
+
import { buildCodegraphChildEnv, buildCodegraphEnv } from "../../../../../utils/src/codegraph/env.ts";
|
|
18
16
|
import {
|
|
19
17
|
buildCodegraphNodeSkipHint,
|
|
20
18
|
evaluateCodegraphNodeSupport,
|
|
@@ -31,12 +29,19 @@ import {
|
|
|
31
29
|
} from "../../../../../utils/src/codegraph/resolve.ts";
|
|
32
30
|
import { getCodexOmoConfig, type CodexOmoConfig } from "../../../shared/src/config-loader.ts";
|
|
33
31
|
import type { CodegraphConfig } from "./hook.js";
|
|
32
|
+
import { runBridgedCodegraphProcess } from "./mcp-bridge.js";
|
|
34
33
|
import { runUnavailableCodegraphMcpServer } from "./mcp-unavailable.js";
|
|
34
|
+
import { SESSION_START_CWD_ENV } from "./session-start-worker.js";
|
|
35
|
+
export { resolveServeProcessInvocation } from "./serve-invocation.js";
|
|
35
36
|
|
|
36
|
-
export type ServeStdio = "
|
|
37
|
+
export type ServeStdio = "pipe";
|
|
37
38
|
|
|
38
39
|
export interface CodegraphServeProcessOptions {
|
|
40
|
+
readonly cwd: string;
|
|
39
41
|
readonly env: Record<string, string | undefined>;
|
|
42
|
+
readonly input: Readable;
|
|
43
|
+
readonly output: Writable;
|
|
44
|
+
readonly stderr: CodegraphServeStderr;
|
|
40
45
|
readonly stdio: ServeStdio;
|
|
41
46
|
}
|
|
42
47
|
|
|
@@ -49,11 +54,6 @@ export type CodegraphProvisioner = (
|
|
|
49
54
|
options: EnsureCodegraphProvisionedOptions,
|
|
50
55
|
) => ReturnType<typeof ensureCodegraphProvisioned>;
|
|
51
56
|
|
|
52
|
-
export interface ServeProcessInvocation {
|
|
53
|
-
readonly args: readonly string[];
|
|
54
|
-
readonly command: string;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
57
|
export interface CodegraphServeStderr {
|
|
58
58
|
readonly write: (chunk: string) => void;
|
|
59
59
|
}
|
|
@@ -79,13 +79,14 @@ const CODEGRAPH_SKIP_HINT =
|
|
|
79
79
|
const CODEGRAPH_DISABLED_HINT =
|
|
80
80
|
"CodeGraph MCP skipped: disabled by OMO SOT config. Set [codex].codegraph.enabled=true to enable it.\n";
|
|
81
81
|
const CODEGRAPH_VERSION = "1.0.1";
|
|
82
|
-
const
|
|
83
|
-
const WINDOWS_NODE_SCRIPT_EXTENSIONS = new Set([".cjs", ".js", ".mjs"]);
|
|
82
|
+
const PROJECT_CWD_ENV_KEYS = ["OMO_CODEGRAPH_PROJECT_CWD", SESSION_START_CWD_ENV, "PWD"] as const;
|
|
84
83
|
|
|
85
84
|
export async function runCodegraphServe(options: RunCodegraphServeOptions = {}): Promise<number> {
|
|
86
85
|
const env = options.env ?? processEnv;
|
|
87
86
|
const homeDir = options.homeDir ?? homedir();
|
|
88
|
-
const
|
|
87
|
+
const wrapperCwd = options.cwd ?? processCwd();
|
|
88
|
+
const projectCwd = resolveProjectCwd(env, wrapperCwd);
|
|
89
|
+
const config = options.config ?? getCodexOmoConfig({ cwd: projectCwd, env, homeDir });
|
|
89
90
|
const codegraphConfig = config.codegraph ?? {};
|
|
90
91
|
if (codegraphConfig.enabled === false) {
|
|
91
92
|
return runUnavailableMcp(CODEGRAPH_DISABLED_HINT, options);
|
|
@@ -120,15 +121,16 @@ export async function runCodegraphServe(options: RunCodegraphServeOptions = {}):
|
|
|
120
121
|
return runUnavailableMcp(buildCodegraphNodeSkipHint(nodeSupport), options);
|
|
121
122
|
}
|
|
122
123
|
|
|
123
|
-
const runProcess = options.runProcess ??
|
|
124
|
+
const runProcess = options.runProcess ?? runBridgedCodegraphProcess;
|
|
124
125
|
const codegraphEnv = codegraphEnvForConfig(trustedInstallDir, homeDir, options.buildEnv);
|
|
125
|
-
const mergedEnv = {
|
|
126
|
-
...env,
|
|
127
|
-
...codegraphEnv,
|
|
128
|
-
};
|
|
126
|
+
const mergedEnv = buildCodegraphChildEnv({ ambientEnv: env, codegraphEnv, runtimeEnv: env });
|
|
129
127
|
return runProcess(resolution.command, [...resolution.argsPrefix, "serve", "--mcp"], {
|
|
128
|
+
cwd: projectCwd,
|
|
130
129
|
env: mergedEnv,
|
|
131
|
-
|
|
130
|
+
input: options.stdin ?? processStdin,
|
|
131
|
+
output: options.stdout ?? processStdout,
|
|
132
|
+
stderr: options.stderr ?? processStderr,
|
|
133
|
+
stdio: "pipe",
|
|
132
134
|
});
|
|
133
135
|
}
|
|
134
136
|
|
|
@@ -185,6 +187,16 @@ function codegraphEnvForConfig(
|
|
|
185
187
|
return trustedInstallDir === undefined ? env : { ...env, CODEGRAPH_INSTALL_DIR: trustedInstallDir };
|
|
186
188
|
}
|
|
187
189
|
|
|
190
|
+
function resolveProjectCwd(env: Record<string, string | undefined>, fallback: string): string {
|
|
191
|
+
for (const key of PROJECT_CWD_ENV_KEYS) {
|
|
192
|
+
const candidate = env[key]?.trim();
|
|
193
|
+
if (candidate === undefined || candidate.length === 0) continue;
|
|
194
|
+
const resolved = resolve(candidate);
|
|
195
|
+
if (existsSync(resolved)) return resolved;
|
|
196
|
+
}
|
|
197
|
+
return resolve(fallback);
|
|
198
|
+
}
|
|
199
|
+
|
|
188
200
|
function provisionedBinFromInstallDir(installDir: string | undefined): string | null {
|
|
189
201
|
if (installDir === undefined) return null;
|
|
190
202
|
const candidate = join(installDir, "bin", process.platform === "win32" ? "codegraph.cmd" : "codegraph");
|
|
@@ -195,44 +207,6 @@ export async function runCodegraphServeCli(): Promise<void> {
|
|
|
195
207
|
process.exitCode = await runCodegraphServe();
|
|
196
208
|
}
|
|
197
209
|
|
|
198
|
-
async function runChildProcess(
|
|
199
|
-
command: string,
|
|
200
|
-
args: readonly string[],
|
|
201
|
-
options: CodegraphServeProcessOptions,
|
|
202
|
-
): Promise<number> {
|
|
203
|
-
const invocation = resolveServeProcessInvocation(command, args);
|
|
204
|
-
const child = spawn(invocation.command, invocation.args, { env: options.env, stdio: options.stdio });
|
|
205
|
-
return new Promise<number>((resolve, reject) => {
|
|
206
|
-
child.once("error", reject);
|
|
207
|
-
child.once("exit", (code, signal) => {
|
|
208
|
-
if (code !== null) {
|
|
209
|
-
resolve(code);
|
|
210
|
-
return;
|
|
211
|
-
}
|
|
212
|
-
resolve(signal === null ? 0 : 1);
|
|
213
|
-
});
|
|
214
|
-
});
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
export function resolveServeProcessInvocation(
|
|
218
|
-
command: string,
|
|
219
|
-
args: readonly string[],
|
|
220
|
-
platform: NodeJS.Platform = process.platform,
|
|
221
|
-
): ServeProcessInvocation {
|
|
222
|
-
if (platform !== "win32") return { args: [...args], command };
|
|
223
|
-
|
|
224
|
-
const extension = extname(command).toLowerCase();
|
|
225
|
-
if (WINDOWS_NODE_SCRIPT_EXTENSIONS.has(extension)) {
|
|
226
|
-
return { args: [command, ...args], command: processExecPath };
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
if (WINDOWS_CMD_EXTENSIONS.has(extension)) {
|
|
230
|
-
return { args: ["/d", "/s", "/c", command, ...args], command: "cmd.exe" };
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
return { args: [...args], command };
|
|
234
|
-
}
|
|
235
|
-
|
|
236
210
|
if (isDirectInvocation(process.argv[1])) {
|
|
237
211
|
runCodegraphServeCli().catch((error: unknown) => {
|
|
238
212
|
processStderr.write(`${error instanceof Error ? (error.stack ?? error.message) : String(error)}\n`);
|
|
@@ -2,10 +2,10 @@ import { execFile } from "node:child_process";
|
|
|
2
2
|
import { appendFileSync, existsSync, mkdirSync } from "node:fs";
|
|
3
3
|
import { homedir } from "node:os";
|
|
4
4
|
import { extname, join } from "node:path";
|
|
5
|
-
import { cwd as processCwd, env as processEnv, stderr as processStderr } from "node:process";
|
|
5
|
+
import { cwd as processCwd, env as processEnv, execPath as processExecPath, stderr as processStderr } from "node:process";
|
|
6
6
|
|
|
7
7
|
import { getCodexOmoConfig } from "../../../shared/src/config-loader.ts";
|
|
8
|
-
import { buildCodegraphEnv } from "../../../../../utils/src/codegraph/env.ts";
|
|
8
|
+
import { buildCodegraphChildEnv, buildCodegraphEnv } from "../../../../../utils/src/codegraph/env.ts";
|
|
9
9
|
import { evaluateCodegraphNodeSupport, type CodegraphNodeSupport } from "../../../../../utils/src/codegraph/node-support.ts";
|
|
10
10
|
import { ensureCodegraphProvisioned } from "../../../../../utils/src/codegraph/provision.ts";
|
|
11
11
|
import {
|
|
@@ -28,6 +28,7 @@ export const SESSION_START_CWD_ENV = "OMO_CODEGRAPH_SESSION_START_CWD";
|
|
|
28
28
|
const CODEGRAPH_VERSION = "1.0.1";
|
|
29
29
|
const COMMAND_TIMEOUT_MS = 60_000;
|
|
30
30
|
const WINDOWS_CMD_EXTENSIONS = new Set([".bat", ".cmd"]);
|
|
31
|
+
const WINDOWS_NODE_SCRIPT_EXTENSIONS = new Set([".cjs", ".js", ".mjs"]);
|
|
31
32
|
type CodegraphBootstrapConfig = CodegraphConfig & {
|
|
32
33
|
readonly trustedCodegraphInstallDir?: string;
|
|
33
34
|
};
|
|
@@ -160,7 +161,7 @@ function jsonSaysInitialized(value: unknown): boolean | undefined {
|
|
|
160
161
|
async function runCodegraphCommand(projectRoot: string, command: string, args: readonly string[], options: { readonly env: Record<string, string>; readonly timeoutMs: number }): Promise<CodegraphCommandResult> {
|
|
161
162
|
const invocation = resolveCodegraphCommandInvocation(command, args);
|
|
162
163
|
return new Promise((resolvePromise) => {
|
|
163
|
-
execFile(invocation.command, [...invocation.args], { cwd: projectRoot, encoding: "utf8", env: {
|
|
164
|
+
execFile(invocation.command, [...invocation.args], { cwd: projectRoot, encoding: "utf8", env: buildCodegraphChildEnv({ ambientEnv: processEnv, codegraphEnv: options.env }), maxBuffer: 1024 * 1024, timeout: options.timeoutMs, windowsHide: true }, (error, stdout, stderr) => {
|
|
164
165
|
if (error === null) {
|
|
165
166
|
resolvePromise({ exitCode: 0, stderr: toOutputText(stderr), stdout: toOutputText(stdout), timedOut: false });
|
|
166
167
|
return;
|
|
@@ -176,7 +177,9 @@ export function resolveCodegraphCommandInvocation(
|
|
|
176
177
|
platform: NodeJS.Platform = process.platform,
|
|
177
178
|
): { readonly args: readonly string[]; readonly command: string } {
|
|
178
179
|
if (platform !== "win32") return { args: [...args], command };
|
|
179
|
-
|
|
180
|
+
const extension = extname(command).toLowerCase();
|
|
181
|
+
if (WINDOWS_NODE_SCRIPT_EXTENSIONS.has(extension)) return { args: [command, ...args], command: processExecPath };
|
|
182
|
+
if (!WINDOWS_CMD_EXTENSIONS.has(extension)) return { args: [...args], command };
|
|
180
183
|
return { args: ["/d", "/s", "/c", command, ...args], command: "cmd.exe" };
|
|
181
184
|
}
|
|
182
185
|
|
|
@@ -15,6 +15,13 @@ import {
|
|
|
15
15
|
const pluginRoot = resolve(fileURLToPath(new URL("../../..", import.meta.url)));
|
|
16
16
|
const pluginConfigPath = resolve(pluginRoot, ".codex-plugin/plugin.json");
|
|
17
17
|
|
|
18
|
+
function expectOmoCodegraphProjectStoreGuidance(context: string): void {
|
|
19
|
+
expect(context).toContain(".omo");
|
|
20
|
+
expect(context).toContain("codegraph");
|
|
21
|
+
expect(context).toContain("projects");
|
|
22
|
+
expect(context).toContain("project-");
|
|
23
|
+
}
|
|
24
|
+
|
|
18
25
|
describe("CodeGraph SessionStart hook", () => {
|
|
19
26
|
it("#given hook session-start cli args #when invoked with empty JSON input #then it emits valid JSON and exits zero", async () => {
|
|
20
27
|
// given
|
|
@@ -30,6 +37,7 @@ describe("CodeGraph SessionStart hook", () => {
|
|
|
30
37
|
stdin: Readable.from(["{}"]),
|
|
31
38
|
stdout: { write: (chunk) => stdout.push(chunk) },
|
|
32
39
|
spawnWorker: (invocation) => spawned.push(invocation),
|
|
40
|
+
statusProbe: () => Promise.resolve(false),
|
|
33
41
|
});
|
|
34
42
|
|
|
35
43
|
// then
|
|
@@ -67,12 +75,9 @@ describe("CodeGraph SessionStart hook", () => {
|
|
|
67
75
|
const parsed = JSON.parse(output);
|
|
68
76
|
|
|
69
77
|
// then
|
|
70
|
-
expect(parsed).
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
additionalContext: expect.stringContaining('"/Users/me/.omo/codegraph/projects/project-'),
|
|
74
|
-
},
|
|
75
|
-
});
|
|
78
|
+
expect(parsed.hookSpecificOutput.hookEventName).toBe("PostToolUse");
|
|
79
|
+
expect(parsed.hookSpecificOutput.additionalContext).toContain('CodeGraph is not initialized for "/Users/me/project"');
|
|
80
|
+
expectOmoCodegraphProjectStoreGuidance(parsed.hookSpecificOutput.additionalContext);
|
|
76
81
|
expect(parsed.hookSpecificOutput.additionalContext).toContain('run `codegraph init` from "/Users/me/project"');
|
|
77
82
|
});
|
|
78
83
|
|
|
@@ -92,7 +97,7 @@ describe("CodeGraph SessionStart hook", () => {
|
|
|
92
97
|
|
|
93
98
|
// then
|
|
94
99
|
expect(parsed.hookSpecificOutput.additionalContext).toContain('CodeGraph is not initialized for "/Users/me/project"');
|
|
95
|
-
|
|
100
|
+
expectOmoCodegraphProjectStoreGuidance(parsed.hookSpecificOutput.additionalContext);
|
|
96
101
|
});
|
|
97
102
|
|
|
98
103
|
it("#given CodeGraph is disabled by Codex SOT config #when SessionStart fires #then it skips without spawning", async () => {
|
|
@@ -214,10 +219,11 @@ describe("CodeGraph SessionStart hook", () => {
|
|
|
214
219
|
const result = await executeCodegraphSessionStartHook({
|
|
215
220
|
config: { codegraph: { enabled: true }, sources: [], warnings: [] },
|
|
216
221
|
cwd: workspace,
|
|
217
|
-
env: { HOME: "/tmp/home", KEEP: "1" },
|
|
222
|
+
env: { HOME: "/tmp/home", KEEP: "1", OPENAI_API_KEY: "sk-test-secret" },
|
|
218
223
|
stdin: Readable.from(["{}"]),
|
|
219
224
|
stdout: { write: (chunk) => stdout.push(chunk) },
|
|
220
225
|
spawnWorker: (invocation) => spawned.push(invocation),
|
|
226
|
+
statusProbe: () => Promise.resolve(false),
|
|
221
227
|
workerCliPath: "/plugin/components/codegraph/dist/cli.js",
|
|
222
228
|
});
|
|
223
229
|
|
|
@@ -229,11 +235,12 @@ describe("CodeGraph SessionStart hook", () => {
|
|
|
229
235
|
command: process.execPath,
|
|
230
236
|
env: {
|
|
231
237
|
HOME: "/tmp/home",
|
|
232
|
-
KEEP: "1",
|
|
233
238
|
OMO_CODEGRAPH_SESSION_START_CWD: workspace,
|
|
234
239
|
},
|
|
235
240
|
},
|
|
236
241
|
]);
|
|
242
|
+
expect(spawned[0]?.env["OPENAI_API_KEY"]).toBeUndefined();
|
|
243
|
+
expect(spawned[0]?.env["KEEP"]).toBeUndefined();
|
|
237
244
|
expect(JSON.parse(stdout.join(""))).toEqual({
|
|
238
245
|
hookSpecificOutput: {
|
|
239
246
|
additionalContext: "LazyCodex CodeGraph bootstrap scheduled in background",
|
|
@@ -245,6 +252,33 @@ describe("CodeGraph SessionStart hook", () => {
|
|
|
245
252
|
}
|
|
246
253
|
});
|
|
247
254
|
|
|
255
|
+
it("#given CodeGraph is already initialized #when SessionStart fires #then it stays silent without spawning", async () => {
|
|
256
|
+
// given
|
|
257
|
+
const stdout: string[] = [];
|
|
258
|
+
const spawned: WorkerSpawnInvocation[] = [];
|
|
259
|
+
const workspace = mkdtempSync(join(tmpdir(), "omo-codegraph-initialized-workspace-"));
|
|
260
|
+
|
|
261
|
+
try {
|
|
262
|
+
// when
|
|
263
|
+
const result = await executeCodegraphSessionStartHook({
|
|
264
|
+
config: { codegraph: { enabled: true }, sources: [], warnings: [] },
|
|
265
|
+
cwd: workspace,
|
|
266
|
+
env: { HOME: "/tmp/home", KEEP: "1" },
|
|
267
|
+
stdin: Readable.from(["{}"]),
|
|
268
|
+
stdout: { write: (chunk) => stdout.push(chunk) },
|
|
269
|
+
spawnWorker: (invocation) => spawned.push(invocation),
|
|
270
|
+
statusProbe: () => Promise.resolve(true),
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
// then
|
|
274
|
+
expect(result).toEqual({ action: "skipped-initialized", exitCode: 0 });
|
|
275
|
+
expect(spawned).toEqual([]);
|
|
276
|
+
expect(stdout.join("")).toBe("");
|
|
277
|
+
} finally {
|
|
278
|
+
rmSync(workspace, { recursive: true, force: true });
|
|
279
|
+
}
|
|
280
|
+
});
|
|
281
|
+
|
|
248
282
|
it("#given malformed hook input with CodeGraph disabled #when SessionStart fires #then it stays silent and exits zero", async () => {
|
|
249
283
|
// given
|
|
250
284
|
const stdout: string[] = [];
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { describe, expect, it } from "bun:test";
|
|
2
|
+
import { chmodSync, mkdirSync, mkdtempSync, readFileSync, realpathSync, rmSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { PassThrough } from "node:stream";
|
|
6
|
+
|
|
7
|
+
import { runCodegraphServe } from "../src/serve.ts";
|
|
8
|
+
|
|
9
|
+
describe("runCodegraphServe MCP protocol bridge", () => {
|
|
10
|
+
it("#given Codex framed stdio and a newline-json CodeGraph child #when listing tools #then it bridges frames and serves from the project cwd", async () => {
|
|
11
|
+
// given
|
|
12
|
+
const tempRoot = mkdtempSync(join(tmpdir(), "omo-codegraph-bridge-"));
|
|
13
|
+
const projectRoot = join(tempRoot, "project");
|
|
14
|
+
const pluginCacheRoot = join(tempRoot, "plugin-cache");
|
|
15
|
+
const fakeCodegraph = join(tempRoot, "codegraph-fake.cjs");
|
|
16
|
+
const childLog = join(tempRoot, "child.log");
|
|
17
|
+
const input = new PassThrough();
|
|
18
|
+
const output = new PassThrough();
|
|
19
|
+
let stdout = "";
|
|
20
|
+
output.on("data", (chunk: Buffer) => {
|
|
21
|
+
stdout += chunk.toString("utf8");
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
mkdirSync(projectRoot, { recursive: true });
|
|
26
|
+
mkdirSync(pluginCacheRoot, { recursive: true });
|
|
27
|
+
writeFakeNewlineCodegraph(fakeCodegraph);
|
|
28
|
+
|
|
29
|
+
const run = runCodegraphServe({
|
|
30
|
+
cwd: pluginCacheRoot,
|
|
31
|
+
env: {
|
|
32
|
+
CODEGRAPH_ALLOW_UNSAFE_NODE: "1",
|
|
33
|
+
CODEGRAPH_FAKE_LOG: childLog,
|
|
34
|
+
OMO_CODEGRAPH_BIN: fakeCodegraph,
|
|
35
|
+
OMO_CODEGRAPH_PROJECT_CWD: projectRoot,
|
|
36
|
+
PATH: process.env["PATH"],
|
|
37
|
+
},
|
|
38
|
+
nodeVersion: "22.14.0",
|
|
39
|
+
buildEnv: () => ({}),
|
|
40
|
+
resolve: () => ({ argsPrefix: [], command: fakeCodegraph, exists: true, source: "env" }),
|
|
41
|
+
stderr: { write: () => undefined },
|
|
42
|
+
stdin: input,
|
|
43
|
+
stdout: output,
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// when
|
|
47
|
+
input.end([
|
|
48
|
+
frameMcpRequest({
|
|
49
|
+
id: 1,
|
|
50
|
+
method: "initialize",
|
|
51
|
+
params: {
|
|
52
|
+
capabilities: {},
|
|
53
|
+
clientInfo: { name: "codex", version: "0.141.0" },
|
|
54
|
+
protocolVersion: "2025-06-18",
|
|
55
|
+
},
|
|
56
|
+
}),
|
|
57
|
+
frameMcpRequest({
|
|
58
|
+
id: 2,
|
|
59
|
+
method: "tools/list",
|
|
60
|
+
params: {},
|
|
61
|
+
}),
|
|
62
|
+
].join(""));
|
|
63
|
+
const exitCode = await run;
|
|
64
|
+
|
|
65
|
+
// then
|
|
66
|
+
expect(exitCode).toBe(0);
|
|
67
|
+
const bodies = parseMcpBodies(stdout);
|
|
68
|
+
expect(bodies).toEqual([
|
|
69
|
+
{
|
|
70
|
+
id: 1,
|
|
71
|
+
jsonrpc: "2.0",
|
|
72
|
+
result: {
|
|
73
|
+
capabilities: { tools: { listChanged: false } },
|
|
74
|
+
protocolVersion: "2025-06-18",
|
|
75
|
+
serverInfo: { name: "codegraph", version: "1.0.1" },
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
id: 2,
|
|
80
|
+
jsonrpc: "2.0",
|
|
81
|
+
result: {
|
|
82
|
+
tools: [
|
|
83
|
+
{ name: "codegraph_search" },
|
|
84
|
+
{ name: "codegraph_node" },
|
|
85
|
+
{ name: "codegraph_explore" },
|
|
86
|
+
{ name: "codegraph_callers" },
|
|
87
|
+
],
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
]);
|
|
91
|
+
expect(readFileSync(childLog, "utf8")).toContain(`cwd=${realpathSync(projectRoot)}`);
|
|
92
|
+
} finally {
|
|
93
|
+
rmSync(tempRoot, { recursive: true, force: true });
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
function writeFakeNewlineCodegraph(filePath: string): void {
|
|
99
|
+
writeFileSync(
|
|
100
|
+
filePath,
|
|
101
|
+
[
|
|
102
|
+
"#!/usr/bin/env node",
|
|
103
|
+
"const fs = require('node:fs');",
|
|
104
|
+
"const readline = require('node:readline');",
|
|
105
|
+
"fs.writeFileSync(process.env.CODEGRAPH_FAKE_LOG, `cwd=${process.cwd()}\\n`);",
|
|
106
|
+
"const rl = readline.createInterface({ input: process.stdin });",
|
|
107
|
+
"rl.on('line', (line) => {",
|
|
108
|
+
" const request = JSON.parse(line);",
|
|
109
|
+
" if (request.method === 'initialize') {",
|
|
110
|
+
" process.stdout.write(JSON.stringify({ jsonrpc: '2.0', id: request.id, result: { capabilities: { tools: { listChanged: false } }, protocolVersion: request.params.protocolVersion, serverInfo: { name: 'codegraph', version: '1.0.1' } } }) + '\\n');",
|
|
111
|
+
" }",
|
|
112
|
+
" if (request.method === 'tools/list') {",
|
|
113
|
+
" process.stdout.write(JSON.stringify({ jsonrpc: '2.0', id: request.id, result: { tools: [{ name: 'codegraph_search' }, { name: 'codegraph_node' }, { name: 'codegraph_explore' }, { name: 'codegraph_callers' }] } }) + '\\n');",
|
|
114
|
+
" }",
|
|
115
|
+
"});",
|
|
116
|
+
].join("\n"),
|
|
117
|
+
);
|
|
118
|
+
chmodSync(filePath, 0o755);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function frameMcpRequest(request: {
|
|
122
|
+
readonly id: number;
|
|
123
|
+
readonly method: string;
|
|
124
|
+
readonly params: Record<string, unknown>;
|
|
125
|
+
}): string {
|
|
126
|
+
const body = JSON.stringify({ jsonrpc: "2.0", ...request });
|
|
127
|
+
return `Content-Length: ${Buffer.byteLength(body)}\r\n\r\n${body}`;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function parseMcpBodies(transcript: string): readonly unknown[] {
|
|
131
|
+
const bodies: unknown[] = [];
|
|
132
|
+
let cursor = 0;
|
|
133
|
+
while (cursor < transcript.length) {
|
|
134
|
+
const headerEnd = transcript.indexOf("\r\n\r\n", cursor);
|
|
135
|
+
if (headerEnd === -1) break;
|
|
136
|
+
const header = transcript.slice(cursor, headerEnd);
|
|
137
|
+
const match = /^Content-Length: (?<length>\d+)$/m.exec(header);
|
|
138
|
+
if (match?.groups?.["length"] === undefined) break;
|
|
139
|
+
const length = Number.parseInt(match.groups["length"], 10);
|
|
140
|
+
const bodyStart = headerEnd + 4;
|
|
141
|
+
const body = transcript.slice(bodyStart, bodyStart + length);
|
|
142
|
+
bodies.push(JSON.parse(body));
|
|
143
|
+
cursor = bodyStart + length;
|
|
144
|
+
}
|
|
145
|
+
return bodies;
|
|
146
|
+
}
|
|
@@ -10,18 +10,21 @@ import { resolveServeProcessInvocation, runCodegraphServe } from "../src/serve.t
|
|
|
10
10
|
const componentRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
11
11
|
|
|
12
12
|
describe("runCodegraphServe", () => {
|
|
13
|
-
it("#given CodeGraph resolves #when serving MCP #then execs codegraph serve --mcp with
|
|
13
|
+
it("#given CodeGraph resolves #when serving MCP #then execs codegraph serve --mcp with bridged stdio and telemetry disabled", async () => {
|
|
14
14
|
// given
|
|
15
|
+
const runCwd = componentRoot;
|
|
15
16
|
const calls: Array<{
|
|
16
17
|
readonly args: readonly string[];
|
|
17
18
|
readonly command: string;
|
|
19
|
+
readonly cwd: string;
|
|
18
20
|
readonly env: Record<string, string | undefined>;
|
|
19
|
-
readonly stdio: "
|
|
21
|
+
readonly stdio: "pipe";
|
|
20
22
|
}> = [];
|
|
21
23
|
|
|
22
24
|
// when
|
|
23
25
|
const exitCode = await runCodegraphServe({
|
|
24
|
-
|
|
26
|
+
cwd: runCwd,
|
|
27
|
+
env: { CUSTOM: "drop", HOME: "/tmp/home", OPENAI_API_KEY: "sk-test-secret" },
|
|
25
28
|
nodeVersion: "22.14.0",
|
|
26
29
|
homeDir: "/tmp/home",
|
|
27
30
|
buildEnv: ({ homeDir }) => ({
|
|
@@ -34,9 +37,9 @@ describe("runCodegraphServe", () => {
|
|
|
34
37
|
runProcess: (
|
|
35
38
|
command: string,
|
|
36
39
|
args: readonly string[],
|
|
37
|
-
options: { readonly env: Record<string, string | undefined>; readonly stdio: "
|
|
40
|
+
options: { readonly cwd: string; readonly env: Record<string, string | undefined>; readonly stdio: "pipe" },
|
|
38
41
|
) => {
|
|
39
|
-
calls.push({ args, command, env: options.env, stdio: options.stdio });
|
|
42
|
+
calls.push({ args, command, cwd: options.cwd, env: options.env, stdio: options.stdio });
|
|
40
43
|
return Promise.resolve(7);
|
|
41
44
|
},
|
|
42
45
|
stderr: { write: () => undefined },
|
|
@@ -48,17 +51,19 @@ describe("runCodegraphServe", () => {
|
|
|
48
51
|
{
|
|
49
52
|
args: ["shim.js", "serve", "--mcp"],
|
|
50
53
|
command: "node",
|
|
54
|
+
cwd: resolve(runCwd),
|
|
51
55
|
env: {
|
|
52
56
|
CODEGRAPH_INSTALL_DIR: "/tmp/home/.omo/codegraph",
|
|
53
57
|
CODEGRAPH_NO_DOWNLOAD: "1",
|
|
54
58
|
CODEGRAPH_TELEMETRY: "0",
|
|
55
|
-
CUSTOM: "keep",
|
|
56
59
|
DO_NOT_TRACK: "1",
|
|
57
60
|
HOME: "/tmp/home",
|
|
58
61
|
},
|
|
59
|
-
stdio: "
|
|
62
|
+
stdio: "pipe",
|
|
60
63
|
},
|
|
61
64
|
]);
|
|
65
|
+
expect(calls[0]?.env["CUSTOM"]).toBeUndefined();
|
|
66
|
+
expect(calls[0]?.env["OPENAI_API_KEY"]).toBeUndefined();
|
|
62
67
|
});
|
|
63
68
|
|
|
64
69
|
it("#given an unsupported local Node but the unsafe override is set #when serving MCP #then it still spawns codegraph", async () => {
|
package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-flow.test.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, expect, it } from "bun:test";
|
|
2
|
-
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
3
3
|
import { tmpdir } from "node:os";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
|
|
@@ -79,6 +79,20 @@ describe("CodeGraph SessionStart worker flow", () => {
|
|
|
79
79
|
});
|
|
80
80
|
});
|
|
81
81
|
|
|
82
|
+
it("#given Windows CodeGraph resolves to a Node script #when default worker runner builds invocation #then Node executes it", () => {
|
|
83
|
+
// given
|
|
84
|
+
const command = "C:\\Users\\test\\.omo\\codegraph\\bin\\codegraph.cjs";
|
|
85
|
+
|
|
86
|
+
// when
|
|
87
|
+
const invocation = resolveCodegraphCommandInvocation(command, ["status", "--json"], "win32");
|
|
88
|
+
|
|
89
|
+
// then
|
|
90
|
+
expect(invocation).toEqual({
|
|
91
|
+
args: [command, "status", "--json"],
|
|
92
|
+
command: process.execPath,
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
|
|
82
96
|
it("#given non-Windows codegraph command #when default worker runner builds invocation #then it executes directly", () => {
|
|
83
97
|
// given
|
|
84
98
|
const command = "/home/test/.omo/codegraph/bin/codegraph";
|
|
@@ -137,6 +151,62 @@ describe("CodeGraph SessionStart worker flow", () => {
|
|
|
137
151
|
}
|
|
138
152
|
}
|
|
139
153
|
});
|
|
154
|
+
|
|
155
|
+
it("#given ambient provider tokens #when default worker runner spawns CodeGraph #then child env only gets safe and controlled variables", async () => {
|
|
156
|
+
// given
|
|
157
|
+
const workspace = mkdtempSync(join(tmpdir(), "omo-codegraph-worker-env-"));
|
|
158
|
+
const homeDir = mkdtempSync(join(tmpdir(), "omo-codegraph-worker-env-home-"));
|
|
159
|
+
const logPath = join(homeDir, "child-env.jsonl");
|
|
160
|
+
const originalOpenAiKey = process.env["OPENAI_API_KEY"];
|
|
161
|
+
process.env["OPENAI_API_KEY"] = "sk-test-secret";
|
|
162
|
+
|
|
163
|
+
try {
|
|
164
|
+
const fakeCodegraphScript = [
|
|
165
|
+
"const fs = require('node:fs');",
|
|
166
|
+
`fs.appendFileSync(${JSON.stringify(logPath)}, JSON.stringify({install:process.env.CODEGRAPH_INSTALL_DIR,openai:process.env.OPENAI_API_KEY}) + '\\n');`,
|
|
167
|
+
"process.stdout.write('{\"initialized\":true}');",
|
|
168
|
+
].join("");
|
|
169
|
+
|
|
170
|
+
// when
|
|
171
|
+
const result = await runCodegraphSessionStartWorker({
|
|
172
|
+
config: { codegraph: { enabled: true }, sources: [], warnings: [] },
|
|
173
|
+
cwd: workspace,
|
|
174
|
+
env: { HOME: homeDir },
|
|
175
|
+
logOutcome: () => undefined,
|
|
176
|
+
nodeVersion: "22.14.0",
|
|
177
|
+
deps: {
|
|
178
|
+
ensureGitignored: () => true,
|
|
179
|
+
ensureProvisioned: () => {
|
|
180
|
+
throw new Error("provisioning should not run when command is resolved");
|
|
181
|
+
},
|
|
182
|
+
prepareWorkspace: () => ({
|
|
183
|
+
dataDir: join(homeDir, ".omo/codegraph/projects/test"),
|
|
184
|
+
dataRoot: join(homeDir, ".omo/codegraph"),
|
|
185
|
+
linked: true,
|
|
186
|
+
mode: "global-linked",
|
|
187
|
+
projectLink: join(workspace, ".codegraph"),
|
|
188
|
+
}),
|
|
189
|
+
resolveCommand: () => ({ argsPrefix: ["-e", fakeCodegraphScript], command: process.execPath, exists: true, source: "bundled" }),
|
|
190
|
+
},
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
// then
|
|
194
|
+
expect(result).toEqual({ action: "synced" });
|
|
195
|
+
const captured = readFileSync(logPath, "utf8")
|
|
196
|
+
.trim()
|
|
197
|
+
.split("\n")
|
|
198
|
+
.map((line) => JSON.parse(line));
|
|
199
|
+
expect(captured).toEqual([
|
|
200
|
+
{ install: join(homeDir, ".omo", "codegraph") },
|
|
201
|
+
{ install: join(homeDir, ".omo", "codegraph") },
|
|
202
|
+
]);
|
|
203
|
+
} finally {
|
|
204
|
+
if (originalOpenAiKey === undefined) delete process.env["OPENAI_API_KEY"];
|
|
205
|
+
else process.env["OPENAI_API_KEY"] = originalOpenAiKey;
|
|
206
|
+
rmSync(workspace, { recursive: true, force: true });
|
|
207
|
+
rmSync(homeDir, { recursive: true, force: true });
|
|
208
|
+
}
|
|
209
|
+
});
|
|
140
210
|
});
|
|
141
211
|
|
|
142
212
|
async function withProcessPlatform(platform: NodeJS.Platform, run: () => Promise<void>): Promise<void> {
|
|
@@ -446,7 +446,10 @@ function wrap(proc) {
|
|
|
446
446
|
}
|
|
447
447
|
function killProcessTree(proc, signal) {
|
|
448
448
|
if (process.platform === "win32" && proc.pid) {
|
|
449
|
-
const result = spawnSync("taskkill", ["/pid", String(proc.pid), "/f", "/t"], {
|
|
449
|
+
const result = spawnSync("taskkill", ["/pid", String(proc.pid), "/f", "/t"], {
|
|
450
|
+
stdio: "ignore",
|
|
451
|
+
windowsHide: true
|
|
452
|
+
});
|
|
450
453
|
if (!result.error && result.status === 0)
|
|
451
454
|
return;
|
|
452
455
|
if (result.error)
|
|
@@ -4032,8 +4032,8 @@ function getSparkShellRuntimeAwareness(env = process.env, deps = {}) {
|
|
|
4032
4032
|
return [
|
|
4033
4033
|
SPARKSHELL_AWARENESS_MARKER,
|
|
4034
4034
|
"",
|
|
4035
|
-
`- Use \`${command} sparkshell <command
|
|
4036
|
-
`- Use \`${command} sparkshell --shell '<command>'\` only for shell metacharacters or
|
|
4035
|
+
`- Use \`${command} sparkshell <command> [args...]\` first for repo inspection, CLI smoke tests, git/history checks, and bounded command output. Pass ordinary commands as executable and arguments in separate argv tokens, for example \`${command} sparkshell rg --files\`; not \`${command} sparkshell 'rg --files'\`, because the quoted string is treated as one executable name. Raw \`rg\`/\`grep\`/\`cat\`/\`git\` are fallbacks when Sparkshell is unavailable or too narrow for the task.`,
|
|
4036
|
+
`- Use \`${command} sparkshell --shell '<command>'\` only for shell syntax such as metacharacters, pipelines, redirects, command substitution, or variable expansion.`,
|
|
4037
4037
|
`- Use \`${command} sparkshell --tmux-pane <pane-id> --tail-lines 400\` only to inspect an existing pane, never to launch ordinary commands. Tail lines must stay between 100 and 1000.`,
|
|
4038
4038
|
"- When no native sidecar or appserver is available, Sparkshell silently falls back to raw command execution. `OMO_SPARKSHELL_BIN` selects a native sidecar path.",
|
|
4039
4039
|
"- When `CODEX_THREAD_ID` identifies a Codex session, Sparkshell feeds recent session context (first/latest user request + last 5 conversation messages) into oversized-output condensation for relevance ranking, but never appends that context to command output. `OMO_SPARKSHELL_SESSION_CONTEXT=0` disables the lookup.",
|