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.
Files changed (445) hide show
  1. package/.agents/skills/codex-qa/SKILL.md +15 -0
  2. package/.agents/skills/codex-qa/references/logging-debug.md +12 -0
  3. package/.agents/skills/opencode-qa/SKILL.md +17 -0
  4. package/.agents/skills/opencode-qa/references/tui-tmux.md +17 -0
  5. package/.agents/skills/work-with-pr/SKILL.md +18 -10
  6. package/.opencode/skills/work-with-pr/SKILL.md +18 -10
  7. package/README.md +2 -2
  8. package/dist/cli/doctor/checks/telemetry.d.ts +2 -0
  9. package/dist/cli/doctor/framework/constants.d.ts +1 -0
  10. package/dist/cli/doctor/framework/doctor-target.d.ts +1 -1
  11. package/dist/cli/index.js +24651 -16452
  12. package/dist/cli-node/index.js +24651 -16452
  13. package/dist/config/schema/oh-my-opencode-config.d.ts +1 -0
  14. package/dist/features/team-mode/test-support/async-test-helpers.d.ts +19 -0
  15. package/dist/hooks/atlas/final-wave-approval-gate.d.ts +1 -0
  16. package/dist/hooks/atlas/subagent-completion-reminder.d.ts +30 -0
  17. package/dist/hooks/atlas/types.d.ts +2 -0
  18. package/dist/hooks/atlas/verification-reminders.d.ts +3 -0
  19. package/dist/hooks/team-session-events/team-idle-wake-hint.d.ts +1 -0
  20. package/dist/index.d.ts +1 -0
  21. package/dist/index.js +33232 -19559
  22. package/dist/mcp/context7.d.ts +9 -8
  23. package/dist/oh-my-opencode.schema.json +4 -0
  24. package/dist/shared/posthog.d.ts +17 -10
  25. package/dist/shared/telemetry-product-identity.d.ts +2 -0
  26. package/dist/skills/coding-agent-sessions/SKILL.md +128 -0
  27. package/dist/skills/coding-agent-sessions/agents/openai.yaml +4 -0
  28. package/dist/skills/coding-agent-sessions/references/all-platforms.md +71 -0
  29. package/dist/skills/coding-agent-sessions/references/claude.md +32 -0
  30. package/dist/skills/coding-agent-sessions/references/codex.md +30 -0
  31. package/dist/skills/coding-agent-sessions/references/opencode.md +43 -0
  32. package/dist/skills/coding-agent-sessions/references/senpi.md +17 -0
  33. package/dist/skills/coding-agent-sessions/scripts/agent_sessions/__init__.py +1 -0
  34. package/dist/skills/coding-agent-sessions/scripts/agent_sessions/claude.py +66 -0
  35. package/dist/skills/coding-agent-sessions/scripts/agent_sessions/cli.py +283 -0
  36. package/dist/skills/coding-agent-sessions/scripts/agent_sessions/codex.py +105 -0
  37. package/dist/skills/coding-agent-sessions/scripts/agent_sessions/file_scanners.py +275 -0
  38. package/dist/skills/coding-agent-sessions/scripts/agent_sessions/jsonio.py +55 -0
  39. package/dist/skills/coding-agent-sessions/scripts/agent_sessions/kiro_scanner.py +91 -0
  40. package/dist/skills/coding-agent-sessions/scripts/agent_sessions/opencode.py +289 -0
  41. package/dist/skills/coding-agent-sessions/scripts/agent_sessions/scanners.py +92 -0
  42. package/dist/skills/coding-agent-sessions/scripts/agent_sessions/sqlite_optional_scanners.py +203 -0
  43. package/dist/skills/coding-agent-sessions/scripts/agent_sessions/sqlite_scanners.py +177 -0
  44. package/dist/skills/coding-agent-sessions/scripts/agent_sessions/timeparse.py +51 -0
  45. package/dist/skills/coding-agent-sessions/scripts/agent_sessions/transcript.py +149 -0
  46. package/dist/skills/coding-agent-sessions/scripts/agent_sessions/types.py +57 -0
  47. package/dist/skills/coding-agent-sessions/scripts/find-agent-sessions.py +19 -0
  48. package/dist/skills/frontend/ATTRIBUTION.md +52 -8
  49. package/dist/skills/frontend/SKILL.md +29 -8
  50. package/dist/skills/frontend/references/design/README.md +29 -12
  51. package/dist/skills/frontend/references/design/_INDEX.md +3 -3
  52. package/dist/skills/frontend/references/design/design-system-architecture.md +22 -19
  53. package/dist/skills/frontend/references/designpowers/EVIDENCE.md +89 -0
  54. package/dist/skills/frontend/references/designpowers/README.md +48 -0
  55. package/dist/skills/frontend/references/designpowers/UPSTREAM.md +80 -0
  56. package/dist/skills/frontend/references/designpowers/lane-a-direction.md +64 -0
  57. package/dist/skills/frontend/references/designpowers/lane-b-execution.md +65 -0
  58. package/dist/skills/frontend/references/designpowers/lane-c-review.md +65 -0
  59. package/dist/skills/frontend/references/designpowers/lane-d-memory.md +83 -0
  60. package/dist/skills/frontend/references/designpowers/orchestration.md +80 -0
  61. package/dist/skills/frontend/references/designpowers/routing.md +79 -0
  62. package/dist/skills/frontend/references/designpowers/vendor/LICENSE +21 -0
  63. package/dist/skills/frontend/references/designpowers/vendor/agents/accessibility-reviewer.md +83 -0
  64. package/dist/skills/frontend/references/designpowers/vendor/agents/content-writer.md +132 -0
  65. package/dist/skills/frontend/references/designpowers/vendor/agents/design-builder.md +109 -0
  66. package/dist/skills/frontend/references/designpowers/vendor/agents/design-critic.md +89 -0
  67. package/dist/skills/frontend/references/designpowers/vendor/agents/design-lead.md +113 -0
  68. package/dist/skills/frontend/references/designpowers/vendor/agents/design-scout.md +78 -0
  69. package/dist/skills/frontend/references/designpowers/vendor/agents/design-strategist.md +121 -0
  70. package/dist/skills/frontend/references/designpowers/vendor/agents/heuristic-evaluator.md +268 -0
  71. package/dist/skills/frontend/references/designpowers/vendor/agents/inspiration-scout.md +107 -0
  72. package/dist/skills/frontend/references/designpowers/vendor/agents/motion-designer.md +120 -0
  73. package/dist/skills/frontend/references/designpowers/vendor/skills/accessible-content/SKILL.md +101 -0
  74. package/dist/skills/frontend/references/designpowers/vendor/skills/adaptive-interfaces/SKILL.md +109 -0
  75. package/dist/skills/frontend/references/designpowers/vendor/skills/cognitive-accessibility/SKILL.md +107 -0
  76. package/dist/skills/frontend/references/designpowers/vendor/skills/design-debate/SKILL.md +199 -0
  77. package/dist/skills/frontend/references/designpowers/vendor/skills/design-debt-tracker/SKILL.md +174 -0
  78. package/dist/skills/frontend/references/designpowers/vendor/skills/design-handoff/SKILL.md +125 -0
  79. package/dist/skills/frontend/references/designpowers/vendor/skills/design-md/SKILL.md +106 -0
  80. package/dist/skills/frontend/references/designpowers/vendor/skills/design-retrospective/SKILL.md +266 -0
  81. package/dist/skills/frontend/references/designpowers/vendor/skills/design-review/SKILL.md +123 -0
  82. package/dist/skills/frontend/references/designpowers/vendor/skills/design-system-alignment/SKILL.md +120 -0
  83. package/dist/skills/frontend/references/designpowers/vendor/skills/designpowers-critique/SKILL.md +164 -0
  84. package/dist/skills/frontend/references/designpowers/vendor/skills/heuristic-evaluation/SKILL.md +85 -0
  85. package/dist/skills/frontend/references/designpowers/vendor/skills/inclusive-personas/SKILL.md +98 -0
  86. package/dist/skills/frontend/references/designpowers/vendor/skills/inspiration-scouting/SKILL.md +165 -0
  87. package/dist/skills/frontend/references/designpowers/vendor/skills/interaction-design/SKILL.md +122 -0
  88. package/dist/skills/frontend/references/designpowers/vendor/skills/motion-choreography/SKILL.md +81 -0
  89. package/dist/skills/frontend/references/designpowers/vendor/skills/research-planning/SKILL.md +96 -0
  90. package/dist/skills/frontend/references/designpowers/vendor/skills/responsive-patterns/SKILL.md +77 -0
  91. package/dist/skills/frontend/references/designpowers/vendor/skills/synthetic-user-testing/SKILL.md +192 -0
  92. package/dist/skills/frontend/references/designpowers/vendor/skills/taste-feedback/SKILL.md +165 -0
  93. package/dist/skills/frontend/references/designpowers/vendor/skills/taste-report/SKILL.md +78 -0
  94. package/dist/skills/frontend/references/designpowers/vendor/skills/token-architecture/SKILL.md +75 -0
  95. package/dist/skills/frontend/references/designpowers/vendor/skills/ui-composition/SKILL.md +117 -0
  96. package/dist/skills/frontend/references/designpowers/vendor/skills/usability-testing/SKILL.md +78 -0
  97. package/dist/skills/frontend/references/designpowers/vendor/skills/verification-before-shipping/SKILL.md +125 -0
  98. package/dist/skills/frontend/references/designpowers/vendor/skills/voice-and-tone/SKILL.md +79 -0
  99. package/dist/skills/frontend/references/designpowers/vendor/skills/writing-design-plans/SKILL.md +119 -0
  100. package/dist/skills/frontend/references/ui-ux-db/scripts/core.py +0 -0
  101. package/dist/skills/git-master/SKILL.md +4 -0
  102. package/dist/skills/review-work/SKILL.md +3 -3
  103. package/dist/skills/start-work/SKILL.md +7 -5
  104. package/dist/skills/ultraresearch/SKILL.md +4 -252
  105. package/dist/skills/ulw-plan/SKILL.md +8 -6
  106. package/dist/skills/ulw-plan/references/full-workflow.md +11 -6
  107. package/dist/skills/ulw-plan/references/intent-clear.md +3 -3
  108. package/dist/skills/ulw-plan/references/intent-unclear.md +1 -1
  109. package/dist/skills/{ultraresearch → ulw-research}/ATTRIBUTION.md +1 -1
  110. package/dist/skills/ulw-research/SKILL.md +260 -0
  111. package/dist/skills/visual-qa/SKILL.md +105 -14
  112. package/dist/skills/visual-qa/scripts/skill-prompt-contract.test.ts +120 -1
  113. package/dist/testing/create-plugin-module.d.ts +2 -0
  114. package/dist/tui.js +23917 -16117
  115. package/docs/reference/github-attachment-upload.md +51 -0
  116. package/docs/reference/web-terminal-visual-qa.md +81 -0
  117. package/package.json +20 -14
  118. package/packages/lsp-core/src/lsp/process.ts +4 -1
  119. package/packages/lsp-core/src/mcp.ts +1 -0
  120. package/packages/lsp-daemon/dist/cli.js +5 -1
  121. package/packages/lsp-daemon/dist/index.js +5 -1
  122. package/packages/lsp-daemon/dist/proxy.js +1 -0
  123. package/packages/lsp-tools-mcp/dist/cli.js +5 -1
  124. package/packages/lsp-tools-mcp/dist/lsp/manager.js +4 -1
  125. package/packages/lsp-tools-mcp/dist/mcp.js +5 -1
  126. package/packages/lsp-tools-mcp/dist/tools.js +4 -1
  127. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
  128. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +323 -62
  129. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  130. package/packages/omo-codex/plugin/components/bootstrap/scripts/bootstrap.ps1 +37 -68
  131. package/packages/omo-codex/plugin/components/bootstrap/scripts/node-dispatch.ps1 +75 -0
  132. package/packages/omo-codex/plugin/components/bootstrap/src/cli.ts +1 -1
  133. package/packages/omo-codex/plugin/components/bootstrap/src/setup.ts +2 -18
  134. package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +575 -334
  135. package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +204 -39
  136. package/packages/omo-codex/plugin/components/codegraph/package.json +2 -2
  137. package/packages/omo-codex/plugin/components/codegraph/src/hook-types.ts +7 -1
  138. package/packages/omo-codex/plugin/components/codegraph/src/hook.ts +103 -3
  139. package/packages/omo-codex/plugin/components/codegraph/src/mcp-bridge.ts +114 -0
  140. package/packages/omo-codex/plugin/components/codegraph/src/serve-invocation.ts +29 -0
  141. package/packages/omo-codex/plugin/components/codegraph/src/serve.ts +31 -57
  142. package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker.ts +7 -4
  143. package/packages/omo-codex/plugin/components/codegraph/test/hook.test.ts +43 -9
  144. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge.test.ts +146 -0
  145. package/packages/omo-codex/plugin/components/codegraph/test/serve.test.ts +12 -7
  146. package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-flow.test.ts +71 -1
  147. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  148. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  149. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
  150. package/packages/omo-codex/plugin/components/lsp/dist/cli.js +4 -1
  151. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  152. package/packages/omo-codex/plugin/components/rules/dist/cli.js +2 -2
  153. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  154. package/packages/omo-codex/plugin/components/rules/src/sparkshell-awareness.ts +2 -2
  155. package/packages/omo-codex/plugin/components/rules/test/sparkshell-awareness.test.ts +11 -2
  156. package/packages/omo-codex/plugin/components/start-work-continuation/directive.md +6 -6
  157. package/packages/omo-codex/plugin/components/start-work-continuation/package.json +1 -1
  158. package/packages/omo-codex/plugin/components/start-work-continuation/test/codex-hook.test.ts +23 -0
  159. package/packages/omo-codex/plugin/components/teammode/dist/cli.js +22 -4
  160. package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
  161. package/packages/omo-codex/plugin/components/teammode/skills/teammode/SKILL.md +40 -2
  162. package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team-guide.mjs +32 -5
  163. package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team.mjs +7 -3
  164. package/packages/omo-codex/plugin/components/teammode/src/codex-hook.ts +19 -4
  165. package/packages/omo-codex/plugin/components/teammode/test/thread-title-hook.test.ts +32 -2
  166. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  167. package/packages/omo-codex/plugin/components/ultrawork/README.md +1 -1
  168. package/packages/omo-codex/plugin/components/ultrawork/agents/explorer.toml +1 -1
  169. package/packages/omo-codex/plugin/components/ultrawork/agents/plan.toml +2 -2
  170. package/packages/omo-codex/plugin/components/ultrawork/directive.md +23 -7
  171. package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +1 -1
  172. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
  173. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +6 -4
  174. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +11 -6
  175. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-clear.md +3 -3
  176. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-unclear.md +1 -1
  177. package/packages/omo-codex/plugin/components/ultrawork/src/codex-hook.ts +1 -1
  178. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook-trigger-policy.test.ts +24 -0
  179. package/packages/omo-codex/plugin/components/ultrawork/test/package-smoke.test.ts +6 -1
  180. package/packages/omo-codex/plugin/components/ulw-loop/AGENTS.md +1 -1
  181. package/packages/omo-codex/plugin/components/ulw-loop/README.md +25 -21
  182. package/packages/omo-codex/plugin/components/ulw-loop/biome.json +1 -1
  183. package/packages/omo-codex/plugin/components/ulw-loop/directive.md +381 -0
  184. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-steering.js +14 -1
  185. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +145 -14
  186. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-hook.d.ts +6 -3
  187. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-hook.js +16 -6
  188. package/packages/omo-codex/plugin/components/ulw-loop/dist/ultrawork-directive.d.ts +5 -0
  189. package/packages/omo-codex/plugin/components/ulw-loop/dist/ultrawork-directive.js +104 -0
  190. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +1 -1
  191. package/packages/omo-codex/plugin/components/ulw-loop/package.json +2 -1
  192. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +19 -11
  193. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-steering.ts +14 -1
  194. package/packages/omo-codex/plugin/components/ulw-loop/src/cli.ts +4 -2
  195. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-hook.ts +28 -6
  196. package/packages/omo-codex/plugin/components/ulw-loop/src/ultrawork-directive.ts +113 -0
  197. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-entrypoint.test.ts +33 -2
  198. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-steering-kind-guidance.test.ts +31 -0
  199. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-hook.test.ts +13 -0
  200. package/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts +36 -0
  201. package/packages/omo-codex/plugin/components/ulw-loop/test/skill-contract.test.ts +12 -0
  202. package/packages/omo-codex/plugin/components/ulw-loop/test/ultrawork-directive.test.ts +64 -0
  203. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +2 -1
  204. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +2 -1
  205. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +2 -1
  206. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +2 -1
  207. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +2 -1
  208. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +2 -1
  209. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +2 -1
  210. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +2 -1
  211. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +2 -1
  212. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +2 -1
  213. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +2 -1
  214. package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +2 -1
  215. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +2 -1
  216. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +2 -1
  217. package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +2 -1
  218. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +2 -1
  219. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +2 -1
  220. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +2 -1
  221. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +2 -1
  222. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +2 -1
  223. package/packages/omo-codex/plugin/package-lock.json +13 -13
  224. package/packages/omo-codex/plugin/package.json +1 -1
  225. package/packages/omo-codex/plugin/scripts/auto-update.mjs +9 -5
  226. package/packages/omo-codex/plugin/scripts/materialize-shared-upstreams.mjs +1 -0
  227. package/packages/omo-codex/plugin/scripts/migrate-codex-config/context7-placeholder-guard.mjs +131 -0
  228. package/packages/omo-codex/plugin/scripts/migrate-codex-config/multi-agent-mode-guard.mjs +60 -0
  229. package/packages/omo-codex/plugin/scripts/migrate-codex-config/multi-agent-v2-guard.mjs +3 -10
  230. package/packages/omo-codex/plugin/scripts/migrate-codex-config/root-settings.mjs +31 -1
  231. package/packages/omo-codex/plugin/scripts/migrate-codex-config/subagent-limit-guard.mjs +73 -0
  232. package/packages/omo-codex/plugin/scripts/migrate-codex-config.mjs +20 -3
  233. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +30 -8
  234. package/packages/omo-codex/plugin/skills/coding-agent-sessions/SKILL.md +128 -0
  235. package/packages/omo-codex/plugin/skills/coding-agent-sessions/agents/openai.yaml +4 -0
  236. package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/all-platforms.md +71 -0
  237. package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/claude.md +32 -0
  238. package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/codex.md +30 -0
  239. package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/opencode.md +43 -0
  240. package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/senpi.md +17 -0
  241. package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/__init__.py +1 -0
  242. package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/claude.py +66 -0
  243. package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/cli.py +283 -0
  244. package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/codex.py +105 -0
  245. package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/file_scanners.py +275 -0
  246. package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/jsonio.py +55 -0
  247. package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/kiro_scanner.py +91 -0
  248. package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/opencode.py +289 -0
  249. package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/scanners.py +92 -0
  250. package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/sqlite_optional_scanners.py +203 -0
  251. package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/sqlite_scanners.py +177 -0
  252. package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/timeparse.py +51 -0
  253. package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/transcript.py +149 -0
  254. package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/types.py +57 -0
  255. package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/find-agent-sessions.py +19 -0
  256. package/packages/omo-codex/plugin/skills/frontend/ATTRIBUTION.md +52 -8
  257. package/packages/omo-codex/plugin/skills/frontend/SKILL.md +29 -8
  258. package/packages/omo-codex/plugin/skills/frontend/references/design/README.md +29 -12
  259. package/packages/omo-codex/plugin/skills/frontend/references/design/_INDEX.md +3 -3
  260. package/packages/omo-codex/plugin/skills/frontend/references/design/design-system-architecture.md +22 -19
  261. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/EVIDENCE.md +89 -0
  262. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/README.md +48 -0
  263. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/UPSTREAM.md +80 -0
  264. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-a-direction.md +64 -0
  265. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-b-execution.md +65 -0
  266. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-c-review.md +65 -0
  267. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-d-memory.md +83 -0
  268. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/orchestration.md +80 -0
  269. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/routing.md +79 -0
  270. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/LICENSE +21 -0
  271. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/agents/accessibility-reviewer.md +83 -0
  272. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/agents/content-writer.md +132 -0
  273. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/agents/design-builder.md +109 -0
  274. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/agents/design-critic.md +89 -0
  275. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/agents/design-lead.md +113 -0
  276. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/agents/design-scout.md +78 -0
  277. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/agents/design-strategist.md +121 -0
  278. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/agents/heuristic-evaluator.md +268 -0
  279. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/agents/inspiration-scout.md +107 -0
  280. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/agents/motion-designer.md +120 -0
  281. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/accessible-content/SKILL.md +101 -0
  282. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/adaptive-interfaces/SKILL.md +109 -0
  283. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/cognitive-accessibility/SKILL.md +107 -0
  284. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/design-debate/SKILL.md +199 -0
  285. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/design-debt-tracker/SKILL.md +174 -0
  286. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/design-handoff/SKILL.md +125 -0
  287. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/design-md/SKILL.md +106 -0
  288. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/design-retrospective/SKILL.md +266 -0
  289. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/design-review/SKILL.md +123 -0
  290. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/design-system-alignment/SKILL.md +120 -0
  291. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/designpowers-critique/SKILL.md +164 -0
  292. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/heuristic-evaluation/SKILL.md +85 -0
  293. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/inclusive-personas/SKILL.md +98 -0
  294. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/inspiration-scouting/SKILL.md +165 -0
  295. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/interaction-design/SKILL.md +122 -0
  296. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/motion-choreography/SKILL.md +81 -0
  297. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/research-planning/SKILL.md +96 -0
  298. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/responsive-patterns/SKILL.md +77 -0
  299. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/synthetic-user-testing/SKILL.md +192 -0
  300. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/taste-feedback/SKILL.md +165 -0
  301. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/taste-report/SKILL.md +78 -0
  302. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/token-architecture/SKILL.md +75 -0
  303. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/ui-composition/SKILL.md +117 -0
  304. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/usability-testing/SKILL.md +78 -0
  305. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/verification-before-shipping/SKILL.md +125 -0
  306. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/voice-and-tone/SKILL.md +79 -0
  307. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/writing-design-plans/SKILL.md +119 -0
  308. package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/scripts/core.py +0 -0
  309. package/packages/omo-codex/plugin/skills/git-master/SKILL.md +4 -0
  310. package/packages/omo-codex/plugin/skills/init-deep/SKILL.md +4 -0
  311. package/packages/omo-codex/plugin/skills/refactor/SKILL.md +4 -0
  312. package/packages/omo-codex/plugin/skills/remove-ai-slops/SKILL.md +4 -0
  313. package/packages/omo-codex/plugin/skills/review-work/SKILL.md +12 -4
  314. package/packages/omo-codex/plugin/skills/start-work/SKILL.md +14 -8
  315. package/packages/omo-codex/plugin/skills/teammode/SKILL.md +40 -2
  316. package/packages/omo-codex/plugin/skills/teammode/scripts/team-guide.mjs +32 -5
  317. package/packages/omo-codex/plugin/skills/teammode/scripts/team.mjs +7 -3
  318. package/packages/omo-codex/plugin/skills/ultraresearch/SKILL.md +4 -250
  319. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +19 -11
  320. package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +6 -4
  321. package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +11 -6
  322. package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-clear.md +3 -3
  323. package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-unclear.md +1 -1
  324. package/packages/{shared-skills/skills/ultraresearch → omo-codex/plugin/skills/ulw-research}/ATTRIBUTION.md +1 -1
  325. package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +262 -0
  326. package/packages/omo-codex/plugin/skills/ulw-research/agents/openai.yaml +2 -0
  327. package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +109 -14
  328. package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +23 -0
  329. package/packages/omo-codex/plugin/test/aggregate-manifest.test.mjs +1 -0
  330. package/packages/omo-codex/plugin/test/auto-update-release-notes.test.mjs +1 -0
  331. package/packages/omo-codex/plugin/test/auto-update-restart-notice.test.mjs +24 -1
  332. package/packages/omo-codex/plugin/test/bootstrap-binlinks.test.mjs +23 -5
  333. package/packages/omo-codex/plugin/test/bootstrap-hooks.test.mjs +38 -0
  334. package/packages/omo-codex/plugin/test/bootstrap-ps-guard.test.mjs +25 -0
  335. package/packages/omo-codex/plugin/test/bootstrap-setup.test.mjs +1 -7
  336. package/packages/omo-codex/plugin/test/migrate-codex-config.test.mjs +206 -6
  337. package/packages/omo-codex/plugin/test/subagent-limit-migration.test.mjs +44 -0
  338. package/packages/omo-codex/plugin/test/sync-skills-orchestration.test.mjs +50 -1
  339. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +10 -7
  340. package/packages/omo-codex/plugin/test/sync-skills.test.mjs +28 -2
  341. package/packages/omo-codex/plugin/test/teammode-communication.test.mjs +20 -0
  342. package/packages/omo-codex/plugin/test/teammode-thread-links.test.mjs +117 -0
  343. package/packages/omo-codex/plugin/test/teammode-worktree.test.mjs +5 -2
  344. package/packages/omo-codex/plugin/test/ulw-research-skill-contract.test.mjs +285 -0
  345. package/packages/omo-codex/scripts/install-bin-links.test.mjs +6 -1
  346. package/packages/omo-codex/scripts/install-cache-copy.test.mjs +51 -0
  347. package/packages/omo-codex/scripts/install-config.test.mjs +198 -17
  348. package/packages/omo-codex/scripts/install-dist/install-local.mjs +701 -282
  349. package/packages/omo-codex/scripts/install-local-git-bash-preflight.test.mjs +24 -15
  350. package/packages/omo-codex/scripts/install-local.test.mjs +5 -1
  351. package/packages/omo-codex/scripts/install-mcp-context7-runtime.test.mjs +84 -0
  352. package/packages/shared-skills/skills/coding-agent-sessions/SKILL.md +128 -0
  353. package/packages/shared-skills/skills/coding-agent-sessions/agents/openai.yaml +4 -0
  354. package/packages/shared-skills/skills/coding-agent-sessions/references/all-platforms.md +71 -0
  355. package/packages/shared-skills/skills/coding-agent-sessions/references/claude.md +32 -0
  356. package/packages/shared-skills/skills/coding-agent-sessions/references/codex.md +30 -0
  357. package/packages/shared-skills/skills/coding-agent-sessions/references/opencode.md +43 -0
  358. package/packages/shared-skills/skills/coding-agent-sessions/references/senpi.md +17 -0
  359. package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/__init__.py +1 -0
  360. package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/claude.py +66 -0
  361. package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/cli.py +283 -0
  362. package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/codex.py +105 -0
  363. package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/file_scanners.py +275 -0
  364. package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/jsonio.py +55 -0
  365. package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/kiro_scanner.py +91 -0
  366. package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/opencode.py +289 -0
  367. package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/scanners.py +92 -0
  368. package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/sqlite_optional_scanners.py +203 -0
  369. package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/sqlite_scanners.py +177 -0
  370. package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/timeparse.py +51 -0
  371. package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/transcript.py +149 -0
  372. package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/types.py +57 -0
  373. package/packages/shared-skills/skills/coding-agent-sessions/scripts/find-agent-sessions.py +19 -0
  374. package/packages/shared-skills/skills/frontend/ATTRIBUTION.md +52 -8
  375. package/packages/shared-skills/skills/frontend/SKILL.md +29 -8
  376. package/packages/shared-skills/skills/frontend/references/design/README.md +29 -12
  377. package/packages/shared-skills/skills/frontend/references/design/_INDEX.md +3 -3
  378. package/packages/shared-skills/skills/frontend/references/design/design-system-architecture.md +22 -19
  379. package/packages/shared-skills/skills/frontend/references/designpowers/EVIDENCE.md +89 -0
  380. package/packages/shared-skills/skills/frontend/references/designpowers/README.md +48 -0
  381. package/packages/shared-skills/skills/frontend/references/designpowers/UPSTREAM.md +80 -0
  382. package/packages/shared-skills/skills/frontend/references/designpowers/lane-a-direction.md +64 -0
  383. package/packages/shared-skills/skills/frontend/references/designpowers/lane-b-execution.md +65 -0
  384. package/packages/shared-skills/skills/frontend/references/designpowers/lane-c-review.md +65 -0
  385. package/packages/shared-skills/skills/frontend/references/designpowers/lane-d-memory.md +83 -0
  386. package/packages/shared-skills/skills/frontend/references/designpowers/orchestration.md +80 -0
  387. package/packages/shared-skills/skills/frontend/references/designpowers/routing.md +79 -0
  388. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/LICENSE +21 -0
  389. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/agents/accessibility-reviewer.md +83 -0
  390. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/agents/content-writer.md +132 -0
  391. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/agents/design-builder.md +109 -0
  392. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/agents/design-critic.md +89 -0
  393. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/agents/design-lead.md +113 -0
  394. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/agents/design-scout.md +78 -0
  395. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/agents/design-strategist.md +121 -0
  396. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/agents/heuristic-evaluator.md +268 -0
  397. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/agents/inspiration-scout.md +107 -0
  398. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/agents/motion-designer.md +120 -0
  399. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/accessible-content/SKILL.md +101 -0
  400. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/adaptive-interfaces/SKILL.md +109 -0
  401. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/cognitive-accessibility/SKILL.md +107 -0
  402. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/design-debate/SKILL.md +199 -0
  403. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/design-debt-tracker/SKILL.md +174 -0
  404. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/design-handoff/SKILL.md +125 -0
  405. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/design-md/SKILL.md +106 -0
  406. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/design-retrospective/SKILL.md +266 -0
  407. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/design-review/SKILL.md +123 -0
  408. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/design-system-alignment/SKILL.md +120 -0
  409. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/designpowers-critique/SKILL.md +164 -0
  410. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/heuristic-evaluation/SKILL.md +85 -0
  411. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/inclusive-personas/SKILL.md +98 -0
  412. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/inspiration-scouting/SKILL.md +165 -0
  413. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/interaction-design/SKILL.md +122 -0
  414. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/motion-choreography/SKILL.md +81 -0
  415. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/research-planning/SKILL.md +96 -0
  416. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/responsive-patterns/SKILL.md +77 -0
  417. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/synthetic-user-testing/SKILL.md +192 -0
  418. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/taste-feedback/SKILL.md +165 -0
  419. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/taste-report/SKILL.md +78 -0
  420. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/token-architecture/SKILL.md +75 -0
  421. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/ui-composition/SKILL.md +117 -0
  422. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/usability-testing/SKILL.md +78 -0
  423. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/verification-before-shipping/SKILL.md +125 -0
  424. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/voice-and-tone/SKILL.md +79 -0
  425. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/writing-design-plans/SKILL.md +119 -0
  426. package/packages/shared-skills/skills/frontend/references/ui-ux-db/scripts/core.py +0 -0
  427. package/packages/shared-skills/skills/git-master/SKILL.md +4 -0
  428. package/packages/shared-skills/skills/review-work/SKILL.md +3 -3
  429. package/packages/shared-skills/skills/start-work/SKILL.md +7 -5
  430. package/packages/shared-skills/skills/ultraresearch/SKILL.md +4 -252
  431. package/packages/shared-skills/skills/ulw-plan/SKILL.md +8 -6
  432. package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +11 -6
  433. package/packages/shared-skills/skills/ulw-plan/references/intent-clear.md +3 -3
  434. package/packages/shared-skills/skills/ulw-plan/references/intent-unclear.md +1 -1
  435. package/packages/{omo-codex/plugin/skills/ultraresearch → shared-skills/skills/ulw-research}/ATTRIBUTION.md +1 -1
  436. package/packages/shared-skills/skills/ulw-research/SKILL.md +260 -0
  437. package/packages/shared-skills/skills/visual-qa/SKILL.md +105 -14
  438. package/packages/shared-skills/skills/visual-qa/scripts/skill-prompt-contract.test.ts +120 -1
  439. package/script/qa/web-terminal-redaction.d.mts +13 -0
  440. package/script/qa/web-terminal-redaction.mjs +43 -0
  441. package/script/qa/web-terminal-renderer.mjs +218 -0
  442. package/script/qa/web-terminal-visual-qa.mjs +264 -0
  443. package/packages/omo-codex/plugin/skills/ultimate-browsing/scripts/tests/test_cookie_domain_filter.py +0 -110
  444. package/packages/omo-codex/plugin/skills/ultimate-browsing/scripts/tests/test_extract_cookies.py +0 -245
  445. package/packages/omo-codex/plugin/test/ultraresearch-skill-contract.test.mjs +0 -204
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-yeongyu/codex-rules",
3
- "version": "4.13.0",
3
+ "version": "4.14.0",
4
4
  "description": "Codex plugin that injects project rule files into model context through lifecycle hooks.",
5
5
  "type": "module",
6
6
  "packageManager": "npm@11.12.1",
@@ -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>\` first for repo inspection, CLI smoke tests, git/history checks, and bounded command output. 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 metacharacters or pipelines.`,
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(guidance).toMatch(/`omo sparkshell <command>`[^.]*\bfirst\b/);
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(/`omo sparkshell --tmux-pane <pane-id> --tail-lines 400`[^.]*\bnever\b[^.]*\blaunch ordinary commands\b/);
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, an executable assignment rather than a context handoff: start with `TASK: <imperative assignment>`, then name `DELIVERABLE`, `SCOPE`, and `VERIFY`. It must include all 7 sections and name one Manual-QA channel with its exact tool and exact invocation (the literal `curl` / `send-keys` / `page.click` with concrete inputs and the binary PASS/FAIL observable), plus the applicable ultraqa adversarial classes, a captured artifact, and a cleanup receipt. Channels: HTTP call (`curl -i`); tmux (`send-keys` + `capture-pane`); browser use use Chrome to drive the page, else download and use agent-browser (https://github.com/vercel-labs/agent-browser); computer use — OS-level GUI automation for a desktop app.
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 resource teardown (scripts, tmux sessions, browser contexts, PIDs, ports, containers, temp dirs) as its own todo the moment it spawns, then execute it. Leftover QA state = BLOCKED, not PASS.
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
- # Global Review and Debugging Gate
41
+ # Final gate
40
42
 
41
- Before completion, run `review-work` and a `debugging` runtime audit. Treat timeout, missing deliverable, ack-only, `BLOCKED:`, and inconclusive review lanes as failures, not progress. Record at least three debugging hypotheses and the runtime evidence that confirms or refutes each one.
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
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-yeongyu/codex-start-work-continuation",
3
- "version": "4.13.0",
3
+ "version": "4.14.0",
4
4
  "description": "Codex Stop hook continuation injector for omo-codex start-work plans.",
5
5
  "type": "module",
6
6
  "packageManager": "npm@11.12.1",
@@ -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}: CALL codex_app.set_thread_title AS SOON AS THREAD ID EXISTS. USE THE REAL TASK/ROLE.`;
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
- if (!isRecord(toolResponse))
51
+ const response = parseToolResponseRecord(toolResponse);
52
+ if (response === null)
52
53
  return null;
53
- const threadId = toolResponse["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 = toolResponse["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;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sisyphuslabs/codex-teammode",
3
- "version": "4.13.0",
3
+ "version": "4.14.0",
4
4
  "description": "Codex team-mode hook component that keeps background thread titles descriptive after create_thread.",
5
5
  "type": "module",
6
6
  "private": true,
@@ -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. Wait for every
117
- required member's final report before you declare the team done.
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
@@ -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) => `- **${m.id}**: worktree \`${m.worktree.path ?? "(assign with bind-thread --cwd)"}\` on branch \`${m.worktree.branch ?? team.worktree.baseBranch}\``);
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 ? `Work inside \`${member.cwd}\`.` : "Work from the repository root unless your manual assigns a worktree.";
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}).\nTell that member to: cd "${result.path}"\n`,
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
- process.stdout.write(` ${m.id} (${m.lens}) ${m.focus} -> ${m.deliverable || "(no deliverable)"} [${m.status}]${m.threadId ? ` thread=${m.threadId}` : ""}${m.cwd ? ` cwd=${m.cwd}` : ""}\n`);
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}: CALL codex_app.set_thread_title AS SOON AS THREAD ID EXISTS. USE THE REAL TASK/ROLE.`;
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
- if (!isRecord(toolResponse)) return null;
77
- const threadId = toolResponse["threadId"];
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 = toolResponse["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 title the thread once the thread id exists", () => {
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: CALL codex_app.set_thread_title AS SOON AS THREAD ID EXISTS. USE THE REAL TASK/ROLE.",
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
  });
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-yeongyu/codex-telemetry",
3
- "version": "4.13.0",
3
+ "version": "4.14.0",
4
4
  "description": "Codex plugin component that emits omo-codex anonymous daily-active telemetry on SessionStart.",
5
5
  "type": "module",
6
6
  "packageManager": "npm@11.12.1",
@@ -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>` first for repo-wide inspection, CLI smoke tests, git/history checks, and bounded command output. Raw `rg`/`grep`/`cat`/`git` are fallbacks when Sparkshell is unavailable or too narrow. Use `omo sparkshell --shell '<command>'` only for shell metacharacters or pipelines. Use `omo sparkshell --tmux-pane <pane-id> --tail-lines 400` only to inspect an existing tmux pane, never to launch ordinary commands.
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 Chrome to drive the page; if Chrome is not available, download and use agent-browser (https://github.com/vercel-labs/agent-browser). Computer use: OS-level GUI automation for a non-browser desktop app.
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 — use Chrome to drive the REAL page; if Chrome is
56
- not available, download and use agent-browser
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 expected status/text.
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>` first. Raw
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 metacharacters or
184
- pipelines; `--tmux-pane` is only for inspecting an existing pane,
185
- never for launching ordinary commands. Sparkshell is your default lens.
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(readFileSync2(transcriptPath, "utf8"));
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.13.0",
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",