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
|
@@ -81,8 +81,8 @@ export function getSparkShellRuntimeAwareness(env: RuntimeEnv = process.env, dep
|
|
|
81
81
|
return [
|
|
82
82
|
SPARKSHELL_AWARENESS_MARKER,
|
|
83
83
|
"",
|
|
84
|
-
`- Use \`${command} sparkshell <command
|
|
85
|
-
`- Use \`${command} sparkshell --shell '<command>'\` only for shell metacharacters or
|
|
84
|
+
`- 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.`,
|
|
85
|
+
`- Use \`${command} sparkshell --shell '<command>'\` only for shell syntax such as metacharacters, pipelines, redirects, command substitution, or variable expansion.`,
|
|
86
86
|
`- 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.`,
|
|
87
87
|
"- When no native sidecar or appserver is available, Sparkshell silently falls back to raw command execution. `OMO_SPARKSHELL_BIN` selects a native sidecar path.",
|
|
88
88
|
"- 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.",
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
// allow: SIZE_OK - rules sparkshell-awareness coverage validates one injected guidance contract; this release adds narrow prompt cases and future growth should split by guidance surface.
|
|
2
|
+
|
|
1
3
|
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
2
4
|
import { tmpdir } from "node:os";
|
|
3
5
|
import { join } from "node:path";
|
|
@@ -26,7 +28,8 @@ function normalizeGuidance(value: string): string {
|
|
|
26
28
|
function expectSparkshellFirstContract(value: string): void {
|
|
27
29
|
const guidance = normalizeGuidance(value);
|
|
28
30
|
|
|
29
|
-
expect(
|
|
31
|
+
expect(value).toContain("`omo sparkshell <command> [args...]`");
|
|
32
|
+
expect(guidance).toMatch(/`omo sparkshell <command> \[args\.\.\.\]`[^.]*\bfirst\b/);
|
|
30
33
|
expect(guidance).toMatch(/\brepo inspection\b/);
|
|
31
34
|
expect(guidance).toMatch(/\bcli smoke tests\b/);
|
|
32
35
|
expect(guidance).toMatch(/\bgit\/history checks\b/);
|
|
@@ -34,11 +37,17 @@ function expectSparkshellFirstContract(value: string): void {
|
|
|
34
37
|
expect(guidance).toMatch(/\braw\b[^.]*`rg`\/`grep`\/`cat`\/`git`[^.]*\bfallbacks?\b/);
|
|
35
38
|
expect(guidance).toMatch(/\bsparkshell is unavailable\b/);
|
|
36
39
|
expect(guidance).toMatch(/\btoo narrow\b/);
|
|
40
|
+
expect(value).toContain("`omo sparkshell rg --files`");
|
|
41
|
+
expect(guidance).toMatch(/\bseparate argv tokens\b/);
|
|
42
|
+
expect(value).toContain("not `omo sparkshell 'rg --files'`");
|
|
43
|
+
expect(guidance).toMatch(/\bone executable name\b/);
|
|
37
44
|
expect(guidance).toMatch(/`omo sparkshell --shell '<command>'`[^.]*\bmetacharacters\b[^.]*\bpipelines\b/);
|
|
38
45
|
expect(guidance).toMatch(
|
|
39
46
|
/`omo sparkshell --tmux-pane <pane-id> --tail-lines 400`[^.]*\bonly\b[^.]*\binspect\b[^.]*\bexisting pane\b/,
|
|
40
47
|
);
|
|
41
|
-
expect(guidance).toMatch(
|
|
48
|
+
expect(guidance).toMatch(
|
|
49
|
+
/`omo sparkshell --tmux-pane <pane-id> --tail-lines 400`[^.]*\bnever\b[^.]*\blaunch ordinary commands\b/,
|
|
50
|
+
);
|
|
42
51
|
expect(guidance).not.toMatch(/\bprefer\b[^.]*\bbefore raw shell commands\b/);
|
|
43
52
|
}
|
|
44
53
|
|
|
@@ -20,7 +20,7 @@ You are mid-flight on a Prometheus work plan; this turn is an automatic continua
|
|
|
20
20
|
3. Follow the `start-work` skill in full. The skill is already loaded from your earlier turn — re-read its file at `packages/omo-codex/plugin/skills/start-work/SKILL.md` if you have lost context.
|
|
21
21
|
4. Apply the checkbox's tier from its ledger entry, or classify it now per the start-work skill: LIGHT (default — a narrow change inside existing layers) needs one real-surface proof of the deliverable, with auxiliary surfaces first-class for CLI- or data-shaped work, and only trigger-mapped adversarial classes; HEAVY (new module/abstraction, auth/security, external integration, schema/migration, concurrency, cross-domain refactor, care signals) takes the full per-criterion regime. When unsure, take HEAVY; never downgrade.
|
|
22
22
|
5. Decompose the checkbox into atomic sub-tasks. Dispatch them in PARALLEL via `multi_agent_v1.spawn_agent` calls in this same response unless a sub-task has a NAMED blocking dependency (input from another sub-task or shared file). Use `fork_context: false` unless full history is truly required. Put role and specialty instructions inside `message`.
|
|
23
|
-
6. Every sub-task message MUST be self-contained,
|
|
23
|
+
6. Every sub-task message MUST be self-contained, executable, not a context handoff: start with `TASK: <imperative assignment>`, then name `DELIVERABLE`, `SCOPE`, and `VERIFY`. It must include all 7 sections and a Manual-QA channel with exact invocation (`curl`, `send-keys`, `browser:control-in-app-browser` action, `page.click`) and PASS/FAIL observable, plus ultraqa classes, artifact, and cleanup receipt. Channels: HTTP (`curl -i`); tmux (`send-keys` + `capture-pane`); browser (Codex: `browser:control-in-app-browser` first unless auth/persistent profile needed; else Chrome/agent-browser); computer use.
|
|
24
24
|
7. Treat every worker DoneClaim as untrusted input. Run independent AdversarialVerify before any checkbox can become FullyDone; `confirmed` is the only pass verdict, while `false-positive`, `needs-fix`, and `needs-human-review` loop back to the executor with exact feedback.
|
|
25
25
|
8. Use `multi_agent_v1.wait_agent` for mailbox signals, not proof of completion — a timeout only means no new mailbox update arrived; a running child is alive. For sub-tasks likely to exceed one wait cycle, require `WORKING: <task> - <current phase>` before long passes and `BLOCKED: <reason>` only when progress stops. Send `TASK STILL ACTIVE: return <deliverable> or BLOCKED: <reason>` only when the child is completed without the deliverable, ack-only, or no longer running. If that followup is still silent or ack-only, record inconclusive, do not count it as pass/review approval, close if safe, and respawn a smaller `fork_context: false` task with the missing deliverable.
|
|
26
26
|
9. After verification of ALL sub-tasks under this checkbox: `apply_patch` the plan to change `- [ ]` → `- [x]`, re-read the plan to confirm the count decreased, append a `task-completed` line to the ledger, then continue.
|
|
@@ -30,17 +30,17 @@ You are mid-flight on a Prometheus work plan; this turn is an automatic continua
|
|
|
30
30
|
|
|
31
31
|
- No production code before a failing-first proof exists: a unit test at a seam, otherwise the sub-task's Manual-QA scenario captured failing. A test that mirrors its implementation (mock-call assertions, pinned constants) is not evidence. When the change touches existing behavior, PIN it first: a baseline characterization test that passes on the unchanged code, with exact inputs, exact observable, and exact assertion. PIN → RED → GREEN → SURFACE.
|
|
32
32
|
- No `--dry-run` as evidence. No "should work". No "tests pass" as completion proof.
|
|
33
|
+
- TUI visual evidence MUST use the web terminal pattern when a task drives an OpenCode/Codex/terminal UI: capture the pane or run `node script/qa/web-terminal-visual-qa.mjs --title "<surface>" --from-file <capture.txt> --evidence-dir <dir>` (or `--command` when tmux is available), then cite `terminal.png`, `terminal.txt`, and `metadata.json`.
|
|
33
34
|
- No `as any` / `@ts-ignore` / `@ts-expect-error`. No deleting failing tests.
|
|
34
35
|
- Probe every ultraqa adversarial class whose trigger fact holds (malformed input, prompt injection, cancel/resume, stale state, dirty worktree, hung or long commands, flaky tests, misleading success output, repeated interruptions — trigger map in the start-work skill) and capture the observable for each. A clean happy-path artifact alone is NOT a PASS when an applicable class went unprobed; record skipped classes with a one-line not-applicable reason.
|
|
35
|
-
- Cleanup receipt is mandatory. Register each QA
|
|
36
|
+
- Cleanup receipt is mandatory. Register each QA teardown (scripts, tmux, browser contexts, PIDs, ports, containers, temp dirs) as a todo when it spawns, then execute it. Leftover QA state = BLOCKED, not PASS.
|
|
36
37
|
- The worktree path (if set in boulder.json) governs every file edit and command. Do not stray into the main repo.
|
|
38
|
+
- PR or branch implementation/review/merge work requires a task-owned git worktree. Treat the main worktree as read-only context.
|
|
37
39
|
- session_ids you write to boulder.json MUST be prefixed `codex:`. Bare ids on read are legacy `opencode:`.
|
|
38
40
|
|
|
39
|
-
#
|
|
41
|
+
# Final gate
|
|
40
42
|
|
|
41
|
-
Before completion, run `review-work` and a `debugging` runtime audit.
|
|
42
|
-
|
|
43
|
-
Do not print `ORCHESTRATION COMPLETE`. Do not create a PR, PR handoff, or branch handoff. Do not write a final completion answer until this gate passes. Always redact secrets, tokens, credentials, auth headers, cookies, env dumps, private logs, and PII from ledgers, PR bodies, and handoffs.
|
|
43
|
+
Before completion, run `review-work` and a `debugging` runtime audit; inconclusive lanes fail. Do not create a PR, PR handoff, branch handoff, merge, or final completion answer until this gate passes. For PR/branch work, stay in the task-owned worktree: create/update the PR, wait for CI/review/Cubic gates, merge by default unless explicitly opted out, then clean up. Redact secrets, tokens, credentials, auth headers, cookies, env dumps, logs, and PII.
|
|
44
44
|
|
|
45
45
|
# Stop conditions for THIS turn
|
|
46
46
|
|
package/packages/omo-codex/plugin/components/start-work-continuation/test/codex-hook.test.ts
CHANGED
|
@@ -138,6 +138,29 @@ describe("start-work Stop hook", () => {
|
|
|
138
138
|
expect(parsed.reason.split(/\s+/).filter(Boolean).length).toBeLessThanOrEqual(1100);
|
|
139
139
|
});
|
|
140
140
|
|
|
141
|
+
it("#given active codex work #when continuation directive is emitted #then PR lifecycle stays worktree-bound", () => {
|
|
142
|
+
// given
|
|
143
|
+
const workspace = createWorkspace({
|
|
144
|
+
boulderJson: createBoulderJson({
|
|
145
|
+
sessionIds: ["codex:sess_abc"],
|
|
146
|
+
status: "active",
|
|
147
|
+
worktreePath: "/tmp/worktree",
|
|
148
|
+
}),
|
|
149
|
+
planMarkdown: ["# Plan", "", "## TODOs", "- [ ] First"].join("\n"),
|
|
150
|
+
});
|
|
151
|
+
const fs = createMemoryFs();
|
|
152
|
+
|
|
153
|
+
// when
|
|
154
|
+
const output = runStopHook(createStopInput(workspace), fs);
|
|
155
|
+
|
|
156
|
+
// then
|
|
157
|
+
const parsed = parseBlockOutput(output);
|
|
158
|
+
expect(parsed.reason).toContain("PR or branch implementation/review/merge work requires a task-owned git worktree");
|
|
159
|
+
expect(parsed.reason).toContain("Treat the main worktree as read-only context");
|
|
160
|
+
expect(parsed.reason).toContain("create/update the PR, wait for CI/review/Cubic gates, merge by default");
|
|
161
|
+
expect(parsed.reason).toContain("Do not create a PR, PR handoff, branch handoff, merge");
|
|
162
|
+
});
|
|
163
|
+
|
|
141
164
|
it("#given stop hook source #when inspected #then it remains Boulder-only without planning bootstrap logic", () => {
|
|
142
165
|
// given
|
|
143
166
|
const hook = readFileSync(new URL("../src/codex-hook.ts", import.meta.url), "utf8");
|
|
@@ -41,25 +41,43 @@ async function runTeammodeHookCli(stdin, stdout) {
|
|
|
41
41
|
}
|
|
42
42
|
function threadTitleReminder(threadReference) {
|
|
43
43
|
const id = formatIdentifier(threadReference.id);
|
|
44
|
-
return threadReference.kind === "thread" ? `THREAD ID ${id}: CALL codex_app.set_thread_title NOW. USE THE REAL TASK/ROLE.` : `PENDING WORKTREE ID ${id}:
|
|
44
|
+
return threadReference.kind === "thread" ? `THREAD ID ${id}: CALL codex_app.set_thread_title NOW. USE THE REAL TASK/ROLE.` : `PENDING WORKTREE ID ${id}: WORKTREE THREAD IS NOT READY YET. DO NOT bind-thread OR SEND THE MEMBER BOOTSTRAP UNTIL A REAL THREAD ID EXISTS. THEN CALL codex_app.set_thread_title USING THE REAL TASK/ROLE.`;
|
|
45
45
|
}
|
|
46
46
|
function formatIdentifier(value) {
|
|
47
47
|
const normalized = value.replace(/\s+/g, " ").trim();
|
|
48
48
|
return normalized.length <= 200 ? normalized : `${normalized.slice(0, 197)}...`;
|
|
49
49
|
}
|
|
50
50
|
function extractThreadCreationReference(toolResponse) {
|
|
51
|
-
|
|
51
|
+
const response = parseToolResponseRecord(toolResponse);
|
|
52
|
+
if (response === null)
|
|
52
53
|
return null;
|
|
53
|
-
const threadId =
|
|
54
|
+
const threadId = response["threadId"];
|
|
54
55
|
if (typeof threadId === "string" && threadId.trim().length > 0) {
|
|
55
56
|
return { kind: "thread", id: threadId };
|
|
56
57
|
}
|
|
57
|
-
const pendingWorktreeId =
|
|
58
|
+
const pendingWorktreeId = response["pendingWorktreeId"];
|
|
58
59
|
if (typeof pendingWorktreeId === "string" && pendingWorktreeId.trim().length > 0) {
|
|
59
60
|
return { kind: "pendingWorktree", id: pendingWorktreeId };
|
|
60
61
|
}
|
|
61
62
|
return null;
|
|
62
63
|
}
|
|
64
|
+
function parseToolResponseRecord(toolResponse) {
|
|
65
|
+
if (isRecord(toolResponse))
|
|
66
|
+
return toolResponse;
|
|
67
|
+
if (typeof toolResponse !== "string")
|
|
68
|
+
return null;
|
|
69
|
+
const trimmed = toolResponse.trim();
|
|
70
|
+
if (trimmed.length === 0)
|
|
71
|
+
return null;
|
|
72
|
+
try {
|
|
73
|
+
const parsed = JSON.parse(trimmed);
|
|
74
|
+
return isRecord(parsed) ? parsed : null;
|
|
75
|
+
} catch (error) {
|
|
76
|
+
if (error instanceof SyntaxError)
|
|
77
|
+
return null;
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
63
81
|
function isPostToolUsePayload(value) {
|
|
64
82
|
if (!isRecord(value))
|
|
65
83
|
return false;
|
|
@@ -89,10 +89,18 @@ subcommand rewrites `guide.md`, so the manual always matches the current team.
|
|
|
89
89
|
exact title to use. If `codex_app.create_thread` accepts a working directory / cwd argument,
|
|
90
90
|
set it to that member's worktree; otherwise the member's manual tells it to `cd` there first.
|
|
91
91
|
Use `codex_app.set_thread_title` if the title did not land at creation.
|
|
92
|
+
If Codex returns only `pendingWorktreeId`, the worktree-backed thread is not ready yet: do not
|
|
93
|
+
`bind-thread` and do not send the member bootstrap. Wait until Codex surfaces a real `threadId`
|
|
94
|
+
or the thread appears in the thread list, then set the title, bind that real id with the cwd,
|
|
95
|
+
and only then send the bootstrap.
|
|
92
96
|
3. `bind-thread` to record each thread id (and `--cwd`), then send that member's bootstrap
|
|
93
97
|
trigger (printed by `add-member` / `member-prompt`) as the thread's first message. The trigger
|
|
94
98
|
is short on purpose: it tells the new thread to READ its `guide.md` and `team.json` rather than
|
|
95
99
|
carrying the whole protocol inline.
|
|
100
|
+
4. Whenever you report, audit, reopen, or hand off a member thread, include the app deep link
|
|
101
|
+
`codex://threads/<thread_id>` next to the raw id. For example:
|
|
102
|
+
`codex://threads/019ef350-ee78-72a3-bd5e-e40cebc3d814`. Worktree-backed threads are easy to
|
|
103
|
+
lose in the sidebar without this link.
|
|
96
104
|
|
|
97
105
|
Every team member is a real Codex thread created with `codex_app.create_thread` - this is strict,
|
|
98
106
|
not a preference. NEVER substitute `multi_agent_v1.spawn_agent`, or any other in-process subagent,
|
|
@@ -113,8 +121,28 @@ members to the hard rules, so you mainly keep the channel open: expect frequent
|
|
|
113
121
|
from each member - findings, `WORKING:`/`BLOCKED:` markers, peer digests - rather than one final
|
|
114
122
|
dump, and act on them as they arrive. All member-to-member and member-to-leader traffic is in English;
|
|
115
123
|
when the END user addresses a member, that member replies in the user's own language. Members hand off
|
|
116
|
-
files and memos through the team `artifacts/` directory and reference them by path.
|
|
117
|
-
|
|
124
|
+
files and memos through the team `artifacts/` directory and reference them by path.
|
|
125
|
+
|
|
126
|
+
## Let members work - do not rush them
|
|
127
|
+
|
|
128
|
+
Members heartbeat every few tool calls and message you on every finding, blocker, and finished
|
|
129
|
+
slice (their manual binds them to this). So a member that is quiet between heartbeats is **working,
|
|
130
|
+
not stalled** - a stretch of silence is the normal sound of focused work, not a problem to chase.
|
|
131
|
+
Re-reading `codex_app.read_thread` to check on a calm member, or sending "any update?" / "are you
|
|
132
|
+
done?" / "hurry up" pings, interrupts that member and slows the whole team. Trust the heartbeat and
|
|
133
|
+
let them cook.
|
|
134
|
+
|
|
135
|
+
Message a member only when one of these is true:
|
|
136
|
+
- you have new information, context, or a correction it needs to do its slice right;
|
|
137
|
+
- you are reassigning, narrowing, or unblocking its scope;
|
|
138
|
+
- a peer's result changes what it should do; or
|
|
139
|
+
- it has gone fully silent well past its heartbeat cadence AND that stall is blocking the team -
|
|
140
|
+
then send one specific question, not a barrage.
|
|
141
|
+
|
|
142
|
+
Otherwise stay calm and keep the channel open: read inbound updates as they arrive and act on them.
|
|
143
|
+
A long-running member is alive; a heartbeat you have not received yet is not a failure. Wait for
|
|
144
|
+
every required member's final report before you declare the team done - rushing toward "done" while
|
|
145
|
+
members are still mid-slice just produces half-built work you will have to redo.
|
|
118
146
|
|
|
119
147
|
## Worktrees - isolate members who would touch the same files
|
|
120
148
|
|
|
@@ -127,6 +155,16 @@ its own worktree. To land the work, `integrate --team <id>` merges every member
|
|
|
127
155
|
current branch with a merge commit (never a squash or rebase); resolve any conflict it reports, then
|
|
128
156
|
`worktree-remove` each worktree at cleanup.
|
|
129
157
|
|
|
158
|
+
After `worktree-add`, immediately send the member a follow-up that includes both its assigned
|
|
159
|
+
worktree path and its `codex://threads/<thread_id>` link. Use `bind-thread --cwd <worktree>` or
|
|
160
|
+
`--worktree-path <worktree>` after the thread exists so `team.json`, `guide.md`, `status`, and
|
|
161
|
+
`member-prompt` all point at the same worktree-backed thread.
|
|
162
|
+
|
|
163
|
+
When the member starts inside a worktree, it must verify the assigned cwd exists and contains the
|
|
164
|
+
repository checkout before editing. If the directory is missing, empty, or does not look like a git
|
|
165
|
+
worktree/repository yet, the member reports `BLOCKED: worktree not ready` to the leader and waits
|
|
166
|
+
instead of editing a parent checkout or an empty directory.
|
|
167
|
+
|
|
130
168
|
## Run a ulw-plan in parallel
|
|
131
169
|
|
|
132
170
|
When a decision-complete plan already exists at `.omo/plans/<slug>.md` (from ulw-plan), execute its
|
package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team-guide.mjs
CHANGED
|
@@ -5,8 +5,12 @@
|
|
|
5
5
|
// writes it once at team creation, and every member thread is told to READ it instead of
|
|
6
6
|
// receiving the rules inline each turn.
|
|
7
7
|
|
|
8
|
+
export function codexThreadLink(threadId) {
|
|
9
|
+
return `codex://threads/${threadId}`;
|
|
10
|
+
}
|
|
11
|
+
|
|
8
12
|
function memberLine(member) {
|
|
9
|
-
const thread = member.threadId ? ` | thread ${member.threadId}` : " | thread not created yet";
|
|
13
|
+
const thread = member.threadId ? ` | thread ${member.threadId} (${codexThreadLink(member.threadId)})` : " | thread not created yet";
|
|
10
14
|
const wt = member.worktree?.path ? ` | worktree ${member.worktree.path}` : "";
|
|
11
15
|
const name = member.name ? ` "${member.name}"` : "";
|
|
12
16
|
const title = member.threadTitle ? ` | thread title \`${member.threadTitle}\`` : "";
|
|
@@ -23,13 +27,23 @@ that is a coordination signal: mark yourself \`blocked\` and tell the leader at
|
|
|
23
27
|
}
|
|
24
28
|
const lines = team.members
|
|
25
29
|
.filter((m) => m.worktree?.path || m.worktree?.branch)
|
|
26
|
-
.map((m) =>
|
|
30
|
+
.map((m) => {
|
|
31
|
+
const thread = m.threadId ? `; thread ${codexThreadLink(m.threadId)}` : "";
|
|
32
|
+
return `- **${m.id}**: worktree \`${m.worktree.path ?? "(assign with bind-thread --cwd)"}\` on branch \`${m.worktree.branch ?? team.worktree.baseBranch}\`${thread}`;
|
|
33
|
+
});
|
|
27
34
|
return `## Worktrees (ISOLATION IS ON - this is not optional for you)
|
|
28
35
|
|
|
29
36
|
This team runs each member in its own git worktree branched off \`${team.worktree.baseBranch}\`.
|
|
30
37
|
**You MUST work only inside your own worktree.** The very first thing you do is \`cd\` into it;
|
|
31
38
|
every edit, command, and commit happens there. Never touch another member's worktree, and
|
|
32
39
|
never edit files outside your assigned scope. Commit your work so the leader can integrate it.
|
|
40
|
+
Before editing, verify that your assigned worktree exists and contains repo files. If the path is
|
|
41
|
+
missing, empty, or does not look like a git worktree/repository yet, send \`BLOCKED: worktree not ready\`
|
|
42
|
+
to the leader and wait instead of editing any parent checkout or empty directory.
|
|
43
|
+
|
|
44
|
+
If Codex returns only \`pendingWorktreeId\` while the leader is creating a worktree-backed member
|
|
45
|
+
thread, the thread is not ready yet. The leader must wait until Codex surfaces a real thread id,
|
|
46
|
+
then bind that real id and send the bootstrap.
|
|
33
47
|
|
|
34
48
|
${lines.length ? lines.join("\n") : "- (worktree paths are assigned as threads are bound; read team.json for yours)"}`;
|
|
35
49
|
}
|
|
@@ -71,6 +85,8 @@ coordinate with each other, but the leader owns the final decision and integrati
|
|
|
71
85
|
- **Reach the leader and your peers with \`codex_app.send_message_to_thread\` - not by narrating in
|
|
72
86
|
your own thread, where no one reads it.** The address book is in team.json: the leader thread id
|
|
73
87
|
is \`leader.sessionId\`, and each peer thread id is its \`members[].threadId\`.
|
|
88
|
+
- **When you mention a Codex thread, include its app link too:** \`codex://threads/<threadId>\`.
|
|
89
|
+
These links are the fastest way for the leader to reopen worktree-backed member threads.
|
|
74
90
|
- **Push a short message at each of these moments - never batch them into one report at the end:**
|
|
75
91
|
- to the **leader**: every finding or decision, every file or sub-task you finish, a
|
|
76
92
|
\`WORKING: <focus> - <phase>\` heartbeat every few tool calls so you never look stale, a
|
|
@@ -78,7 +94,9 @@ coordinate with each other, but the leader owns the final decision and integrati
|
|
|
78
94
|
- to a **peer**: the instant you learn anything that touches their slice - a shared finding, a
|
|
79
95
|
changed assumption, an interface they depend on. When unsure who owns it, send it to the leader.
|
|
80
96
|
- **Going quiet is the only failure.** Many small lean messages beat one end-of-work dump; keep
|
|
81
|
-
every message short.
|
|
97
|
+
every message short. Your heartbeats are what let the leader relax and leave you to work: a leader
|
|
98
|
+
who can see your progress has no reason to interrupt you, while silence forces it to break in and
|
|
99
|
+
ask where things stand. Frequent lean updates buy you uninterrupted focus.
|
|
82
100
|
|
|
83
101
|
## Artifacts (how you hand work off)
|
|
84
102
|
|
|
@@ -103,10 +121,19 @@ export function buildMemberPrompt(team, id) {
|
|
|
103
121
|
if (!member) throw new Error(`no member with id "${id}"`);
|
|
104
122
|
const guide = team.paths?.guide ?? ".omo/teams/<session_id>/guide.md";
|
|
105
123
|
const teamJson = team.paths?.team ?? ".omo/teams/<session_id>/team.json";
|
|
106
|
-
const where = member.cwd
|
|
124
|
+
const where = member.cwd
|
|
125
|
+
? `Work inside \`${member.cwd}\`.`
|
|
126
|
+
: team.worktree?.enabled
|
|
127
|
+
? "Wait for the leader to bind your worktree cwd before editing."
|
|
128
|
+
: "Work from the repository root unless your manual assigns a worktree.";
|
|
129
|
+
const threadLink = member.threadId ? `\nYour Codex thread link is ${codexThreadLink(member.threadId)}. Include it when reporting handoffs or worktree status.` : "";
|
|
130
|
+
const readiness =
|
|
131
|
+
team.worktree?.enabled
|
|
132
|
+
? "\nBefore editing, verify that your assigned worktree exists and contains repo files. If this prompt arrived before your Codex worktree checkout is ready, or the path is missing, empty, or not a git worktree/repository yet, report `BLOCKED: worktree not ready` to the leader and wait."
|
|
133
|
+
: "";
|
|
107
134
|
return `You are member ${member.id}${member.name ? ` (${member.name})` : ""} of team ${team.teamName} - owner of: ${member.focus}. Your thread title is \`${member.threadTitle}\`.
|
|
108
135
|
FIRST read your field manual at \`${guide}\`, then the team state at \`${teamJson}\`; they define your scope, deliverable, the leader, the artifacts directory, and the communication rules.
|
|
109
|
-
${where}
|
|
136
|
+
${where}${threadLink}${readiness}
|
|
110
137
|
Communicate with the team and leader in English; reply to the end user in the user's own language.
|
|
111
138
|
Start now. Push updates to the leader and relevant peers with \`codex_app.send_message_to_thread\` as you work - findings, \`WORKING:\` heartbeats, and \`BLOCKED:\` the instant you stall - never just one report at the end.`;
|
|
112
139
|
}
|
|
@@ -20,7 +20,7 @@ import { randomUUID } from "node:crypto";
|
|
|
20
20
|
import { realpathSync } from "node:fs";
|
|
21
21
|
import { rm } from "node:fs/promises";
|
|
22
22
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
23
|
-
import { buildGuide, buildMemberPrompt } from "./team-guide.mjs";
|
|
23
|
+
import { buildGuide, buildMemberPrompt, codexThreadLink } from "./team-guide.mjs";
|
|
24
24
|
import {
|
|
25
25
|
addMember,
|
|
26
26
|
archive,
|
|
@@ -164,8 +164,11 @@ const handlers = {
|
|
|
164
164
|
setMemberWorktree(team, { id: member.id, path: result.path, branch: result.branch });
|
|
165
165
|
await persist(team, dir);
|
|
166
166
|
const note = result.created ? "" : " (already exists)";
|
|
167
|
+
const thread = member.threadId
|
|
168
|
+
? `\nMember thread: ${codexThreadLink(member.threadId)}\nTell that member to: cd "${result.path}"`
|
|
169
|
+
: "\nMember thread is not bound yet; wait for the real Codex thread id, then bind-thread before sending bootstrap. After binding, send the member this worktree path.";
|
|
167
170
|
process.stdout.write(
|
|
168
|
-
`worktree for member ${member.id}${note}: ${result.path} on branch ${result.branch} (off ${result.base})
|
|
171
|
+
`worktree for member ${member.id}${note}: ${result.path} on branch ${result.branch} (off ${result.base}).${thread}\n`,
|
|
169
172
|
);
|
|
170
173
|
},
|
|
171
174
|
|
|
@@ -232,7 +235,8 @@ const handlers = {
|
|
|
232
235
|
const { team } = await loadTeam(cwd, sessionId);
|
|
233
236
|
process.stdout.write(`Team ${team.teamName} [${team.status}] - leader: main session - ${team.members.length} member(s)\n`);
|
|
234
237
|
for (const m of team.members) {
|
|
235
|
-
|
|
238
|
+
const thread = m.threadId ? ` thread=${m.threadId} link=${codexThreadLink(m.threadId)}` : "";
|
|
239
|
+
process.stdout.write(` ${m.id} (${m.lens}) ${m.focus} -> ${m.deliverable || "(no deliverable)"} [${m.status}]${thread}${m.cwd ? ` cwd=${m.cwd}` : ""}\n`);
|
|
236
240
|
}
|
|
237
241
|
if (isUnderstaffed(team)) {
|
|
238
242
|
process.stdout.write(
|
|
@@ -64,7 +64,7 @@ function threadTitleReminder(threadReference: ThreadCreationReference): string {
|
|
|
64
64
|
const id = formatIdentifier(threadReference.id);
|
|
65
65
|
return threadReference.kind === "thread"
|
|
66
66
|
? `THREAD ID ${id}: CALL codex_app.set_thread_title NOW. USE THE REAL TASK/ROLE.`
|
|
67
|
-
: `PENDING WORKTREE ID ${id}:
|
|
67
|
+
: `PENDING WORKTREE ID ${id}: WORKTREE THREAD IS NOT READY YET. DO NOT bind-thread OR SEND THE MEMBER BOOTSTRAP UNTIL A REAL THREAD ID EXISTS. THEN CALL codex_app.set_thread_title USING THE REAL TASK/ROLE.`;
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
function formatIdentifier(value: string): string {
|
|
@@ -73,18 +73,33 @@ function formatIdentifier(value: string): string {
|
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
function extractThreadCreationReference(toolResponse: unknown): ThreadCreationReference | null {
|
|
76
|
-
|
|
77
|
-
|
|
76
|
+
const response = parseToolResponseRecord(toolResponse);
|
|
77
|
+
if (response === null) return null;
|
|
78
|
+
const threadId = response["threadId"];
|
|
78
79
|
if (typeof threadId === "string" && threadId.trim().length > 0) {
|
|
79
80
|
return { kind: "thread", id: threadId };
|
|
80
81
|
}
|
|
81
|
-
const pendingWorktreeId =
|
|
82
|
+
const pendingWorktreeId = response["pendingWorktreeId"];
|
|
82
83
|
if (typeof pendingWorktreeId === "string" && pendingWorktreeId.trim().length > 0) {
|
|
83
84
|
return { kind: "pendingWorktree", id: pendingWorktreeId };
|
|
84
85
|
}
|
|
85
86
|
return null;
|
|
86
87
|
}
|
|
87
88
|
|
|
89
|
+
function parseToolResponseRecord(toolResponse: unknown): Record<string, unknown> | null {
|
|
90
|
+
if (isRecord(toolResponse)) return toolResponse;
|
|
91
|
+
if (typeof toolResponse !== "string") return null;
|
|
92
|
+
const trimmed = toolResponse.trim();
|
|
93
|
+
if (trimmed.length === 0) return null;
|
|
94
|
+
try {
|
|
95
|
+
const parsed: unknown = JSON.parse(trimmed);
|
|
96
|
+
return isRecord(parsed) ? parsed : null;
|
|
97
|
+
} catch (error) {
|
|
98
|
+
if (error instanceof SyntaxError) return null;
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
88
103
|
function isPostToolUsePayload(value: unknown): value is PostToolUsePayload {
|
|
89
104
|
if (!isRecord(value)) return false;
|
|
90
105
|
return (
|
|
@@ -34,6 +34,36 @@ describe("thread title PostToolUse guidance", () => {
|
|
|
34
34
|
);
|
|
35
35
|
});
|
|
36
36
|
|
|
37
|
+
it("#given Codex reports create_thread output as a JSON string #when the hook runs #then it still extracts the thread id", () => {
|
|
38
|
+
// given
|
|
39
|
+
const output = runPostToolUseHook({
|
|
40
|
+
hook_event_name: "PostToolUse",
|
|
41
|
+
session_id: "s-team",
|
|
42
|
+
turn_id: "t-team",
|
|
43
|
+
transcript_path: null,
|
|
44
|
+
cwd: "/repo",
|
|
45
|
+
model: "gpt-5.5",
|
|
46
|
+
permission_mode: "default",
|
|
47
|
+
tool_name: "codex_app.create_thread",
|
|
48
|
+
tool_use_id: "tool-create-thread",
|
|
49
|
+
tool_input: {
|
|
50
|
+
prompt: "Review a worktree PR",
|
|
51
|
+
target: { type: "project", projectId: "/repo", environment: { type: "local" } },
|
|
52
|
+
},
|
|
53
|
+
tool_response: '{"threadId":"019ef350-ee78-72a3-bd5e-e40cebc3d814"}',
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
// when
|
|
57
|
+
const parsed: unknown = JSON.parse(output);
|
|
58
|
+
|
|
59
|
+
// then
|
|
60
|
+
expect(isHookOutput(parsed)).toBe(true);
|
|
61
|
+
if (!isHookOutput(parsed)) return;
|
|
62
|
+
expect(parsed.hookSpecificOutput.additionalContext).toBe(
|
|
63
|
+
"THREAD ID 019ef350-ee78-72a3-bd5e-e40cebc3d814: CALL codex_app.set_thread_title NOW. USE THE REAL TASK/ROLE.",
|
|
64
|
+
);
|
|
65
|
+
});
|
|
66
|
+
|
|
37
67
|
it("#given an unrelated tool completed #when the hook runs #then it stays silent", () => {
|
|
38
68
|
// given
|
|
39
69
|
const output = runPostToolUseHook({
|
|
@@ -57,7 +87,7 @@ describe("thread title PostToolUse guidance", () => {
|
|
|
57
87
|
expect(actual).toBe("");
|
|
58
88
|
});
|
|
59
89
|
|
|
60
|
-
it("#given worktree-backed thread creation is pending #when the hook runs #then it tells Codex to
|
|
90
|
+
it("#given worktree-backed thread creation is pending #when the hook runs #then it tells Codex to wait for the real thread before bootstrapping", () => {
|
|
61
91
|
// given
|
|
62
92
|
const output = runPostToolUseHook({
|
|
63
93
|
hook_event_name: "PostToolUse",
|
|
@@ -89,7 +119,7 @@ describe("thread title PostToolUse guidance", () => {
|
|
|
89
119
|
expect(isHookOutput(parsed)).toBe(true);
|
|
90
120
|
if (!isHookOutput(parsed)) return;
|
|
91
121
|
expect(parsed.hookSpecificOutput.additionalContext).toBe(
|
|
92
|
-
"PENDING WORKTREE ID remote-control:env:test-worktree:
|
|
122
|
+
"PENDING WORKTREE ID remote-control:env:test-worktree: WORKTREE THREAD IS NOT READY YET. DO NOT bind-thread OR SEND THE MEMBER BOOTSTRAP UNTIL A REAL THREAD ID EXISTS. THEN CALL codex_app.set_thread_title USING THE REAL TASK/ROLE.",
|
|
93
123
|
);
|
|
94
124
|
});
|
|
95
125
|
});
|
|
@@ -9,7 +9,7 @@ Bundled Codex agent role TOMLs in `agents/` are installed into `CODEX_HOME/agent
|
|
|
9
9
|
| Mandate | Behavior |
|
|
10
10
|
|---|---|
|
|
11
11
|
| Goal + binding success criteria | Call `create_goal` (or open with a `# Goal` block) listing the deliverable + **3+ realistic QA scenarios** (happy path, edge cases, adjacent-surface regression). Each scenario MUST name which **Manual-QA channel** it will use. "Tests pass" is supporting signal, NEVER completion proof. |
|
|
12
|
-
| Manual-QA channels (TESTS ALONE NEVER PROVE DONE) | A dedicated top-level section enumerates the **four** channels you can use to verify a criterion in reality: **(1) HTTP call** (`curl -i` / Playwright APIRequestContext), **(2) tmux** (`tmux new-session` + `send-keys` + `capture-pane`), **(3) Browser use** (Playwright / puppeteer / Chromium driving the real page), **(4) Computer use** (OS-level GUI automation against the running app). Every criterion picks one channel, builds a real-usage scenario, runs it, and captures the artifact — every time. Aux surfaces (CLI stdout / DB diff / parsed config) only count for genuinely CLI- or data-shaped criteria. |
|
|
12
|
+
| Manual-QA channels (TESTS ALONE NEVER PROVE DONE) | A dedicated top-level section enumerates the **four** channels you can use to verify a criterion in reality: **(1) HTTP call** (`curl -i` / Playwright APIRequestContext), **(2) tmux** (`tmux new-session` + `send-keys` + `capture-pane`), **(3) Browser use** (in Codex, `browser:control-in-app-browser` first when no authenticated/persistent browser profile is needed; otherwise Playwright / puppeteer / Chromium driving the real page), **(4) Computer use** (OS-level GUI automation against the running app). Every criterion picks one channel, builds a real-usage scenario, runs it, and captures the artifact — every time. Aux surfaces (CLI stdout / DB diff / parsed config) only count for genuinely CLI- or data-shaped criteria. |
|
|
13
13
|
| Surface + paired cleanup | Execution loop step 4 (**SURFACE-AS-SCENARIO**) runs the chosen channel scenario end-to-end. Step 5 (**CLEANUP, PAIRED**) tears down every QA-spawned process / tmux session / browser context / container / port / temp dir, with a one-line receipt appended to the notepad. Leftover state → NOT done. |
|
|
14
14
|
| Durable /tmp notepad | `mktemp -t ulw-$(date +%Y%m%d-%H%M%S).XXXXXX.md` with sections `Plan`, `Success criteria + QA scenarios`, `Now`, `Todo`, `Findings`, `Learnings`. **Append**, never rewrite. |
|
|
15
15
|
| Obsessive atomic todos | Every action — even one-line edits, `ls`, single test runs — becomes a todo. Format: `path: <action> for <criterion> — verify by <check>`. One in_progress at a time, mark completed immediately. |
|
|
@@ -46,7 +46,7 @@ If asked "where is auth?", explain the auth flow you found.]
|
|
|
46
46
|
</results>
|
|
47
47
|
|
|
48
48
|
# Tool strategy (parallel, flood the first wave)
|
|
49
|
-
- Use `omo sparkshell <command
|
|
49
|
+
- Use `omo sparkshell <command> [args...]` first for repo-wide inspection, CLI smoke tests, git/history checks, and bounded command output. Pass ordinary commands as executable and arguments in separate argv tokens, for example `omo sparkshell rg --files`; not `omo 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. Use `omo sparkshell --shell '<command>'` only for shell syntax such as metacharacters, pipelines, redirects, command substitution, or variable expansion. Use `omo sparkshell --tmux-pane <pane-id> --tail-lines 400` only to inspect an existing tmux pane, never to launch ordinary commands.
|
|
50
50
|
- Symbol questions -> `lsp_goto_definition`, `lsp_find_references`, `lsp_symbols`, `lsp_diagnostics`.
|
|
51
51
|
- Structural shapes -> the `ast-grep` skill helper or `sg` CLI with `$VAR` / `$$$` metavars.
|
|
52
52
|
- Text / strings / comments / logs -> `rg` (grep).
|
|
@@ -107,10 +107,10 @@ Critical path: Task 1 -> Task 2 -> Task 6
|
|
|
107
107
|
- [ ] <verifiable condition with the exact command or assertion>
|
|
108
108
|
|
|
109
109
|
QA scenarios (MANDATORY - task incomplete without these):
|
|
110
|
-
> Name the exact tool AND its exact invocation - not "verify it works". Browser use: use
|
|
110
|
+
> Name the exact tool AND its exact invocation - not "verify it works". Browser use: in Codex, use `browser:control-in-app-browser` first when available and no authenticated/persistent user browser profile is required; otherwise use Chrome to drive the page, or agent-browser (https://github.com/vercel-labs/agent-browser) when Chrome is unavailable. Computer use: OS-level GUI automation for a non-browser desktop app.
|
|
111
111
|
```
|
|
112
112
|
Scenario: <happy path>
|
|
113
|
-
Tool: <bash | curl | tmux | playwright(real Chrome) | agent-browser | computer-use>
|
|
113
|
+
Tool: <bash | curl | tmux | browser:control-in-app-browser | playwright(real Chrome) | agent-browser | computer-use>
|
|
114
114
|
Steps: <exact command / API call / page action with concrete inputs - URL, payload, keystrokes, selectors>
|
|
115
115
|
Expected: <concrete, binary pass/fail observable>
|
|
116
116
|
Evidence: .omo/evidence/task-<N>-<slug>.<ext>
|
|
@@ -52,8 +52,10 @@ exercises the surface; capture the artifact.
|
|
|
52
52
|
2. tmux — `tmux new-session -d -s ulw-qa-<criterion>`, drive with
|
|
53
53
|
`send-keys`, dump via `tmux capture-pane -pS -E -`; transcript
|
|
54
54
|
is the artifact.
|
|
55
|
-
3. Browser use —
|
|
56
|
-
|
|
55
|
+
3. Browser use — in Codex, use `browser:control-in-app-browser`
|
|
56
|
+
first when available and no authenticated/persistent user browser
|
|
57
|
+
profile is required. Otherwise use Chrome to drive the REAL page;
|
|
58
|
+
if Chrome is not available, download and use agent-browser
|
|
57
59
|
(https://github.com/vercel-labs/agent-browser). Capture action
|
|
58
60
|
log + screenshot path. Never downgrade to a non-browser surface
|
|
59
61
|
for a browser-facing criterion.
|
|
@@ -68,7 +70,8 @@ upfront: the literal command / API call / page action with its concrete
|
|
|
68
70
|
inputs (URL, payload, keystrokes, selectors) and the single binary
|
|
69
71
|
observable that decides PASS vs FAIL. "run the endpoint", "open the
|
|
70
72
|
page", "check it works" are NOT scenarios — write the `curl ...`, the
|
|
71
|
-
`send-keys ...`, the `page.click(...)`, the
|
|
73
|
+
`send-keys ...`, the Browser plugin action, the `page.click(...)`, the
|
|
74
|
+
expected status/text.
|
|
72
75
|
|
|
73
76
|
Auxiliary surfaces (CLI stdout / DB state diff / parsed config dump)
|
|
74
77
|
are first-class evidence for CLI- or data-shaped criteria; use a
|
|
@@ -76,6 +79,14 @@ channel scenario when the behavior is user-facing. `--dry-run`,
|
|
|
76
79
|
printing the command, "should respond", and "looks correct" never
|
|
77
80
|
count.
|
|
78
81
|
|
|
82
|
+
For TUI visual QA, terminal transcripts alone are not enough when a
|
|
83
|
+
visual surface is being evaluated. In this repo, prefer
|
|
84
|
+
`node script/qa/web-terminal-visual-qa.mjs --title "<surface>" --from-file <capture.txt> --evidence-dir <dir>`
|
|
85
|
+
or the helper's `--command` tmux-backed PTY connector when available.
|
|
86
|
+
Outside this repo, capture equivalent browser/computer-use rendered
|
|
87
|
+
terminal evidence: screenshot, plain transcript, rendered HTML or action
|
|
88
|
+
log, and cleanup receipt.
|
|
89
|
+
|
|
79
90
|
# Bootstrap (DO ALL FOUR BEFORE ANY OTHER WORK — NO SKIPPING)
|
|
80
91
|
|
|
81
92
|
## 0. Survey the skills, then size the work
|
|
@@ -178,11 +189,16 @@ serialize only when one output strictly feeds the next.
|
|
|
178
189
|
inactive/uninitialized, or cold-start unavailable, keep moving with
|
|
179
190
|
Read/Grep/Glob/LSP and the ast-grep skill.
|
|
180
191
|
- Repo-wide inspection, CLI smoke tests, git/history, bounded command
|
|
181
|
-
output → use `omo sparkshell <command
|
|
192
|
+
output → use `omo sparkshell <command> [args...]` first. Pass ordinary
|
|
193
|
+
commands as executable and arguments in separate argv tokens, for
|
|
194
|
+
example `omo sparkshell rg --files`; not `omo sparkshell 'rg --files'`,
|
|
195
|
+
because the quoted string is treated as one executable name. Raw
|
|
182
196
|
`rg`/`grep`/`cat`/`git` are fallbacks when Sparkshell is unavailable
|
|
183
|
-
or too narrow. `--shell` is only for shell
|
|
184
|
-
pipelines
|
|
185
|
-
|
|
197
|
+
or too narrow. `--shell` is only for shell syntax such as
|
|
198
|
+
metacharacters, pipelines, redirects, command substitution, or
|
|
199
|
+
variable expansion; `--tmux-pane` is only for inspecting an existing
|
|
200
|
+
pane, never for launching ordinary commands. Sparkshell is your
|
|
201
|
+
default lens.
|
|
186
202
|
- Symbols — definitions, references, rename impact, diagnostics →
|
|
187
203
|
`lsp_goto_definition`, `lsp_find_references`, `lsp_symbols`,
|
|
188
204
|
`lsp_diagnostics`. Use the LSP, not text search, for anything
|
|
@@ -80,7 +80,7 @@ function isContextPressureTranscript(transcriptPath) {
|
|
|
80
80
|
if (transcriptPath === undefined || transcriptPath === null)
|
|
81
81
|
return false;
|
|
82
82
|
try {
|
|
83
|
-
return isContextPressureRecoveryPrompt(
|
|
83
|
+
return isContextPressureRecoveryPrompt(readTranscriptTail(transcriptPath));
|
|
84
84
|
} catch (error) {
|
|
85
85
|
if (error instanceof Error)
|
|
86
86
|
return false;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@code-yeongyu/codex-ultrawork",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.14.0",
|
|
4
4
|
"description": "Codex plugin that injects the ultrawork orchestration directive and ships LazyCodex planning, review, QA, and gate agent roles.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"packageManager": "npm@11.12.1",
|