oh-my-copilot 4.13.1 → 4.13.21

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 (507) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/README.md +3 -3
  4. package/bridge/cli.cjs +4709 -1961
  5. package/bridge/mcp-server.cjs +112 -11
  6. package/bridge/runtime-cli.cjs +4917 -2645
  7. package/bridge/team-bridge.cjs +6 -4
  8. package/bridge/team-mcp.cjs +19607 -0
  9. package/bridge/team.js +4895 -2215
  10. package/dist/__tests__/auto-slash-aliases.test.js +91 -0
  11. package/dist/__tests__/auto-slash-aliases.test.js.map +1 -1
  12. package/dist/__tests__/hooks/learner/bridge.test.js +25 -0
  13. package/dist/__tests__/hooks/learner/bridge.test.js.map +1 -1
  14. package/dist/__tests__/hooks/learner/parser.test.js +30 -0
  15. package/dist/__tests__/hooks/learner/parser.test.js.map +1 -1
  16. package/dist/__tests__/hud/extra-usage.test.js +42 -0
  17. package/dist/__tests__/hud/extra-usage.test.js.map +1 -1
  18. package/dist/__tests__/hud/labels.test.d.ts +2 -0
  19. package/dist/__tests__/hud/labels.test.d.ts.map +1 -0
  20. package/dist/__tests__/hud/labels.test.js +158 -0
  21. package/dist/__tests__/hud/labels.test.js.map +1 -0
  22. package/dist/__tests__/hud/render-enterprise.test.d.ts +5 -0
  23. package/dist/__tests__/hud/render-enterprise.test.d.ts.map +1 -0
  24. package/dist/__tests__/hud/render-enterprise.test.js +232 -0
  25. package/dist/__tests__/hud/render-enterprise.test.js.map +1 -0
  26. package/dist/__tests__/hud/render-rate-limits-priority.test.js +185 -0
  27. package/dist/__tests__/hud/render-rate-limits-priority.test.js.map +1 -1
  28. package/dist/__tests__/hud/stdin-session-scope.test.d.ts +2 -0
  29. package/dist/__tests__/hud/stdin-session-scope.test.d.ts.map +1 -0
  30. package/dist/__tests__/hud/stdin-session-scope.test.js +169 -0
  31. package/dist/__tests__/hud/stdin-session-scope.test.js.map +1 -0
  32. package/dist/__tests__/hud/usage-api.test.js +111 -1
  33. package/dist/__tests__/hud/usage-api.test.js.map +1 -1
  34. package/dist/__tests__/hud-marketplace-resolution.test.js +34 -0
  35. package/dist/__tests__/hud-marketplace-resolution.test.js.map +1 -1
  36. package/dist/__tests__/installer-hud-skip.test.js +6 -0
  37. package/dist/__tests__/installer-hud-skip.test.js.map +1 -1
  38. package/dist/__tests__/installer-omc-reference.test.js +1 -1
  39. package/dist/__tests__/installer-omc-reference.test.js.map +1 -1
  40. package/dist/__tests__/keyword-detector-echo-guard.test.d.ts +2 -0
  41. package/dist/__tests__/keyword-detector-echo-guard.test.d.ts.map +1 -0
  42. package/dist/__tests__/keyword-detector-echo-guard.test.js +218 -0
  43. package/dist/__tests__/keyword-detector-echo-guard.test.js.map +1 -0
  44. package/dist/__tests__/mnemosyne/detector.test.js +2 -0
  45. package/dist/__tests__/mnemosyne/detector.test.js.map +1 -1
  46. package/dist/__tests__/notepad.test.js +2 -2
  47. package/dist/__tests__/notepad.test.js.map +1 -1
  48. package/dist/__tests__/pre-tool-enforcer.test.js +84 -1
  49. package/dist/__tests__/pre-tool-enforcer.test.js.map +1 -1
  50. package/dist/__tests__/preemptive-compaction-hook.test.js +63 -0
  51. package/dist/__tests__/preemptive-compaction-hook.test.js.map +1 -1
  52. package/dist/__tests__/ralph-prd-mandatory.test.js +11 -1
  53. package/dist/__tests__/ralph-prd-mandatory.test.js.map +1 -1
  54. package/dist/__tests__/ralph-prd.test.js +40 -2
  55. package/dist/__tests__/ralph-prd.test.js.map +1 -1
  56. package/dist/__tests__/skills.test.js +363 -4
  57. package/dist/__tests__/skills.test.js.map +1 -1
  58. package/dist/__tests__/state-root-resolution.test.js +120 -6
  59. package/dist/__tests__/state-root-resolution.test.js.map +1 -1
  60. package/dist/autoresearch/__tests__/runtime.test.js +225 -28
  61. package/dist/autoresearch/__tests__/runtime.test.js.map +1 -1
  62. package/dist/autoresearch/runtime.d.ts.map +1 -1
  63. package/dist/autoresearch/runtime.js +9 -5
  64. package/dist/autoresearch/runtime.js.map +1 -1
  65. package/dist/cli/__tests__/team-status-worktree.test.d.ts +2 -0
  66. package/dist/cli/__tests__/team-status-worktree.test.d.ts.map +1 -0
  67. package/dist/cli/__tests__/team-status-worktree.test.js +96 -0
  68. package/dist/cli/__tests__/team-status-worktree.test.js.map +1 -0
  69. package/dist/cli/__tests__/team.test.js +164 -0
  70. package/dist/cli/__tests__/team.test.js.map +1 -1
  71. package/dist/cli/autoresearch.d.ts +1 -1
  72. package/dist/cli/autoresearch.d.ts.map +1 -1
  73. package/dist/cli/autoresearch.js +4 -4
  74. package/dist/cli/commands/team.d.ts +1 -0
  75. package/dist/cli/commands/team.d.ts.map +1 -1
  76. package/dist/cli/commands/team.js +15 -3
  77. package/dist/cli/commands/team.js.map +1 -1
  78. package/dist/cli/index.js +3 -0
  79. package/dist/cli/index.js.map +1 -1
  80. package/dist/cli/team.d.ts +6 -0
  81. package/dist/cli/team.d.ts.map +1 -1
  82. package/dist/cli/team.js +126 -5
  83. package/dist/cli/team.js.map +1 -1
  84. package/dist/cli/utils/formatting.d.ts +0 -10
  85. package/dist/cli/utils/formatting.d.ts.map +1 -1
  86. package/dist/cli/utils/formatting.js +0 -52
  87. package/dist/cli/utils/formatting.js.map +1 -1
  88. package/dist/config/__tests__/loader.test.js.map +1 -1
  89. package/dist/features/boulder-state/constants.d.ts +1 -1
  90. package/dist/features/boulder-state/constants.d.ts.map +1 -1
  91. package/dist/features/builtin-skills/skills.d.ts.map +1 -1
  92. package/dist/features/builtin-skills/skills.js +11 -3
  93. package/dist/features/builtin-skills/skills.js.map +1 -1
  94. package/dist/features/builtin-skills/types.d.ts +7 -0
  95. package/dist/features/builtin-skills/types.d.ts.map +1 -1
  96. package/dist/features/delegation-enforcer.d.ts +2 -0
  97. package/dist/features/delegation-enforcer.d.ts.map +1 -1
  98. package/dist/features/delegation-enforcer.js +10 -0
  99. package/dist/features/delegation-enforcer.js.map +1 -1
  100. package/dist/features/magic-keywords.d.ts.map +1 -1
  101. package/dist/features/magic-keywords.js +30 -1
  102. package/dist/features/magic-keywords.js.map +1 -1
  103. package/dist/features/rate-limit-wait/tmux-detector.d.ts +4 -4
  104. package/dist/features/rate-limit-wait/tmux-detector.js +9 -9
  105. package/dist/features/rate-limit-wait/tmux-detector.js.map +1 -1
  106. package/dist/hooks/__tests__/bridge-routing.test.js +156 -0
  107. package/dist/hooks/__tests__/bridge-routing.test.js.map +1 -1
  108. package/dist/hooks/auto-slash-command/constants.d.ts.map +1 -1
  109. package/dist/hooks/auto-slash-command/constants.js +1 -0
  110. package/dist/hooks/auto-slash-command/constants.js.map +1 -1
  111. package/dist/hooks/auto-slash-command/executor.d.ts.map +1 -1
  112. package/dist/hooks/auto-slash-command/executor.js +29 -0
  113. package/dist/hooks/auto-slash-command/executor.js.map +1 -1
  114. package/dist/hooks/bridge.d.ts.map +1 -1
  115. package/dist/hooks/bridge.js +184 -1
  116. package/dist/hooks/bridge.js.map +1 -1
  117. package/dist/hooks/learner/bridge.d.ts.map +1 -1
  118. package/dist/hooks/learner/bridge.js +4 -109
  119. package/dist/hooks/learner/bridge.js.map +1 -1
  120. package/dist/hooks/learner/detector.js +1 -1
  121. package/dist/hooks/learner/parser.d.ts +9 -0
  122. package/dist/hooks/learner/parser.d.ts.map +1 -1
  123. package/dist/hooks/learner/parser.js +18 -5
  124. package/dist/hooks/learner/parser.js.map +1 -1
  125. package/dist/hooks/learner/types.d.ts +6 -0
  126. package/dist/hooks/learner/types.d.ts.map +1 -1
  127. package/dist/hooks/mode-registry/__tests__/session-isolation.test.js +16 -0
  128. package/dist/hooks/mode-registry/__tests__/session-isolation.test.js.map +1 -1
  129. package/dist/hooks/notepad/index.d.ts +4 -1
  130. package/dist/hooks/notepad/index.d.ts.map +1 -1
  131. package/dist/hooks/notepad/index.js +7 -4
  132. package/dist/hooks/notepad/index.js.map +1 -1
  133. package/dist/hooks/persistent-mode/__tests__/ralph-verification-flow.test.js +70 -3
  134. package/dist/hooks/persistent-mode/__tests__/ralph-verification-flow.test.js.map +1 -1
  135. package/dist/hooks/persistent-mode/index.d.ts.map +1 -1
  136. package/dist/hooks/persistent-mode/index.js +17 -13
  137. package/dist/hooks/persistent-mode/index.js.map +1 -1
  138. package/dist/hooks/persistent-mode/stop-hook-blocking.test.js +175 -3
  139. package/dist/hooks/persistent-mode/stop-hook-blocking.test.js.map +1 -1
  140. package/dist/hooks/project-memory/__tests__/integration.test.js +117 -3
  141. package/dist/hooks/project-memory/__tests__/integration.test.js.map +1 -1
  142. package/dist/hooks/project-memory/__tests__/storage.test.js +11 -11
  143. package/dist/hooks/project-memory/__tests__/storage.test.js.map +1 -1
  144. package/dist/hooks/project-memory/index.d.ts.map +1 -1
  145. package/dist/hooks/project-memory/index.js +24 -12
  146. package/dist/hooks/project-memory/index.js.map +1 -1
  147. package/dist/hooks/ralph/index.d.ts +1 -1
  148. package/dist/hooks/ralph/index.d.ts.map +1 -1
  149. package/dist/hooks/ralph/index.js +1 -1
  150. package/dist/hooks/ralph/index.js.map +1 -1
  151. package/dist/hooks/ralph/loop.d.ts +6 -6
  152. package/dist/hooks/ralph/loop.d.ts.map +1 -1
  153. package/dist/hooks/ralph/loop.js +18 -18
  154. package/dist/hooks/ralph/loop.js.map +1 -1
  155. package/dist/hooks/ralph/prd.d.ts +23 -12
  156. package/dist/hooks/ralph/prd.d.ts.map +1 -1
  157. package/dist/hooks/ralph/prd.js +88 -42
  158. package/dist/hooks/ralph/prd.js.map +1 -1
  159. package/dist/hooks/session-end/__tests__/mode-state-cleanup.test.js +20 -0
  160. package/dist/hooks/session-end/__tests__/mode-state-cleanup.test.js.map +1 -1
  161. package/dist/hooks/session-end/index.d.ts +9 -0
  162. package/dist/hooks/session-end/index.d.ts.map +1 -1
  163. package/dist/hooks/session-end/index.js +110 -0
  164. package/dist/hooks/session-end/index.js.map +1 -1
  165. package/dist/hooks/skill-bridge.cjs +114 -92
  166. package/dist/hooks/skill-state/index.d.ts.map +1 -1
  167. package/dist/hooks/skill-state/index.js +1 -0
  168. package/dist/hooks/skill-state/index.js.map +1 -1
  169. package/dist/hud/__tests__/enterprise-cost.test.d.ts +5 -0
  170. package/dist/hud/__tests__/enterprise-cost.test.d.ts.map +1 -0
  171. package/dist/hud/__tests__/enterprise-cost.test.js +151 -0
  172. package/dist/hud/__tests__/enterprise-cost.test.js.map +1 -0
  173. package/dist/hud/__tests__/git-status.test.js +18 -0
  174. package/dist/hud/__tests__/git-status.test.js.map +1 -1
  175. package/dist/hud/__tests__/usage-api-enterprise.test.d.ts +5 -0
  176. package/dist/hud/__tests__/usage-api-enterprise.test.d.ts.map +1 -0
  177. package/dist/hud/__tests__/usage-api-enterprise.test.js +249 -0
  178. package/dist/hud/__tests__/usage-api-enterprise.test.js.map +1 -0
  179. package/dist/hud/elements/background.d.ts +3 -3
  180. package/dist/hud/elements/background.d.ts.map +1 -1
  181. package/dist/hud/elements/background.js +5 -4
  182. package/dist/hud/elements/background.js.map +1 -1
  183. package/dist/hud/elements/call-counts.d.ts +2 -2
  184. package/dist/hud/elements/call-counts.d.ts.map +1 -1
  185. package/dist/hud/elements/call-counts.js +7 -6
  186. package/dist/hud/elements/call-counts.js.map +1 -1
  187. package/dist/hud/elements/context.d.ts +3 -3
  188. package/dist/hud/elements/context.d.ts.map +1 -1
  189. package/dist/hud/elements/context.js +5 -4
  190. package/dist/hud/elements/context.js.map +1 -1
  191. package/dist/hud/elements/enterprise-cost.d.ts +16 -0
  192. package/dist/hud/elements/enterprise-cost.d.ts.map +1 -0
  193. package/dist/hud/elements/enterprise-cost.js +63 -0
  194. package/dist/hud/elements/enterprise-cost.js.map +1 -0
  195. package/dist/hud/elements/git.d.ts +2 -1
  196. package/dist/hud/elements/git.d.ts.map +1 -1
  197. package/dist/hud/elements/git.js +7 -6
  198. package/dist/hud/elements/git.js.map +1 -1
  199. package/dist/hud/elements/permission.d.ts.map +1 -1
  200. package/dist/hud/elements/permission.js +2 -5
  201. package/dist/hud/elements/permission.js.map +1 -1
  202. package/dist/hud/elements/ralph.d.ts +2 -2
  203. package/dist/hud/elements/ralph.d.ts.map +1 -1
  204. package/dist/hud/elements/ralph.js +3 -2
  205. package/dist/hud/elements/ralph.js.map +1 -1
  206. package/dist/hud/elements/session.d.ts.map +1 -1
  207. package/dist/hud/elements/session.js +5 -9
  208. package/dist/hud/elements/session.js.map +1 -1
  209. package/dist/hud/elements/thinking.d.ts +2 -2
  210. package/dist/hud/elements/thinking.d.ts.map +1 -1
  211. package/dist/hud/elements/thinking.js +3 -2
  212. package/dist/hud/elements/thinking.js.map +1 -1
  213. package/dist/hud/elements/token-usage.d.ts +2 -2
  214. package/dist/hud/elements/token-usage.d.ts.map +1 -1
  215. package/dist/hud/elements/token-usage.js +3 -2
  216. package/dist/hud/elements/token-usage.js.map +1 -1
  217. package/dist/hud/index.d.ts.map +1 -1
  218. package/dist/hud/index.js +5 -1
  219. package/dist/hud/index.js.map +1 -1
  220. package/dist/hud/render.d.ts.map +1 -1
  221. package/dist/hud/render.js +43 -10
  222. package/dist/hud/render.js.map +1 -1
  223. package/dist/hud/state.d.ts.map +1 -1
  224. package/dist/hud/state.js +18 -1
  225. package/dist/hud/state.js.map +1 -1
  226. package/dist/hud/stdin.d.ts.map +1 -1
  227. package/dist/hud/stdin.js +49 -5
  228. package/dist/hud/stdin.js.map +1 -1
  229. package/dist/hud/types.d.ts +42 -0
  230. package/dist/hud/types.d.ts.map +1 -1
  231. package/dist/hud/types.js +59 -1
  232. package/dist/hud/types.js.map +1 -1
  233. package/dist/hud/usage-api.d.ts +19 -1
  234. package/dist/hud/usage-api.d.ts.map +1 -1
  235. package/dist/hud/usage-api.js +101 -18
  236. package/dist/hud/usage-api.js.map +1 -1
  237. package/dist/installer/__tests__/hud-cache-wrapper.test.d.ts +2 -0
  238. package/dist/installer/__tests__/hud-cache-wrapper.test.d.ts.map +1 -0
  239. package/dist/installer/__tests__/hud-cache-wrapper.test.js +235 -0
  240. package/dist/installer/__tests__/hud-cache-wrapper.test.js.map +1 -0
  241. package/dist/installer/__tests__/standalone-hook-reconcile.test.js +2 -0
  242. package/dist/installer/__tests__/standalone-hook-reconcile.test.js.map +1 -1
  243. package/dist/installer/index.d.ts +1 -0
  244. package/dist/installer/index.d.ts.map +1 -1
  245. package/dist/installer/index.js +83 -31
  246. package/dist/installer/index.js.map +1 -1
  247. package/dist/lib/__tests__/worktree-paths.test.js +162 -39
  248. package/dist/lib/__tests__/worktree-paths.test.js.map +1 -1
  249. package/dist/lib/worktree-paths.d.ts +87 -9
  250. package/dist/lib/worktree-paths.d.ts.map +1 -1
  251. package/dist/lib/worktree-paths.js +209 -27
  252. package/dist/lib/worktree-paths.js.map +1 -1
  253. package/dist/mcp/__tests__/team-server-artifact-convergence.test.js +156 -4
  254. package/dist/mcp/__tests__/team-server-artifact-convergence.test.js.map +1 -1
  255. package/dist/mcp/omc-tools-server.d.ts +11 -17
  256. package/dist/mcp/omc-tools-server.d.ts.map +1 -1
  257. package/dist/mcp/omc-tools-server.js +22 -32
  258. package/dist/mcp/omc-tools-server.js.map +1 -1
  259. package/dist/mcp/team-job-convergence.d.ts +9 -2
  260. package/dist/mcp/team-job-convergence.d.ts.map +1 -1
  261. package/dist/mcp/team-job-convergence.js +35 -14
  262. package/dist/mcp/team-job-convergence.js.map +1 -1
  263. package/dist/mcp/team-server.d.ts.map +1 -1
  264. package/dist/mcp/team-server.js +93 -13
  265. package/dist/mcp/team-server.js.map +1 -1
  266. package/dist/ralphthon/prd.d.ts.map +1 -1
  267. package/dist/ralphthon/prd.js +13 -17
  268. package/dist/ralphthon/prd.js.map +1 -1
  269. package/dist/shared/types.d.ts +2 -0
  270. package/dist/shared/types.d.ts.map +1 -1
  271. package/dist/team/__tests__/api-interop.cleanup.test.d.ts +2 -0
  272. package/dist/team/__tests__/api-interop.cleanup.test.d.ts.map +1 -0
  273. package/dist/team/__tests__/api-interop.cleanup.test.js +234 -0
  274. package/dist/team/__tests__/api-interop.cleanup.test.js.map +1 -0
  275. package/dist/team/__tests__/api-interop.dispatch.test.js +2 -1
  276. package/dist/team/__tests__/api-interop.dispatch.test.js.map +1 -1
  277. package/dist/team/__tests__/auto-merge-restart.test.d.ts +2 -0
  278. package/dist/team/__tests__/auto-merge-restart.test.d.ts.map +1 -0
  279. package/dist/team/__tests__/auto-merge-restart.test.js +128 -0
  280. package/dist/team/__tests__/auto-merge-restart.test.js.map +1 -0
  281. package/dist/team/__tests__/auto-merge.perf.test.d.ts +2 -0
  282. package/dist/team/__tests__/auto-merge.perf.test.d.ts.map +1 -0
  283. package/dist/team/__tests__/auto-merge.perf.test.js +85 -0
  284. package/dist/team/__tests__/auto-merge.perf.test.js.map +1 -0
  285. package/dist/team/__tests__/conflict-mailbox.test.d.ts +2 -0
  286. package/dist/team/__tests__/conflict-mailbox.test.d.ts.map +1 -0
  287. package/dist/team/__tests__/conflict-mailbox.test.js +238 -0
  288. package/dist/team/__tests__/conflict-mailbox.test.js.map +1 -0
  289. package/dist/team/__tests__/git-worktree.test.js +164 -3
  290. package/dist/team/__tests__/git-worktree.test.js.map +1 -1
  291. package/dist/team/__tests__/helpers/git-fixture.d.ts +72 -0
  292. package/dist/team/__tests__/helpers/git-fixture.d.ts.map +1 -0
  293. package/dist/team/__tests__/helpers/git-fixture.js +252 -0
  294. package/dist/team/__tests__/helpers/git-fixture.js.map +1 -0
  295. package/dist/team/__tests__/leader-inbox.test.d.ts +2 -0
  296. package/dist/team/__tests__/leader-inbox.test.d.ts.map +1 -0
  297. package/dist/team/__tests__/leader-inbox.test.js +152 -0
  298. package/dist/team/__tests__/leader-inbox.test.js.map +1 -0
  299. package/dist/team/__tests__/merge-orchestrator.test.d.ts +2 -0
  300. package/dist/team/__tests__/merge-orchestrator.test.d.ts.map +1 -0
  301. package/dist/team/__tests__/merge-orchestrator.test.js +779 -0
  302. package/dist/team/__tests__/merge-orchestrator.test.js.map +1 -0
  303. package/dist/team/__tests__/model-contract.test.js +35 -21
  304. package/dist/team/__tests__/model-contract.test.js.map +1 -1
  305. package/dist/team/__tests__/rebase-smoke.test.d.ts +2 -0
  306. package/dist/team/__tests__/rebase-smoke.test.d.ts.map +1 -0
  307. package/dist/team/__tests__/rebase-smoke.test.js +272 -0
  308. package/dist/team/__tests__/rebase-smoke.test.js.map +1 -0
  309. package/dist/team/__tests__/runtime-cli.test.js +11 -3
  310. package/dist/team/__tests__/runtime-cli.test.js.map +1 -1
  311. package/dist/team/__tests__/runtime-prompt-mode.test.js +14 -16
  312. package/dist/team/__tests__/runtime-prompt-mode.test.js.map +1 -1
  313. package/dist/team/__tests__/runtime-v2-role-routing.test.js +7 -1
  314. package/dist/team/__tests__/runtime-v2-role-routing.test.js.map +1 -1
  315. package/dist/team/__tests__/runtime-v2.dispatch.test.js +293 -15
  316. package/dist/team/__tests__/runtime-v2.dispatch.test.js.map +1 -1
  317. package/dist/team/__tests__/runtime-v2.monitor.test.d.ts +2 -0
  318. package/dist/team/__tests__/runtime-v2.monitor.test.d.ts.map +1 -0
  319. package/dist/team/__tests__/runtime-v2.monitor.test.js +219 -0
  320. package/dist/team/__tests__/runtime-v2.monitor.test.js.map +1 -0
  321. package/dist/team/__tests__/runtime-v2.shutdown.test.d.ts +2 -0
  322. package/dist/team/__tests__/runtime-v2.shutdown.test.d.ts.map +1 -0
  323. package/dist/team/__tests__/runtime-v2.shutdown.test.js +292 -0
  324. package/dist/team/__tests__/runtime-v2.shutdown.test.js.map +1 -0
  325. package/dist/team/__tests__/scaling-launch-config.test.js +203 -3
  326. package/dist/team/__tests__/scaling-launch-config.test.js.map +1 -1
  327. package/dist/team/__tests__/team-summary-worktree.test.d.ts +2 -0
  328. package/dist/team/__tests__/team-summary-worktree.test.d.ts.map +1 -0
  329. package/dist/team/__tests__/team-summary-worktree.test.js +85 -0
  330. package/dist/team/__tests__/team-summary-worktree.test.js.map +1 -0
  331. package/dist/team/__tests__/teardown-invariant.test.d.ts +2 -0
  332. package/dist/team/__tests__/teardown-invariant.test.d.ts.map +1 -0
  333. package/dist/team/__tests__/teardown-invariant.test.js +176 -0
  334. package/dist/team/__tests__/teardown-invariant.test.js.map +1 -0
  335. package/dist/team/__tests__/tmux-session-liveness.test.d.ts +2 -0
  336. package/dist/team/__tests__/tmux-session-liveness.test.d.ts.map +1 -0
  337. package/dist/team/__tests__/tmux-session-liveness.test.js +37 -0
  338. package/dist/team/__tests__/tmux-session-liveness.test.js.map +1 -0
  339. package/dist/team/__tests__/worker-bootstrap.test.js +47 -1
  340. package/dist/team/__tests__/worker-bootstrap.test.js.map +1 -1
  341. package/dist/team/__tests__/worker-commit-cadence.test.d.ts +2 -0
  342. package/dist/team/__tests__/worker-commit-cadence.test.d.ts.map +1 -0
  343. package/dist/team/__tests__/worker-commit-cadence.test.js +315 -0
  344. package/dist/team/__tests__/worker-commit-cadence.test.js.map +1 -0
  345. package/dist/team/__tests__/worktree-contract-fields.test.d.ts +2 -0
  346. package/dist/team/__tests__/worktree-contract-fields.test.d.ts.map +1 -0
  347. package/dist/team/__tests__/worktree-contract-fields.test.js +157 -0
  348. package/dist/team/__tests__/worktree-contract-fields.test.js.map +1 -0
  349. package/dist/team/__tests__/worktree-runtime-e2e.test.d.ts +2 -0
  350. package/dist/team/__tests__/worktree-runtime-e2e.test.d.ts.map +1 -0
  351. package/dist/team/__tests__/worktree-runtime-e2e.test.js +182 -0
  352. package/dist/team/__tests__/worktree-runtime-e2e.test.js.map +1 -0
  353. package/dist/team/api-interop.d.ts +2 -1
  354. package/dist/team/api-interop.d.ts.map +1 -1
  355. package/dist/team/api-interop.js +121 -14
  356. package/dist/team/api-interop.js.map +1 -1
  357. package/dist/team/capabilities.d.ts.map +1 -1
  358. package/dist/team/capabilities.js +2 -0
  359. package/dist/team/capabilities.js.map +1 -1
  360. package/dist/team/cli-worker-contract.d.ts +7 -6
  361. package/dist/team/cli-worker-contract.d.ts.map +1 -1
  362. package/dist/team/cli-worker-contract.js +7 -6
  363. package/dist/team/cli-worker-contract.js.map +1 -1
  364. package/dist/team/conflict-mailbox.d.ts +49 -0
  365. package/dist/team/conflict-mailbox.d.ts.map +1 -0
  366. package/dist/team/conflict-mailbox.js +98 -0
  367. package/dist/team/conflict-mailbox.js.map +1 -0
  368. package/dist/team/events.d.ts +3 -0
  369. package/dist/team/events.d.ts.map +1 -1
  370. package/dist/team/events.js +2 -1
  371. package/dist/team/events.js.map +1 -1
  372. package/dist/team/git-worktree.d.ts +78 -10
  373. package/dist/team/git-worktree.d.ts.map +1 -1
  374. package/dist/team/git-worktree.js +453 -97
  375. package/dist/team/git-worktree.js.map +1 -1
  376. package/dist/team/governance.d.ts +3 -2
  377. package/dist/team/governance.d.ts.map +1 -1
  378. package/dist/team/governance.js.map +1 -1
  379. package/dist/team/leader-inbox.d.ts +28 -0
  380. package/dist/team/leader-inbox.d.ts.map +1 -0
  381. package/dist/team/leader-inbox.js +68 -0
  382. package/dist/team/leader-inbox.js.map +1 -0
  383. package/dist/team/merge-coordinator.d.ts +6 -0
  384. package/dist/team/merge-coordinator.d.ts.map +1 -1
  385. package/dist/team/merge-coordinator.js +6 -2
  386. package/dist/team/merge-coordinator.js.map +1 -1
  387. package/dist/team/merge-orchestrator.d.ts +41 -0
  388. package/dist/team/merge-orchestrator.d.ts.map +1 -0
  389. package/dist/team/merge-orchestrator.js +736 -0
  390. package/dist/team/merge-orchestrator.js.map +1 -0
  391. package/dist/team/model-contract.d.ts +18 -2
  392. package/dist/team/model-contract.d.ts.map +1 -1
  393. package/dist/team/model-contract.js +55 -28
  394. package/dist/team/model-contract.js.map +1 -1
  395. package/dist/team/monitor.d.ts.map +1 -1
  396. package/dist/team/monitor.js +47 -3
  397. package/dist/team/monitor.js.map +1 -1
  398. package/dist/team/runtime-cli.d.ts +1 -0
  399. package/dist/team/runtime-cli.d.ts.map +1 -1
  400. package/dist/team/runtime-cli.js +15 -2
  401. package/dist/team/runtime-cli.js.map +1 -1
  402. package/dist/team/runtime-flags.d.ts +5 -0
  403. package/dist/team/runtime-flags.d.ts.map +1 -0
  404. package/dist/team/runtime-flags.js +12 -0
  405. package/dist/team/runtime-flags.js.map +1 -0
  406. package/dist/team/runtime-v2.d.ts +16 -1
  407. package/dist/team/runtime-v2.d.ts.map +1 -1
  408. package/dist/team/runtime-v2.js +531 -127
  409. package/dist/team/runtime-v2.js.map +1 -1
  410. package/dist/team/runtime.d.ts.map +1 -1
  411. package/dist/team/runtime.js +4 -1
  412. package/dist/team/runtime.js.map +1 -1
  413. package/dist/team/scaling.d.ts.map +1 -1
  414. package/dist/team/scaling.js +110 -13
  415. package/dist/team/scaling.js.map +1 -1
  416. package/dist/team/state/tasks.d.ts.map +1 -1
  417. package/dist/team/state/tasks.js +1 -0
  418. package/dist/team/state/tasks.js.map +1 -1
  419. package/dist/team/team-ops.d.ts.map +1 -1
  420. package/dist/team/team-ops.js +112 -16
  421. package/dist/team/team-ops.js.map +1 -1
  422. package/dist/team/tmux-session.d.ts +17 -29
  423. package/dist/team/tmux-session.d.ts.map +1 -1
  424. package/dist/team/tmux-session.js +117 -108
  425. package/dist/team/tmux-session.js.map +1 -1
  426. package/dist/team/types.d.ts +31 -17
  427. package/dist/team/types.d.ts.map +1 -1
  428. package/dist/team/types.js.map +1 -1
  429. package/dist/team/worker-bootstrap.d.ts +11 -0
  430. package/dist/team/worker-bootstrap.d.ts.map +1 -1
  431. package/dist/team/worker-bootstrap.js +37 -14
  432. package/dist/team/worker-bootstrap.js.map +1 -1
  433. package/dist/team/worker-canonicalization.d.ts.map +1 -1
  434. package/dist/team/worker-canonicalization.js +2 -0
  435. package/dist/team/worker-canonicalization.js.map +1 -1
  436. package/dist/team/worker-commit-cadence.d.ts +70 -0
  437. package/dist/team/worker-commit-cadence.d.ts.map +1 -0
  438. package/dist/team/worker-commit-cadence.js +271 -0
  439. package/dist/team/worker-commit-cadence.js.map +1 -0
  440. package/dist/tools/__tests__/memory-tools.test.js +4 -4
  441. package/dist/tools/__tests__/memory-tools.test.js.map +1 -1
  442. package/dist/tools/__tests__/state-tools.test.js +13 -1
  443. package/dist/tools/__tests__/state-tools.test.js.map +1 -1
  444. package/dist/utils/frontmatter.d.ts.map +1 -1
  445. package/dist/utils/frontmatter.js +1 -16
  446. package/dist/utils/frontmatter.js.map +1 -1
  447. package/dist/utils/resolve-node.d.ts.map +1 -1
  448. package/dist/utils/resolve-node.js +22 -28
  449. package/dist/utils/resolve-node.js.map +1 -1
  450. package/docs/GETTING-STARTED.md +415 -0
  451. package/docs/MIGRATION.md +1003 -0
  452. package/docs/REFERENCE.md +21 -4
  453. package/docs/TEAM-WORKTREE-MODE.md +86 -0
  454. package/docs/company-context-interface.md +5 -16
  455. package/docs/copilot-instructions.md +1 -1
  456. package/package.json +1 -1
  457. package/scripts/keyword-detector.mjs +168 -20
  458. package/scripts/lib/hud-cache-wrapper.sh +122 -0
  459. package/scripts/persistent-mode.cjs +28 -2
  460. package/scripts/persistent-mode.mjs +28 -2
  461. package/scripts/plugin-setup.mjs +10 -1
  462. package/scripts/post-tool-verifier.mjs +153 -3
  463. package/scripts/pre-tool-enforcer.mjs +54 -6
  464. package/scripts/session-start.mjs +194 -2
  465. package/skills/AGENTS.md +22 -91
  466. package/skills/ai-slop-cleaner/SKILL.md +118 -120
  467. package/skills/ask/SKILL.md +6 -8
  468. package/skills/autopilot/SKILL.md +1 -28
  469. package/skills/autoresearch/SKILL.md +5 -5
  470. package/skills/cancel/SKILL.md +13 -13
  471. package/skills/cccg/SKILL.md +1 -0
  472. package/skills/configure-notifications/SKILL.md +80 -215
  473. package/skills/debug/SKILL.md +3 -2
  474. package/skills/deep-dive/SKILL.md +20 -9
  475. package/skills/deep-interview/SKILL.md +32 -4
  476. package/skills/deepinit/SKILL.md +1 -0
  477. package/skills/external-context/SKILL.md +2 -1
  478. package/skills/hud/SKILL.md +22 -52
  479. package/skills/learner/SKILL.md +90 -57
  480. package/skills/mcp-setup/SKILL.md +45 -60
  481. package/skills/omc-doctor/SKILL.md +1 -1
  482. package/skills/omc-reference/SKILL.md +6 -6
  483. package/skills/omc-setup/SKILL.md +30 -74
  484. package/skills/omc-setup/phases/01-install-claude-md.md +97 -0
  485. package/skills/omc-setup/phases/02-configure.md +25 -40
  486. package/skills/omc-setup/phases/03-integrations.md +100 -69
  487. package/skills/omc-setup/phases/04-welcome.md +102 -44
  488. package/skills/omc-teams/SKILL.md +63 -26
  489. package/skills/plan/SKILL.md +11 -9
  490. package/skills/ralph/SKILL.md +42 -41
  491. package/skills/ralplan/SKILL.md +3 -10
  492. package/skills/release/SKILL.md +168 -57
  493. package/skills/remember/SKILL.md +2 -1
  494. package/skills/sciomc/SKILL.md +12 -11
  495. package/skills/self-improve/SKILL.md +4 -4
  496. package/skills/setup/SKILL.md +1 -0
  497. package/skills/skill/SKILL.md +21 -20
  498. package/skills/skillify/SKILL.md +34 -3
  499. package/skills/team/SKILL.md +62 -44
  500. package/skills/ultraqa/SKILL.md +1 -2
  501. package/skills/ultrawork/SKILL.md +28 -21
  502. package/skills/verify/SKILL.md +2 -1
  503. package/skills/writer-memory/SKILL.md +2 -1
  504. package/templates/hooks/keyword-detector.mjs +129 -11
  505. package/templates/hooks/persistent-mode.mjs +28 -2
  506. package/templates/hooks/pre-tool-use.mjs +144 -45
  507. package/templates/hooks/session-start.mjs +25 -1
package/docs/REFERENCE.md CHANGED
@@ -12,7 +12,7 @@ Complete reference for oh-my-copilot. For quick start, see the main [README.md](
12
12
  - [CLI Commands: ask/team/session](#cli-commands-askteamsession)
13
13
  - [Legacy MCP Team Runtime Tools (Deprecated)](#legacy-mcp-team-runtime-tools-deprecated)
14
14
  - [Agents (29 Total)](#agents-29-total)
15
- - [Skills (35 Total)](#skills-35-total)
15
+ - [Skills (36 Total)](#skills-36-total)
16
16
  - [Slash Commands](#slash-commands)
17
17
  - [Hooks System](#hooks-system)
18
18
  - [Magic Keywords](#magic-keywords)
@@ -520,9 +520,9 @@ Always use `oh-my-copilot:` prefix when calling via Task tool.
520
520
 
521
521
  ---
522
522
 
523
- ## Skills (35 Total)
523
+ ## Skills (36 Total)
524
524
 
525
- Includes **34 canonical skills + 1 deprecated alias** (`psm`). Runtime truth comes from the builtin skill loader scanning `skills/*/SKILL.md` and expanding aliases declared in frontmatter.
525
+ Includes **34 canonical skills + 2 deprecated aliases** (`learner`, `psm`). Runtime truth comes from the builtin skill loader scanning `skills/*/SKILL.md` and expanding aliases declared in frontmatter.
526
526
 
527
527
  | Skill | Description | Manual Command |
528
528
  | ------------------------- | ---------------------------------------------------------------- | ------------------------------------------- |
@@ -900,12 +900,29 @@ Configure HUD elements in `~/.claude/settings.json`:
900
900
  | `autopilot` | Show autopilot status | `true` |
901
901
  | `showTokens` | Show transcript-derived token usage (`tok:i1.2k/o340`, plus `r...` reasoning and `s...` session total when reliable) | `false` |
902
902
 
903
- Additional `omcHud` layout options (top-level):
903
+ Additional `omcHud` layout and label options (top-level):
904
904
 
905
905
  | Option | Description | Default |
906
906
  | ---------- | --------------------------------------------------------------------------------- | ---------- |
907
907
  | `maxWidth` | Maximum HUD line width (terminal columns) | unset |
908
908
  | `wrapMode` | `truncate` (ellipsis) or `wrap` (break at `\|` boundaries) when `maxWidth` is set | `truncate` |
909
+ | `locale` | HUD label preset. Supported values: `en`, `zh-CN` | `en` |
910
+ | `labels` | Per-label HUD text overrides; supported keys only | unset |
911
+
912
+ `locale` and `labels` affect only HUD labels. English remains the default, unsupported locale values and unknown label keys are ignored, and explicit `labels` override the locale preset. Supported label keys are `context`, `tokens`, `tool`, `agent`, `skill`, `ralph`, `background`, `thinking`, `staged`, `modified`, `untracked`, `ahead`, and `behind`.
913
+
914
+ Example:
915
+
916
+ ```json
917
+ {
918
+ "omcHud": {
919
+ "locale": "zh-CN",
920
+ "labels": {
921
+ "context": "CTX"
922
+ }
923
+ }
924
+ }
925
+ ```
909
926
 
910
927
  Available presets: `minimal`, `focused`, `full`, `dense`, `analytics`, `opencode`
911
928
 
@@ -0,0 +1,86 @@
1
+ # Native Team Worktree Mode
2
+
3
+ Native team worktree mode is the opt-in rollout path for running `omc team` workers in dedicated git worktrees while keeping one leader-owned team-specific coordination root. It is intended for runtime-v2 team sessions and is designed to make worker edits isolated without fragmenting task, mailbox, status, or manifest state.
4
+
5
+ ## Availability
6
+
7
+ - The rollout is **opt-in / config-gated** for the first slice. Do not assume worktree mode is the default behavior.
8
+ - The target runtime is `runtime-v2`. Legacy `runtime.ts` remains limited to read/status and cleanup compatibility unless a later plan explicitly expands it.
9
+ - No new dependency is required; lifecycle operations use git worktrees plus the existing team CLI/API surfaces.
10
+
11
+ ## Workspace contract
12
+
13
+ When worktree mode is active, OMC uses this stable layout:
14
+
15
+ | Field | Contract |
16
+ | --- | --- |
17
+ | Worktree root | `<repo>/.omc/team/<team-name>/worktrees/<worker-name>` |
18
+ | Team-specific coordination root | `<repo>/.omc/state/team/<team-name>` in the leader workspace |
19
+ | Worker cwd | The worker's `worktree_path` |
20
+ | Worker coordination | `OMC_TEAM_STATE_ROOT` points back to the team-specific leader-owned coordination root |
21
+ | Worker instructions | Worktree-root `AGENTS.md` is installed with backup/restore safeguards |
22
+
23
+ Workers must keep using `omc team api ...` lifecycle and mailbox operations against the team-specific coordination root. They must not create or mutate a separate local `.omc/state` inside their worker worktree when `OMC_TEAM_STATE_ROOT` is available; for worktree-backed workers it should point at `<repo>/.omc/state/team/<team-name>`.
24
+
25
+ ## Persisted fields
26
+
27
+ Config, manifest, worker identity, and status surfaces should expose the same locked field set so resume/status/bootstrap paths can reason about worker location without inference:
28
+
29
+ - `workspace_mode`
30
+ - `worktree_mode`
31
+ - `team_state_root`
32
+ - `working_dir`
33
+ - `worktree_repo_root`
34
+ - `worktree_path`
35
+ - `worktree_branch`
36
+ - `worktree_detached`
37
+ - `worktree_created`
38
+
39
+ `workspace_mode` should be `worktree` for worktree-backed sessions and `single` for the existing shared-workspace behavior. `team_state_root` means the team-specific coordination root (`<repo>/.omc/state/team/<team-name>`); if a future feature needs the broader `.omc/state` base, use a separately named field such as `state_base_root`.
40
+
41
+ ## Safety rules
42
+
43
+ - OMC must check the leader workspace before provisioning worktrees. If the leader repo is dirty, startup should refuse worktree provisioning rather than copying an unsafe base state.
44
+ - Existing compatible clean worker worktrees may be reused.
45
+ - Dirty worker worktrees must be preserved and surfaced as warnings/events. Cleanup must not force-remove dirty worker edits.
46
+ - Branch/path mismatches should fail instead of reusing the wrong workspace.
47
+ - Rollback may remove newly created clean worktrees and runtime-created branches when safe; reused worktrees are preserved.
48
+ - `orphan-cleanup` is a destructive escape hatch that may delete worktree recovery metadata and root `AGENTS.md` backups. When that evidence exists, callers must pass `acknowledge_lost_worktree_recovery: true` only after manually preserving or intentionally discarding the affected worker worktrees/backups.
49
+
50
+ ## CLI and status expectations
51
+
52
+ `omc team status <team-name> --json` should make the workspace contract observable. JSON consumers should be able to find `workspace_mode`, `worktree_mode`, `team_state_root`, and each worker's worktree metadata without reading private files directly.
53
+
54
+ Human status output should also surface the mode and worktree path/branch details enough for users to understand where worker changes live and whether cleanup preserved a dirty worktree.
55
+
56
+ ## Verification checklist for changes
57
+
58
+ Use the source PRD/test-spec checklist when modifying this area. At minimum, changes should cover:
59
+
60
+ 1. Worktree planning disabled/no-op and active path modes.
61
+ 2. Fresh, reused, dirty, and mismatched worktree lifecycle cases.
62
+ 3. Runtime-v2 startup/spawn state: worker cwd, env, config, manifest, and identity all agree.
63
+ 4. Bootstrap prompts and trigger paths use `$OMC_TEAM_STATE_ROOT` for worktree-backed workers.
64
+ 5. Scale-up workers inherit the same team-specific coordination root and worktree instruction strategy.
65
+ 6. Shutdown/cleanup removes safe clean worktrees, preserves dirty ones, and reports warnings.
66
+ 7. CLI help/status tests cover the opt-in rollout and locked status field set.
67
+
68
+ Recommended focused commands:
69
+
70
+ ```bash
71
+ npm test -- --run src/team/__tests__/git-worktree.test.ts
72
+ npm test -- --run src/team/__tests__/worker-bootstrap.test.ts
73
+ npm test -- --run src/team/__tests__/runtime-v2.dispatch.test.ts
74
+ npm test -- --run src/team/__tests__/runtime-v2.shutdown.test.ts
75
+ npm test -- --run src/team/__tests__/api-interop.dispatch.test.ts
76
+ npm test -- --run src/team/__tests__/api-interop.cwd-resolution.test.ts
77
+ npm test -- --run src/team/__tests__/scaling-launch-config.test.ts
78
+ npm test -- --run src/cli/__tests__/team-runtime-boundary.test.ts
79
+ npm run build
80
+ ```
81
+
82
+ ## Review notes
83
+
84
+ - Keep the first slice narrow: runtime-v2 startup/spawn/dispatch/scale-up/resume/status/shutdown/cleanup plus legacy read/cleanup compatibility.
85
+ - Do not reduce scope by omitting status visibility, dirty-worktree preservation, or team-specific coordination-root behavior; those are part of the locked contract.
86
+ - Prefer explicit persisted fields over reconstructing worktree state from paths or branch names.
@@ -2,12 +2,6 @@
2
2
 
3
3
  OMC supports a narrow, prompt-level contract for vendor-owned company context.
4
4
 
5
- This contract is aimed at a specific failure mode from upstream issue #2692:
6
- purely prompt-directive company-context guidance is still missed in practice
7
- roughly 5% of the time. Making the lookup an explicit configured tool call
8
- materially reduces that miss mode at the spec layer without changing OMC
9
- runtime behavior.
10
-
11
5
  This is **not** a runtime enforcement feature. It gives OMC workflows:
12
6
 
13
7
  - a consistent tool shape,
@@ -52,8 +46,8 @@ OMC skill clauses should treat the returned markdown the same way `deep-dive` tr
52
46
 
53
47
  Configure the contract in the standard OMC config surface:
54
48
 
55
- - Project: `.copilot/omg.jsonc`
56
- - User: `~/.config/copilot-omg/config.jsonc`
49
+ - Project: `.claude/omc.jsonc`
50
+ - User: `~/.config/claude-omc/config.jsonc`
57
51
 
58
52
  Project config overrides user config.
59
53
 
@@ -98,23 +92,18 @@ Each skill should build a `query` that summarizes the current task, current stag
98
92
 
99
93
  The company-context server itself is still registered through the normal MCP surfaces:
100
94
 
101
- - Copilot CLI MCP configuration / `copilot mcp add ...`
95
+ - Claude MCP configuration / `claude mcp add ...`
102
96
  - the unified MCP registry that OMC syncs to Codex
103
97
 
104
98
  This contract does not change how MCP servers are registered.
105
99
 
106
100
  For a tiny runnable reference implementation, see:
107
101
 
108
- - [`examples/vendor-mcp-server/README.md`](../examples/vendor-mcp-server/README.md)
102
+ - [`examples/vendor-mcp-server/README.md`](/mnt/offloading/Workspace/oh-my-claudecode.omx-worktrees/issue-2692-company-context-mcp-interface/examples/vendor-mcp-server/README.md)
109
103
 
110
104
  ## Residual Risk
111
105
 
112
- This interface addresses the observed ~5% prompt-directive miss mode by making
113
- the company-context lookup explicit, but it still operates at the skill-prompt
114
- layer. The documented MUST-call clauses should meaningfully reduce that miss
115
- rate, yet they do **not** guarantee a 0% miss rate or mathematically perfect
116
- invocation. If you need deterministic invocation, that would require a separate
117
- runtime enforcement design.
106
+ This interface makes the contract explicit and lowers prompt drift, but it still operates at the skill-prompt layer. If you need guaranteed invocation, that would require a separate runtime enforcement design.
118
107
 
119
108
  ## Non-Goals
120
109
 
@@ -1,5 +1,5 @@
1
1
  <!-- OMC:START -->
2
- <!-- OMC:VERSION:4.13.1 -->
2
+ <!-- OMC:VERSION:4.13.21 -->
3
3
 
4
4
  # oh-my-copilot - Intelligent Multi-Agent Orchestration
5
5
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oh-my-copilot",
3
- "version": "4.13.1",
3
+ "version": "4.13.21",
4
4
  "description": "Multi-agent orchestration system for Copilot CLI - Inspired by oh-my-opencode",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -28,6 +28,7 @@ import { join, dirname } from 'path';
28
28
  import { homedir } from 'os';
29
29
  import { fileURLToPath } from 'url';
30
30
  import { getClaudeConfigDir } from './lib/config-dir.mjs';
31
+ import { atomicWriteFileSync } from './lib/atomic-write.mjs';
31
32
  import { readStdin } from './lib/stdin.mjs';
32
33
 
33
34
  // Resolve OMC package root: PLUGIN_ROOT (plugin system) or derive from this script's location
@@ -359,6 +360,119 @@ const QUESTION_FOLLOWUP_PATTERNS = [
359
360
  /\b(?:how\s+many|how\s+much|why|what\s+happened|what\s+went\s+wrong|token\s+budget|cost|pricing)\b/i,
360
361
  /(?:왜|얼마|몇\s*번|몇번|토큰|가격|비용|질문)/u,
361
362
  ];
363
+
364
+ // Patterns that identify system-generated echoes (hook outputs) which can be
365
+ // pasted back into the prompt verbatim. If a mode keyword only appears inside
366
+ // such an echo block we MUST NOT re-activate the mode: otherwise a user who
367
+ // copies a "[RALPH LOOP - ITERATION N] ..." block into a new session to debug
368
+ // it will unintentionally re-trigger ralph, and the pasted text ends up as
369
+ // the new state.prompt — producing a recursive self-reinforcing loop.
370
+ // Continuation lines that hook output typically emits DIRECTLY after a
371
+ // recognized block header. They must be stripped only in that context —
372
+ // never standalone — because a user might legitimately start a prompt with
373
+ // "Task: …" or similar (Codex automated review P1/P2 on #2795).
374
+ const ECHO_CONTINUATION = '(?:\\r?\\n[ \\t]*(?:Task:\\s|When FULLY complete \\(after Architect verification\\)|run\\s+\\/oh-my-(?:claudecode|codex|copilot):cancel).*)*';
375
+
376
+ // NOTE: each pattern is a SINGLE LOGICAL BLOCK: the block header line +
377
+ // zero-or-more continuation lines that hooks emit right after it. The whole
378
+ // match is stripped together. Both `i` (case-insensitive against the
379
+ // lower-cased cleanPrompt upstream) and `m` (so `^`/`$` match line
380
+ // boundaries) are required.
381
+ function buildEchoBlockRegex(headerBody) {
382
+ return new RegExp(`^[ \\t]*${headerBody}.*${ECHO_CONTINUATION}$`, 'gim');
383
+ }
384
+
385
+ const SYSTEM_ECHO_BLOCK_PATTERNS = [
386
+ // persistent-mode.mjs block headers
387
+ buildEchoBlockRegex('\\[RALPH LOOP\\s*-\\s*ITERATION[^\\]\\n]*\\]'),
388
+ buildEchoBlockRegex('\\[RALPH LOOP\\s*-\\s*(?:HARD LIMIT|EXTENDED)\\]'),
389
+ buildEchoBlockRegex('\\[TEAM\\s*-\\s*Phase:[^\\]\\n]*\\]'),
390
+ buildEchoBlockRegex('\\[AUTOPILOT[^\\]\\n]*\\]'),
391
+ buildEchoBlockRegex('\\[ULTRAPILOT[^\\]\\n]*\\]'),
392
+ buildEchoBlockRegex('\\[ULTRAWORK[^\\]\\n]*\\]'),
393
+ buildEchoBlockRegex('\\[ULTRAQA[^\\]\\n]*\\]'),
394
+ buildEchoBlockRegex('\\[PIPELINE[^\\]\\n]*\\]'),
395
+ buildEchoBlockRegex('\\[SWARM[^\\]\\n]*\\]'),
396
+ buildEchoBlockRegex('\\[TOOL ERROR[^\\]\\n]*\\]'),
397
+ // keyword-detector.mjs block headers
398
+ buildEchoBlockRegex('\\[MAGIC KEYWORD:[^\\]\\n]*\\]'),
399
+ buildEchoBlockRegex('\\[MAGIC KEYWORDS DETECTED:[^\\]\\n]*\\]'),
400
+ // Stop-hook wrapping by the Claude Code harness
401
+ buildEchoBlockRegex('Stop hook (?:blocking error|feedback|stopped continuation)'),
402
+ buildEchoBlockRegex('PreToolUse:[^\\n]*hook additional context:'),
403
+ buildEchoBlockRegex('PostToolUse:[^\\n]*hook additional context:'),
404
+ ];
405
+
406
+ // Signature lines indicating the text is predominantly a system echo. Even
407
+ // when the block patterns above fail to delimit cleanly (e.g. truncation),
408
+ // presence of these sentinels should make us treat the prompt as an echo.
409
+ // All patterns use `i` because hasActionableKeyword sees a lowercased prompt.
410
+ const SYSTEM_ECHO_SIGNATURES = [
411
+ /\bWhen FULLY complete \(after Architect verification\)\b/i,
412
+ /\brun\s+\/oh-my-(?:claudecode|codex|copilot):cancel\b/i,
413
+ /\[RALPH LOOP\s*-\s*ITERATION\b/i,
414
+ ];
415
+
416
+ const MAX_STATE_PROMPT_LEN = 500;
417
+
418
+ function stripSystemEchoes(text) {
419
+ if (typeof text !== 'string' || text.length === 0) return '';
420
+ let cleaned = text;
421
+ for (const pattern of SYSTEM_ECHO_BLOCK_PATTERNS) {
422
+ cleaned = cleaned.replace(pattern, ' ');
423
+ }
424
+ return cleaned;
425
+ }
426
+
427
+ function looksLikeSystemEcho(text) {
428
+ if (typeof text !== 'string' || text.length === 0) return false;
429
+ if (SYSTEM_ECHO_SIGNATURES.some((pattern) => pattern.test(text))) return true;
430
+ // Also treat the presence of ANY echo block pattern as an echo, so that
431
+ // mode-specific paste blocks (AUTOPILOT, ULTRAWORK, TEAM, etc.) are
432
+ // recognized without needing a dedicated signature line.
433
+ for (const pattern of SYSTEM_ECHO_BLOCK_PATTERNS) {
434
+ const probe = new RegExp(pattern.source, pattern.flags.replace('g', ''));
435
+ if (probe.test(text)) return true;
436
+ }
437
+ return false;
438
+ }
439
+
440
+ /**
441
+ * Sanitize a prompt before persisting it to a *-state.json file.
442
+ * Returning the raw prompt risks storing large system echoes or pasted
443
+ * hook output, which persistent-mode.mjs would then blast back into the
444
+ * next Stop-hook block reason on every iteration.
445
+ *
446
+ * Strategy:
447
+ * 1. Strip echoes first. If non-empty content remains AND that remainder no
448
+ * longer looks like an echo, keep it (preserves the real user request in
449
+ * an "echo + blank line + real request" paste).
450
+ * 2. Otherwise, if the raw prompt looks like a pure echo, substitute the
451
+ * placeholder sentinel.
452
+ * 3. Finally, hard-truncate to MAX_STATE_PROMPT_LEN chars.
453
+ */
454
+ function sanitizePromptForState(prompt) {
455
+ if (typeof prompt !== 'string') return '';
456
+ const trimmed = prompt.trim();
457
+ if (!trimmed) return '';
458
+
459
+ const stripped = stripSystemEchoes(trimmed).trim();
460
+ if (stripped.length > 0 && !looksLikeSystemEcho(stripped)) {
461
+ return stripped.length > MAX_STATE_PROMPT_LEN
462
+ ? `${stripped.slice(0, MAX_STATE_PROMPT_LEN - 3)}...`
463
+ : stripped;
464
+ }
465
+
466
+ if (looksLikeSystemEcho(trimmed)) {
467
+ return '(prompt omitted: pasted system echo)';
468
+ }
469
+
470
+ // Fallback (stripping left nothing but original isn't recognizably an echo)
471
+ const base = stripped.length > 0 ? stripped : trimmed;
472
+ return base.length > MAX_STATE_PROMPT_LEN
473
+ ? `${base.slice(0, MAX_STATE_PROMPT_LEN - 3)}...`
474
+ : base;
475
+ }
362
476
  const MODE_REFERENCE_PATTERN =
363
477
  /\b(?:ralph|autopilot|auto[\s-]?pilot|ultrawork|ulw|ralplan|ultrathink|deepsearch|deep[\s-]?analyze|deepanalyze|deep[\s-]interview|ouroboros|ccg|claude-codex-gemini|deerflow)\b/gi;
364
478
 
@@ -473,15 +587,25 @@ function isInformationalKeywordContext(text, position, keywordLength, keywordTex
473
587
  }
474
588
 
475
589
  function hasActionableKeyword(text, pattern) {
590
+ // Strip system-generated echo blocks (persistent-mode/keyword-detector
591
+ // outputs, Stop-hook wrappers) BEFORE searching for keywords. Otherwise
592
+ // pasting a previous "[RALPH LOOP - ITERATION N] ..." block into a prompt
593
+ // would re-activate ralph mode and the echo itself would be saved as
594
+ // state.prompt, which persistent-mode.mjs then blasts back on every
595
+ // iteration — a self-reinforcing loop that is hard to cancel.
596
+ const searchText = looksLikeSystemEcho(text)
597
+ ? stripSystemEchoes(text)
598
+ : text;
599
+
476
600
  const flags = pattern.flags.includes('g') ? pattern.flags : `${pattern.flags}g`;
477
601
  const globalPattern = new RegExp(pattern.source, flags);
478
602
 
479
- for (const match of text.matchAll(globalPattern)) {
603
+ for (const match of searchText.matchAll(globalPattern)) {
480
604
  if (match.index === undefined) {
481
605
  continue;
482
606
  }
483
607
 
484
- if (isInformationalKeywordContext(text, match.index, match[0].length, match[0])) {
608
+ if (isInformationalKeywordContext(searchText, match.index, match[0].length, match[0])) {
485
609
  continue;
486
610
  }
487
611
 
@@ -508,19 +632,26 @@ function hasExplicitInvocationContext(text, position, keywordLength, keywordText
508
632
  }
509
633
 
510
634
  function hasActionableRalplanKeyword(text, pattern) {
635
+ // Same echo guard as hasActionableKeyword.
636
+ const searchText = looksLikeSystemEcho(text)
637
+ ? stripSystemEchoes(text)
638
+ : text;
639
+
511
640
  const flags = pattern.flags.includes('g') ? pattern.flags : `${pattern.flags}g`;
512
641
  const globalPattern = new RegExp(pattern.source, flags);
513
642
 
514
- for (const match of text.matchAll(globalPattern)) {
643
+ for (const match of searchText.matchAll(globalPattern)) {
515
644
  if (match.index === undefined) {
516
645
  continue;
517
646
  }
518
647
 
519
- if (isInformationalKeywordContext(text, match.index, match[0].length, match[0])) {
648
+ // match.index is relative to searchText — use searchText for all
649
+ // downstream context lookups to keep indices aligned.
650
+ if (isInformationalKeywordContext(searchText, match.index, match[0].length, match[0])) {
520
651
  continue;
521
652
  }
522
653
 
523
- if (!hasExplicitInvocationContext(text, match.index, match[0].length, match[0])) {
654
+ if (!hasExplicitInvocationContext(searchText, match.index, match[0].length, match[0])) {
524
655
  continue;
525
656
  }
526
657
 
@@ -532,6 +663,10 @@ function hasActionableRalplanKeyword(text, pattern) {
532
663
 
533
664
  // Create state file for a mode
534
665
  function activateState(directory, prompt, stateName, sessionId) {
666
+ const now = new Date().toISOString();
667
+ // Sanitize prompt BEFORE writing to state: prevents pasted system echoes
668
+ // and oversized blobs from being persisted and re-emitted by Stop hook.
669
+ const safePrompt = sanitizePromptForState(prompt);
535
670
  let state;
536
671
 
537
672
  if (stateName === 'ralph') {
@@ -540,45 +675,51 @@ function activateState(directory, prompt, stateName, sessionId) {
540
675
  active: true,
541
676
  iteration: 1,
542
677
  max_iterations: 100,
543
- started_at: new Date().toISOString(),
544
- prompt: prompt,
678
+ started_at: now,
679
+ prompt: safePrompt,
545
680
  session_id: sessionId || undefined,
546
681
  project_path: directory,
547
682
  linked_ultrawork: true,
548
683
  awaiting_confirmation: true,
549
- last_checked_at: new Date().toISOString()
684
+ awaiting_confirmation_set_at: now,
685
+ last_checked_at: now
550
686
  };
551
687
  } else if (stateName === 'ralplan') {
552
688
  // Ralplan needs active + session_id for stop-hook enforcement
553
689
  state = {
554
690
  active: true,
555
- started_at: new Date().toISOString(),
691
+ started_at: now,
556
692
  session_id: sessionId || undefined,
557
693
  project_path: directory,
558
694
  awaiting_confirmation: true,
559
- last_checked_at: new Date().toISOString()
695
+ awaiting_confirmation_set_at: now,
696
+ last_checked_at: now
560
697
  };
561
698
  } else {
562
699
  // Generic state for ultrawork, autopilot, etc.
563
700
  state = {
564
701
  active: true,
565
- started_at: new Date().toISOString(),
566
- original_prompt: prompt,
702
+ started_at: now,
703
+ original_prompt: safePrompt,
567
704
  session_id: sessionId || undefined,
568
705
  project_path: directory,
569
706
  reinforcement_count: 0,
570
707
  awaiting_confirmation: true,
571
- last_checked_at: new Date().toISOString()
708
+ awaiting_confirmation_set_at: now,
709
+ last_checked_at: now
572
710
  };
573
711
  }
574
712
 
575
- // Write to session-scoped path if sessionId available
713
+ // Write to session-scoped path if sessionId available. Use atomic writes
714
+ // so that concurrent hook processes cannot expose half-written JSON to
715
+ // persistent-mode.mjs's readJsonFile (which would otherwise return null
716
+ // and temporarily drop mode enforcement).
576
717
  if (sessionId && /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,255}$/.test(sessionId)) {
577
718
  const sessionDir = join(directory, '.omcp', 'state', 'sessions', sessionId);
578
719
  if (!existsSync(sessionDir)) {
579
720
  try { mkdirSync(sessionDir, { recursive: true }); } catch {}
580
721
  }
581
- try { writeFileSync(join(sessionDir, `${stateName}-state.json`), JSON.stringify(state, null, 2), { mode: 0o600 }); } catch {}
722
+ try { atomicWriteFileSync(join(sessionDir, `${stateName}-state.json`), JSON.stringify(state, null, 2)); } catch {}
582
723
  return;
583
724
  }
584
725
 
@@ -587,7 +728,7 @@ function activateState(directory, prompt, stateName, sessionId) {
587
728
  if (!existsSync(localDir)) {
588
729
  try { mkdirSync(localDir, { recursive: true }); } catch {}
589
730
  }
590
- try { writeFileSync(join(localDir, `${stateName}-state.json`), JSON.stringify(state, null, 2), { mode: 0o600 }); } catch {}
731
+ try { atomicWriteFileSync(join(localDir, `${stateName}-state.json`), JSON.stringify(state, null, 2)); } catch {}
591
732
  }
592
733
 
593
734
  function activateRalplanStartupState(directory, prompt, sessionId) {
@@ -596,7 +737,7 @@ function activateRalplanStartupState(directory, prompt, sessionId) {
596
737
  active: true,
597
738
  started_at: now,
598
739
  current_phase: 'ralplan',
599
- original_prompt: prompt,
740
+ original_prompt: sanitizePromptForState(prompt),
600
741
  session_id: sessionId || undefined,
601
742
  project_path: directory,
602
743
  awaiting_confirmation: true,
@@ -609,7 +750,7 @@ function activateRalplanStartupState(directory, prompt, sessionId) {
609
750
  if (!existsSync(sessionDir)) {
610
751
  try { mkdirSync(sessionDir, { recursive: true }); } catch {}
611
752
  }
612
- try { writeFileSync(join(sessionDir, 'ralplan-state.json'), JSON.stringify(state, null, 2), { mode: 0o600 }); } catch {}
753
+ try { atomicWriteFileSync(join(sessionDir, 'ralplan-state.json'), JSON.stringify(state, null, 2)); } catch {}
613
754
  return;
614
755
  }
615
756
 
@@ -617,7 +758,7 @@ function activateRalplanStartupState(directory, prompt, sessionId) {
617
758
  if (!existsSync(localDir)) {
618
759
  try { mkdirSync(localDir, { recursive: true }); } catch {}
619
760
  }
620
- try { writeFileSync(join(localDir, 'ralplan-state.json'), JSON.stringify(state, null, 2), { mode: 0o600 }); } catch {}
761
+ try { atomicWriteFileSync(join(localDir, 'ralplan-state.json'), JSON.stringify(state, null, 2)); } catch {}
621
762
  }
622
763
 
623
764
  /**
@@ -858,7 +999,14 @@ async function main() {
858
999
  return;
859
1000
  }
860
1001
 
861
- const cleanPrompt = sanitizeForKeywordDetection(prompt).toLowerCase();
1002
+ // Strip pasted system-echo blocks BEFORE any mode-keyword dispatch runs.
1003
+ // This covers both the hasActionableKeyword() call sites AND alternative
1004
+ // matchers (e.g. isAntiSlopCleanupRequest) that bypass it. The helper
1005
+ // inside hasActionableKeyword also strips defensively, which stays as
1006
+ // belt-and-suspenders.
1007
+ const cleanPrompt = stripSystemEchoes(
1008
+ sanitizeForKeywordDetection(prompt).toLowerCase(),
1009
+ );
862
1010
 
863
1011
  // Collect all matching keywords
864
1012
  const matches = [];
@@ -0,0 +1,122 @@
1
+ #!/bin/sh
2
+ # OMC HUD cached statusLine launcher.
3
+ #
4
+ # Claude Code invokes statusLine commands for every render. Starting Node and
5
+ # importing the HUD bundle each time can take hundreds of milliseconds, which
6
+ # makes the first frame blank/flickery. This POSIX wrapper keeps the statusLine
7
+ # protocol unchanged (stdin JSON in, one line out) while making the hot path a
8
+ # shell read + cat of the last rendered line. A single background Node refresh
9
+ # updates the session-scoped cache for the next frame.
10
+
11
+ case "$0" in
12
+ */*) SCRIPT_DIR=${0%/*} ;;
13
+ *) SCRIPT_DIR=. ;;
14
+ esac
15
+ SCRIPT_DIR=$(cd "$SCRIPT_DIR" 2>/dev/null && pwd -P) || SCRIPT_DIR=.
16
+ CONFIG_DIR=${COPILOT_CONFIG_DIR:-$(cd "$SCRIPT_DIR/.." 2>/dev/null && pwd -P)}
17
+ CACHE_DIR=${OMC_HUD_CACHE_DIR:-"$CONFIG_DIR/hud/cache"}
18
+ HUD_SCRIPT=${1:-"$SCRIPT_DIR/omcp-hud.mjs"}
19
+ INPUT_TMP="$CACHE_DIR/stdin.$$.tmp"
20
+
21
+ mkdir -p "$CACHE_DIR" 2>/dev/null || {
22
+ printf '[OMC] Starting...\n'
23
+ exit 0
24
+ }
25
+
26
+ # Capture Claude's current statusLine stdin first so rendered output can be
27
+ # scoped per session/worktree instead of leaking across concurrent sessions.
28
+ cat > "$INPUT_TMP" 2>/dev/null || :
29
+
30
+ extract_json_string() {
31
+ key=$1
32
+ sed -n "s/.*\"$key\"[[:space:]]*:[[:space:]]*\"\([^\"]*\)\".*/\1/p" "$INPUT_TMP" 2>/dev/null | head -1
33
+ }
34
+
35
+ SESSION_KEY=$(extract_json_string session_id)
36
+ if [ -z "$SESSION_KEY" ] && [ -n "${CLAUDE_SESSION_ID:-}" ]; then
37
+ SESSION_KEY=$CLAUDE_SESSION_ID
38
+ fi
39
+ if [ -z "$SESSION_KEY" ] && [ -n "${CLAUDECODE_SESSION_ID:-}" ]; then
40
+ SESSION_KEY=$CLAUDECODE_SESSION_ID
41
+ fi
42
+ TRANSCRIPT_PATH=$(extract_json_string transcript_path)
43
+ if [ -z "$SESSION_KEY" ] && [ -n "$TRANSCRIPT_PATH" ]; then
44
+ SESSION_KEY=$(printf '%s\n' "$TRANSCRIPT_PATH" | sed -n 's/.*\([0-9a-fA-F][0-9a-fA-F-]\{35\}\).*/\1/p' | head -1)
45
+ if [ -z "$SESSION_KEY" ]; then
46
+ SESSION_KEY=$(printf '%s\n' "$TRANSCRIPT_PATH" | cksum 2>/dev/null | awk '{print "transcript-" $1}')
47
+ fi
48
+ fi
49
+ if [ -z "$SESSION_KEY" ]; then
50
+ CWD_VALUE=$(extract_json_string cwd)
51
+ if [ -n "$CWD_VALUE" ]; then
52
+ SESSION_KEY=$(printf '%s\n' "$CWD_VALUE" | cksum 2>/dev/null | awk '{print "cwd-" $1}')
53
+ fi
54
+ fi
55
+ if [ -z "$SESSION_KEY" ]; then
56
+ SESSION_KEY=default
57
+ fi
58
+ SESSION_KEY=$(printf '%s' "$SESSION_KEY" | sed 's/[^A-Za-z0-9_.-]/_/g')
59
+
60
+ INPUT_FILE="$CACHE_DIR/stdin.$SESSION_KEY.json"
61
+ OUTPUT_FILE="$CACHE_DIR/statusline.$SESSION_KEY.txt"
62
+ LOCK_DIR="$CACHE_DIR/render.$SESSION_KEY.lock"
63
+ NODE_STDOUT_TMP="$CACHE_DIR/statusline.$SESSION_KEY.$$.tmp"
64
+ NODE_STDERR_TMP="$CACHE_DIR/statusline.$SESSION_KEY.$$.err"
65
+
66
+ if [ -s "$INPUT_TMP" ]; then
67
+ mv "$INPUT_TMP" "$INPUT_FILE" 2>/dev/null || cp "$INPUT_TMP" "$INPUT_FILE" 2>/dev/null || :
68
+ fi
69
+ rm -f "$INPUT_TMP" 2>/dev/null || :
70
+
71
+ # Hot path: return immediately from the last successful render for this session.
72
+ if [ -s "$OUTPUT_FILE" ]; then
73
+ cat "$OUTPUT_FILE" 2>/dev/null || printf '[OMC] Starting...\n'
74
+ else
75
+ printf '[OMC] Starting...\n'
76
+ fi
77
+
78
+ # Avoid spawning a Node renderer on every statusLine render. mkdir is atomic.
79
+ if ! mkdir "$LOCK_DIR" 2>/dev/null; then
80
+ # Recover from stale locks left by crashes.
81
+ if [ -d "$LOCK_DIR" ]; then
82
+ now=$(date +%s 2>/dev/null || printf '0')
83
+ lock_mtime=$( (stat -c %Y "$LOCK_DIR" 2>/dev/null || stat -f %m "$LOCK_DIR" 2>/dev/null) | head -1 )
84
+ if [ -n "$lock_mtime" ] && [ "$now" -gt 0 ] && [ $((now - lock_mtime)) -gt 10 ]; then
85
+ rm -rf "$LOCK_DIR" 2>/dev/null || :
86
+ mkdir "$LOCK_DIR" 2>/dev/null || exit 0
87
+ else
88
+ exit 0
89
+ fi
90
+ else
91
+ exit 0
92
+ fi
93
+ fi
94
+
95
+ refresh_cache() {
96
+ if [ ! -s "$INPUT_FILE" ]; then
97
+ rm -rf "$LOCK_DIR" 2>/dev/null || :
98
+ return
99
+ fi
100
+
101
+ if [ -x "$SCRIPT_DIR/find-node.sh" ]; then
102
+ sh "$SCRIPT_DIR/find-node.sh" "$HUD_SCRIPT" < "$INPUT_FILE" > "$NODE_STDOUT_TMP" 2> "$NODE_STDERR_TMP"
103
+ else
104
+ node "$HUD_SCRIPT" < "$INPUT_FILE" > "$NODE_STDOUT_TMP" 2> "$NODE_STDERR_TMP"
105
+ fi
106
+
107
+ # Keep the last good line if rendering fails or returns empty output.
108
+ if [ -s "$NODE_STDOUT_TMP" ]; then
109
+ mv "$NODE_STDOUT_TMP" "$OUTPUT_FILE" 2>/dev/null || cp "$NODE_STDOUT_TMP" "$OUTPUT_FILE" 2>/dev/null || :
110
+ fi
111
+
112
+ rm -f "$NODE_STDOUT_TMP" "$NODE_STDERR_TMP" 2>/dev/null || :
113
+ rm -rf "$LOCK_DIR" 2>/dev/null || :
114
+ }
115
+
116
+ if [ "${OMC_HUD_SYNC_REFRESH:-0}" = "1" ]; then
117
+ refresh_cache
118
+ else
119
+ ( refresh_cache ) >/dev/null 2>&1 &
120
+ fi
121
+
122
+ exit 0