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
@@ -572,6 +572,32 @@ function readStateFileWithSession(stateDir, filename, sessionId) {
572
572
  return readStateFile(stateDir, filename);
573
573
  }
574
574
 
575
+ const WORKFLOW_SLOT_TOMBSTONE_TTL_MS = 24 * 60 * 60 * 1000;
576
+
577
+ function isWorkflowSlotTombstonedForMode(stateDir, mode, sessionId) {
578
+ const safeSessionId = sessionId && /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,255}$/.test(sessionId) ? sessionId : "";
579
+ const ledgerPath = safeSessionId
580
+ ? join(stateDir, "sessions", safeSessionId, "skill-active-state.json")
581
+ : join(stateDir, "skill-active-state.json");
582
+ const ledger = readJsonFile(ledgerPath);
583
+ const slot = ledger?.active_skills?.[mode];
584
+ if (!slot || typeof slot !== "object") return false;
585
+ if (typeof slot.completed_at !== "string" || !slot.completed_at) return false;
586
+ const completedAt = new Date(slot.completed_at).getTime();
587
+ if (!Number.isFinite(completedAt)) return true;
588
+ return Date.now() - completedAt < WORKFLOW_SLOT_TOMBSTONE_TTL_MS;
589
+ }
590
+
591
+ function isAuthoritativeModeActive(stateDir, mode, loaded, sessionId) {
592
+ const state = loaded?.state;
593
+ if (!state?.active) return false;
594
+ if (isWorkflowSlotTombstonedForMode(stateDir, mode, sessionId)) return false;
595
+ const safeSessionId = sessionId && /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,255}$/.test(sessionId) ? sessionId : "";
596
+ if (safeSessionId && state.session_id && state.session_id !== safeSessionId) return false;
597
+ return true;
598
+ }
599
+
600
+
575
601
  function getActiveSubagentCount(stateDir) {
576
602
  try {
577
603
  const tracking = readJsonFile(join(stateDir, "subagent-tracking.json"));
@@ -891,7 +917,7 @@ async function main() {
891
917
 
892
918
  // Priority 1: Ralph Loop (explicit persistence mode)
893
919
  // Skip if state is stale (older than 2 hours) - prevents blocking new sessions
894
- if (ralph.state?.active && !isAwaitingConfirmation(ralph.state) && !isStaleState(ralph.state) && isSessionMatch(ralph.state, sessionId)) {
920
+ if (isAuthoritativeModeActive(stateDir, "ralph", ralph, sessionId) && !isAwaitingConfirmation(ralph.state) && !isStaleState(ralph.state) && isSessionMatch(ralph.state, sessionId)) {
895
921
  const iteration = ralph.state.iteration || 1;
896
922
  const maxIter = ralph.state.max_iterations || 100;
897
923
 
@@ -1212,7 +1238,7 @@ async function main() {
1212
1238
  // Session isolation: only block if state belongs to this session (issue #311)
1213
1239
  // Project isolation: only block if state belongs to this project
1214
1240
  if (
1215
- ultrawork.state?.active && !isAwaitingConfirmation(ultrawork.state) &&
1241
+ isAuthoritativeModeActive(stateDir, "ultrawork", ultrawork, sessionId) && !isAwaitingConfirmation(ultrawork.state) &&
1216
1242
  !isStaleState(ultrawork.state) &&
1217
1243
  isSessionMatch(ultrawork.state, sessionId) &&
1218
1244
  isStateForCurrentProject(ultrawork.state, directory, ultrawork.isGlobal)
@@ -370,6 +370,32 @@ function readStateFileWithSession(stateDir, globalStateDir, filename, sessionId)
370
370
  return readStateFile(stateDir, globalStateDir, filename);
371
371
  }
372
372
 
373
+ const WORKFLOW_SLOT_TOMBSTONE_TTL_MS = 24 * 60 * 60 * 1000;
374
+
375
+ function isWorkflowSlotTombstonedForMode(stateDir, mode, sessionId) {
376
+ const safeSessionId = sanitizeSessionId(sessionId);
377
+ const ledgerPath = safeSessionId
378
+ ? join(stateDir, "sessions", safeSessionId, "skill-active-state.json")
379
+ : join(stateDir, "skill-active-state.json");
380
+ const ledger = readJsonFile(ledgerPath);
381
+ const slot = ledger?.active_skills?.[mode];
382
+ if (!slot || typeof slot !== "object") return false;
383
+ if (typeof slot.completed_at !== "string" || !slot.completed_at) return false;
384
+ const completedAt = new Date(slot.completed_at).getTime();
385
+ if (!Number.isFinite(completedAt)) return true;
386
+ return Date.now() - completedAt < WORKFLOW_SLOT_TOMBSTONE_TTL_MS;
387
+ }
388
+
389
+ function isAuthoritativeModeActive(stateDir, mode, loaded, sessionId) {
390
+ const state = loaded?.state;
391
+ if (!state?.active) return false;
392
+ if (isWorkflowSlotTombstonedForMode(stateDir, mode, sessionId)) return false;
393
+ const safeSessionId = sanitizeSessionId(sessionId);
394
+ if (safeSessionId && state.session_id && state.session_id !== safeSessionId) return false;
395
+ return true;
396
+ }
397
+
398
+
373
399
  function isSessionCancelInProgress(stateDir, sessionId) {
374
400
  const isActiveSignal = (signalPath) => {
375
401
  const signal = readJsonFile(signalPath);
@@ -762,7 +788,7 @@ async function main() {
762
788
  // Priority 1: Ralph Loop (explicit persistence mode)
763
789
  // Skip if state is stale (older than 2 hours) - prevents blocking new sessions
764
790
  if (
765
- ralph.state?.active && !isAwaitingConfirmation(ralph.state) &&
791
+ isAuthoritativeModeActive(stateDir, "ralph", ralph, sessionId) && !isAwaitingConfirmation(ralph.state) &&
766
792
  !isStaleState(ralph.state) &&
767
793
  isStateForCurrentProject(ralph.state, directory, ralph.isGlobal)
768
794
  ) {
@@ -1102,7 +1128,7 @@ async function main() {
1102
1128
  // If state has session_id, it must match. If no session_id (legacy), allow.
1103
1129
  // Project isolation: only block if state belongs to this project
1104
1130
  if (
1105
- ultrawork.state?.active && !isAwaitingConfirmation(ultrawork.state) &&
1131
+ isAuthoritativeModeActive(stateDir, "ultrawork", ultrawork, sessionId) && !isAwaitingConfirmation(ultrawork.state) &&
1106
1132
  !isStaleState(ultrawork.state) &&
1107
1133
  (hasValidSessionId
1108
1134
  ? ultrawork.state.session_id === sessionId
@@ -35,6 +35,11 @@ if (!existsSync(HUD_LIB_DIR)) {
35
35
  mkdirSync(HUD_LIB_DIR, { recursive: true });
36
36
  }
37
37
  copyFileSync(join(__dirname, 'lib', 'config-dir.mjs'), join(HUD_LIB_DIR, 'config-dir.mjs'));
38
+ copyFileSync(join(__dirname, 'lib', 'config-dir.sh'), join(HUD_LIB_DIR, 'config-dir.sh'));
39
+ copyFileSync(join(__dirname, 'find-node.sh'), join(HUD_DIR, 'find-node.sh'));
40
+ copyFileSync(join(__dirname, 'lib', 'hud-cache-wrapper.sh'), join(HUD_DIR, 'omcp-hud-cache.sh'));
41
+ try { chmodSync(join(HUD_DIR, 'find-node.sh'), 0o755); } catch { /* Windows doesn't need this */ }
42
+ try { chmodSync(join(HUD_DIR, 'omcp-hud-cache.sh'), 0o755); } catch { /* Windows doesn't need this */ }
38
43
 
39
44
  // 2. Create HUD wrapper script
40
45
  const hudScriptPath = join(HUD_DIR, 'omcp-hud.mjs').replace(/\\/g, '/');
@@ -238,9 +243,13 @@ try {
238
243
  settings = JSON.parse(readFileSync(SETTINGS_FILE, 'utf-8'));
239
244
  }
240
245
 
246
+ const statusLineCommand = process.platform === 'win32'
247
+ ? `"${nodeBin}" "${hudScriptPath.replace(/\\/g, "/")}"`
248
+ : `sh "${join(HUD_DIR, 'omcp-hud-cache.sh').replace(/\\/g, "/")}" "${hudScriptPath.replace(/\\/g, "/")}"`;
249
+
241
250
  settings.statusLine = {
242
251
  type: 'command',
243
- command: `"${nodeBin}" "${hudScriptPath.replace(/\\/g, "/")}"`
252
+ command: statusLineCommand
244
253
  };
245
254
  writeFileSync(SETTINGS_FILE, JSON.stringify(settings, null, 2));
246
255
  console.log('[OMC] Configured HUD statusLine in settings.json');
@@ -718,6 +718,145 @@ export function isCopilotCliWriteSuccess(output) {
718
718
  return successPatterns.some(pattern => pattern.test(cleaned));
719
719
  }
720
720
 
721
+ function extractTextFromKnownToolResponseField(value, depth = 0) {
722
+ if (typeof value === 'string') return [value];
723
+ if (!value || depth > 4) return [];
724
+
725
+ if (Array.isArray(value)) {
726
+ return value.flatMap(item => extractTextFromKnownToolResponseField(item, depth + 1));
727
+ }
728
+
729
+ if (typeof value !== 'object') return [];
730
+
731
+ const textFields = ['text', 'message', 'result', 'output', 'stdout'];
732
+ const texts = [];
733
+ for (const field of textFields) {
734
+ if (typeof value[field] === 'string') {
735
+ texts.push(value[field]);
736
+ }
737
+ }
738
+
739
+ if (
740
+ 'content' in value &&
741
+ value.content &&
742
+ (Array.isArray(value.content) || typeof value.content === 'object')
743
+ ) {
744
+ texts.push(...extractTextFromKnownToolResponseField(value.content, depth + 1));
745
+ }
746
+
747
+ return texts;
748
+ }
749
+
750
+ function isStructuredEnvelopePayloadField(fieldName) {
751
+ return new Set([
752
+ 'content',
753
+ 'oldstring',
754
+ 'newstring',
755
+ 'originalfile',
756
+ 'structuredpatch',
757
+ 'patch',
758
+ 'diff',
759
+ 'lines',
760
+ 'line',
761
+ ]).has(fieldName.toLowerCase());
762
+ }
763
+
764
+ function isStructuredEnvelopeStatusTextField(fieldName) {
765
+ return new Set(['message', 'output', 'stdout', 'stderr', 'text', 'result'])
766
+ .has(fieldName.toLowerCase());
767
+ }
768
+
769
+ function hasExplicitStructuredFailureIndicator(value, depth = 0, fieldName = '') {
770
+ if (!value || typeof value === 'string' || depth > 4) return false;
771
+ if (fieldName && isStructuredEnvelopePayloadField(fieldName)) return false;
772
+
773
+ if (Array.isArray(value)) {
774
+ return value.some(item => hasExplicitStructuredFailureIndicator(item, depth + 1, fieldName));
775
+ }
776
+
777
+ if (typeof value !== 'object') return false;
778
+
779
+ for (const [key, fieldValue] of Object.entries(value)) {
780
+ const normalizedKey = key.toLowerCase();
781
+ if (
782
+ typeof fieldValue === 'string' &&
783
+ isStructuredEnvelopeStatusTextField(key) &&
784
+ detectWriteFailure(fieldValue)
785
+ ) {
786
+ return true;
787
+ }
788
+
789
+ if (
790
+ (normalizedKey.includes('error') || normalizedKey.includes('fail')) &&
791
+ fieldValue !== false &&
792
+ fieldValue !== 0 &&
793
+ fieldValue !== null &&
794
+ fieldValue !== undefined &&
795
+ !(typeof fieldValue === 'string' && fieldValue.trim() === '') &&
796
+ !(Array.isArray(fieldValue) && fieldValue.length === 0)
797
+ ) {
798
+ return true;
799
+ }
800
+
801
+ if (hasExplicitStructuredFailureIndicator(fieldValue, depth + 1, key)) {
802
+ return true;
803
+ }
804
+ }
805
+
806
+ return false;
807
+ }
808
+
809
+ function hasEditEnvelopeSuccess(value, depth = 0) {
810
+ if (!value || typeof value === 'string' || depth > 4) return false;
811
+
812
+ if (Array.isArray(value)) {
813
+ return value.some(item => hasEditEnvelopeSuccess(item, depth + 1));
814
+ }
815
+
816
+ if (typeof value !== 'object') return false;
817
+
818
+ if (hasExplicitStructuredFailureIndicator(value, depth)) return false;
819
+
820
+ if (typeof value.filePath === 'string' && Array.isArray(value.structuredPatch)) {
821
+ return true;
822
+ }
823
+
824
+ return Object.values(value).some(item => hasEditEnvelopeSuccess(item, depth + 1));
825
+ }
826
+
827
+ function hasWriteEnvelopeSuccess(value, depth = 0) {
828
+ if (!value || typeof value === 'string' || depth > 4) return false;
829
+
830
+ if (Array.isArray(value)) {
831
+ return value.some(item => hasWriteEnvelopeSuccess(item, depth + 1));
832
+ }
833
+
834
+ if (typeof value !== 'object') return false;
835
+
836
+ if (hasExplicitStructuredFailureIndicator(value, depth)) return false;
837
+
838
+ if (
839
+ typeof value.filePath === 'string' &&
840
+ (value.type === 'create' || value.type === 'update')
841
+ ) {
842
+ return true;
843
+ }
844
+
845
+ return Object.values(value).some(item => hasWriteEnvelopeSuccess(item, depth + 1));
846
+ }
847
+
848
+ function hasStructuredWriteSuccess(rawResponse, toolName = '') {
849
+ if (!rawResponse || typeof rawResponse === 'string') return false;
850
+ if (toolName === 'Edit' && hasEditEnvelopeSuccess(rawResponse)) return true;
851
+ if (toolName === 'Write' && hasWriteEnvelopeSuccess(rawResponse)) return true;
852
+ return extractTextFromKnownToolResponseField(rawResponse).some(isCopilotCliWriteSuccess);
853
+ }
854
+
855
+ function hasStructuredWriteFailure(rawResponse) {
856
+ if (!rawResponse || typeof rawResponse === 'string') return false;
857
+ return hasExplicitStructuredFailureIndicator(rawResponse);
858
+ }
859
+
721
860
  // Get agent completion summary from tracking state
722
861
  function getAgentCompletionSummary(directory, quietLevel = QUIET_LEVEL) {
723
862
  const trackingFile = join(directory, '.omcp', 'state', 'subagent-tracking.json');
@@ -746,7 +885,12 @@ function getAgentCompletionSummary(directory, quietLevel = QUIET_LEVEL) {
746
885
 
747
886
  // Generate contextual message
748
887
  function generateMessage(toolName, toolOutput, sessionId, toolCount, directory, options = {}) {
749
- const { wasTruncated = false, rawLength = 0 } = options;
888
+ const {
889
+ wasTruncated = false,
890
+ rawLength = 0,
891
+ structuredWriteSuccess = false,
892
+ structuredWriteFailure = false,
893
+ } = options;
750
894
  let message = '';
751
895
 
752
896
  switch (toolName) {
@@ -797,7 +941,7 @@ function generateMessage(toolName, toolOutput, sessionId, toolCount, directory,
797
941
  }
798
942
 
799
943
  case 'Edit':
800
- if (!isCopilotCliWriteSuccess(toolOutput) && detectWriteFailure(toolOutput)) {
944
+ if (structuredWriteFailure || (!structuredWriteSuccess && !isCopilotCliWriteSuccess(toolOutput) && detectWriteFailure(toolOutput))) {
801
945
  message = 'Edit operation failed. Verify file exists and content matches exactly.';
802
946
  } else if (QUIET_LEVEL === 0) {
803
947
  message = 'Code modified. Verify changes work as expected before marking complete.';
@@ -805,7 +949,7 @@ function generateMessage(toolName, toolOutput, sessionId, toolCount, directory,
805
949
  break;
806
950
 
807
951
  case 'Write':
808
- if (!isCopilotCliWriteSuccess(toolOutput) && detectWriteFailure(toolOutput)) {
952
+ if (structuredWriteFailure || (!structuredWriteSuccess && !isCopilotCliWriteSuccess(toolOutput) && detectWriteFailure(toolOutput))) {
809
953
  message = 'Write operation failed. Check file permissions and directory existence.';
810
954
  } else if (QUIET_LEVEL === 0) {
811
955
  message = 'File written. Test the changes to ensure they work correctly.';
@@ -862,6 +1006,10 @@ async function main() {
862
1006
 
863
1007
  const toolName = data.tool_name || data.toolName || '';
864
1008
  const rawResponse = data.tool_response || data.toolOutput || '';
1009
+ const structuredWriteSuccess =
1010
+ (toolName === 'Write' || toolName === 'Edit') && hasStructuredWriteSuccess(rawResponse, toolName);
1011
+ const structuredWriteFailure =
1012
+ (toolName === 'Write' || toolName === 'Edit') && hasStructuredWriteFailure(rawResponse);
865
1013
  const toolOutput = typeof rawResponse === 'string' ? rawResponse : JSON.stringify(rawResponse);
866
1014
  const { clipped: clippedToolOutput, wasTruncated } = clipToolOutputForAnalysis(toolName, toolOutput);
867
1015
  const sessionId = data.session_id || data.sessionId || 'unknown';
@@ -907,6 +1055,8 @@ async function main() {
907
1055
  generateMessage(toolName, clippedToolOutput, sessionId, toolCount, directory, {
908
1056
  wasTruncated,
909
1057
  rawLength: toolOutput.length,
1058
+ structuredWriteSuccess,
1059
+ structuredWriteFailure,
910
1060
  }),
911
1061
  maybeBuildPreemptiveCompactionMessage(toolName, data, directory),
912
1062
  );
@@ -10,7 +10,7 @@ import { existsSync, mkdirSync, readFileSync, readdirSync, renameSync, writeFile
10
10
  import { dirname, join, resolve } from 'path';
11
11
  import { execSync } from 'child_process';
12
12
  import { fileURLToPath, pathToFileURL } from 'url';
13
- import { getClaudeConfigDir } from './lib/config-dir.mjs';
13
+ import { getCopilotConfigDir } from './lib/config-dir.mjs';
14
14
  import { evaluateAgentHeavyPreflight } from './lib/pre-tool-enforcer-preflight.mjs';
15
15
  import { resolveOmcStateRoot } from './lib/state-root.mjs';
16
16
  import { readStdin } from './lib/stdin.mjs';
@@ -29,6 +29,53 @@ function hasExtendedContextSuffix(modelId) {
29
29
  function isSubagentSafeModelId(modelId) {
30
30
  return isProviderSpecificModelId(modelId) && !hasExtendedContextSuffix(modelId);
31
31
  }
32
+ function isBedrockProviderEnv() {
33
+ if (process.env.CLAUDE_CODE_USE_BEDROCK === '1') return true;
34
+ const modelId = process.env.CLAUDE_MODEL || process.env.ANTHROPIC_MODEL || '';
35
+ if (/^((us|eu|ap|global)\.anthropic\.|anthropic\.claude)/i.test(modelId)) return true;
36
+ if (
37
+ /^arn:aws(-[^:]+)?:bedrock:/i.test(modelId)
38
+ && /:(inference-profile|application-inference-profile)\//i.test(modelId)
39
+ && modelId.toLowerCase().includes('claude')
40
+ ) {
41
+ return true;
42
+ }
43
+ return false;
44
+ }
45
+ function isVertexProviderEnv() {
46
+ if (process.env.CLAUDE_CODE_USE_VERTEX === '1') return true;
47
+ const modelId = process.env.CLAUDE_MODEL || process.env.ANTHROPIC_MODEL || '';
48
+ return !!modelId && modelId.toLowerCase().startsWith('vertex_ai/');
49
+ }
50
+ function getActiveModelIds() {
51
+ return [process.env.CLAUDE_MODEL || '', process.env.ANTHROPIC_MODEL || ''].filter(Boolean);
52
+ }
53
+ function isNormalClaudeModelId(modelId) {
54
+ const lower = (modelId || '').toLowerCase();
55
+ return Boolean(lower) && lower.includes('claude') && !isProviderSpecificModelId(modelId);
56
+ }
57
+ function hasNormalClaudeActiveModel() {
58
+ return getActiveModelIds().some(isNormalClaudeModelId);
59
+ }
60
+ function isConfigForceInheritProxyEnv() {
61
+ const config = loadOmcConfig();
62
+ return config.routing?.forceInherit === true && !hasNormalClaudeActiveModel();
63
+ }
64
+ function isNonClaudeProviderEnv() {
65
+ if (isBedrockProviderEnv() || isVertexProviderEnv()) return true;
66
+ const modelId = process.env.CLAUDE_MODEL || process.env.ANTHROPIC_MODEL || '';
67
+ if (modelId && !modelId.toLowerCase().includes('claude')) return true;
68
+ const baseUrl = process.env.ANTHROPIC_BASE_URL || '';
69
+ if (baseUrl && !baseUrl.includes('anthropic.com')) return true;
70
+ return isConfigForceInheritProxyEnv();
71
+ }
72
+ function acceptsProxyAnthropicDefaultTierValue(key, value) {
73
+ return key.startsWith('ANTHROPIC_DEFAULT_')
74
+ && Boolean(value)
75
+ && isNonClaudeProviderEnv()
76
+ && !isBedrockProviderEnv()
77
+ && !isVertexProviderEnv();
78
+ }
32
79
  const TIER_ALIASES = new Set(['sonnet', 'opus', 'haiku']);
33
80
  function isTierAlias(modelId) {
34
81
  return TIER_ALIASES.has((modelId || '').toLowerCase());
@@ -55,9 +102,10 @@ function resolveTierAliasToSafeModel(tierAlias) {
55
102
  // model resolution, which handles [1m] suffixes correctly for explicit model= calls.
56
103
  // OMC-internal vars (OMC_SUBAGENT_MODEL, OMC_MODEL_*) are not read by CC, so a [1m]
57
104
  // value there is not a valid routing proof — keep the stricter isSubagentSafeModelId check.
58
- const isNativeCcVar = key.startsWith('ANTHROPIC_DEFAULT_') || key.startsWith('CLAUDE_CODE_BEDROCK_');
105
+ const isAnthropicDefaultTierVar = key.startsWith('ANTHROPIC_DEFAULT_');
106
+ const isNativeCcVar = isAnthropicDefaultTierVar || key.startsWith('CLAUDE_CODE_BEDROCK_');
59
107
  const validator = isNativeCcVar ? isProviderSpecificModelId : isSubagentSafeModelId;
60
- if (value && validator(value)) return value;
108
+ if (value && (validator(value) || acceptsProxyAnthropicDefaultTierValue(key, value))) return value;
61
109
  }
62
110
  return '';
63
111
  }
@@ -167,7 +215,7 @@ function resolveTranscriptPath(transcriptPath, cwd) {
167
215
  const lastSep = transcriptPath.lastIndexOf('/');
168
216
  const sessionFile = lastSep !== -1 ? transcriptPath.substring(lastSep + 1) : '';
169
217
  if (sessionFile) {
170
- const configDir = getClaudeConfigDir();
218
+ const configDir = getCopilotConfigDir();
171
219
  const projectsDir = join(configDir, 'projects');
172
220
  if (existsSync(projectsDir)) {
173
221
  const encodedMain = mainRepoRoot.replace(/[/\\]/g, '-');
@@ -518,8 +566,8 @@ function getSkillProtectionLevel(skillName, rawSkillName) {
518
566
  // Load OMC config to check forceInherit setting (issues #1135, #1201)
519
567
  function loadOmcConfig() {
520
568
  const configPaths = [
521
- join(getClaudeConfigDir(), '.omc-config.json'),
522
- join(process.cwd(), '.omc', 'config.json'),
569
+ join(getCopilotConfigDir(), '.omc-config.json'),
570
+ join(process.cwd(), '.omcp', 'config.json'),
523
571
  ];
524
572
  for (const configPath of configPaths) {
525
573
  try {
@@ -48,6 +48,180 @@ function readJsonFile(path) {
48
48
  }
49
49
  }
50
50
 
51
+ const WORKFLOW_SLOT_TOMBSTONE_TTL_MS = 24 * 60 * 60 * 1000;
52
+
53
+ function isWorkflowSlotTombstonedForMode(omcRoot, mode, sessionId) {
54
+ const safeSessionId = typeof sessionId === 'string' && SAFE_SESSION_ID_PATTERN.test(sessionId) ? sessionId : '';
55
+ const ledgerPath = safeSessionId
56
+ ? join(omcRoot, 'state', 'sessions', safeSessionId, 'skill-active-state.json')
57
+ : join(omcRoot, 'state', 'skill-active-state.json');
58
+ const ledger = readJsonFile(ledgerPath);
59
+ const slot = ledger?.active_skills?.[mode];
60
+ if (!slot || typeof slot !== 'object') return false;
61
+ if (typeof slot.completed_at !== 'string' || !slot.completed_at) return false;
62
+ const completedAt = new Date(slot.completed_at).getTime();
63
+ if (!Number.isFinite(completedAt)) return true;
64
+ return Date.now() - completedAt < WORKFLOW_SLOT_TOMBSTONE_TTL_MS;
65
+ }
66
+
67
+ function shouldRestoreModeState(omcRoot, mode, state, sessionId) {
68
+ if (!state?.active) return false;
69
+ if (isWorkflowSlotTombstonedForMode(omcRoot, mode, sessionId)) return false;
70
+ return true;
71
+ }
72
+
73
+ function readLinuxBootId() {
74
+ try {
75
+ if (!existsSync(LINUX_BOOT_ID_PATH)) return undefined;
76
+ const bootId = readFileSync(LINUX_BOOT_ID_PATH, 'utf-8').trim();
77
+ return bootId || undefined;
78
+ } catch {
79
+ return undefined;
80
+ }
81
+ }
82
+
83
+ function sessionStateDir(omcRoot, sessionId) {
84
+ return join(omcRoot, 'state', 'sessions', sessionId);
85
+ }
86
+
87
+ function sessionStartedMarkerPath(omcRoot, sessionId) {
88
+ return join(sessionStateDir(omcRoot, sessionId), SESSION_STARTED_MARKER_FILE);
89
+ }
90
+
91
+ function writeSessionStartedMarker(omcRoot, directory, sessionId) {
92
+ if (!sessionId || !SAFE_SESSION_ID_PATTERN.test(sessionId)) return;
93
+ try {
94
+ const dir = sessionStateDir(omcRoot, sessionId);
95
+ mkdirSync(dir, { recursive: true });
96
+ writeFileSync(
97
+ sessionStartedMarkerPath(omcRoot, sessionId),
98
+ JSON.stringify({
99
+ session_id: sessionId,
100
+ started_at: new Date().toISOString(),
101
+ cwd: directory,
102
+ pid: process.pid,
103
+ // Do not persist process.ppid here: installed hooks run through
104
+ // scripts/run.cjs, whose short-lived process exits as soon as this
105
+ // hook returns. Treating that runner PID as owner liveness caused
106
+ // later SessionStart hooks to falsely clean live session state.
107
+ boot_id: readLinuxBootId(),
108
+ }, null, 2),
109
+ { encoding: 'utf-8', mode: 0o600 },
110
+ );
111
+ } catch {
112
+ // Best-effort only; SessionStart must remain non-blocking.
113
+ }
114
+ }
115
+
116
+ function removeSessionStartedMarker(omcRoot, sessionId) {
117
+ if (!sessionId || !SAFE_SESSION_ID_PATTERN.test(sessionId)) return;
118
+ try {
119
+ const markerPath = sessionStartedMarkerPath(omcRoot, sessionId);
120
+ if (existsSync(markerPath)) unlinkSync(markerPath);
121
+ } catch {
122
+ // Best-effort only.
123
+ }
124
+ }
125
+
126
+ /**
127
+ * Return true only when SessionStart has durable abandonment evidence.
128
+ *
129
+ * Claude Code SessionStart input currently provides session metadata such as
130
+ * session_id, transcript_path, cwd, source, model, and agent_type, but no
131
+ * stable owner process for the interactive session. In installed OMC hooks the
132
+ * immediate hook parent belongs to scripts/run.cjs and is intentionally
133
+ * short-lived, so same-boot PID liveness checks are not reliable here. SessionEnd
134
+ * remains the primary same-boot cleanup path; SessionStart only reconciles
135
+ * durable leftovers, such as markers from a previous OS boot.
136
+ */
137
+ function hasDurableAbandonmentEvidence(marker) {
138
+ const storedBootId = typeof marker?.boot_id === 'string' ? marker.boot_id : undefined;
139
+ const currentBootId = readLinuxBootId();
140
+ if (storedBootId && currentBootId && storedBootId !== currentBootId) {
141
+ return true;
142
+ }
143
+
144
+ // Same-boot hard-kill cleanup requires a durable owner signal. Claude Code
145
+ // does not currently provide one to hooks, so keep active state rather than
146
+ // guessing from hook-runner process ancestry or transcript metadata.
147
+ return false;
148
+ }
149
+
150
+ function cleanupSessionModeState(omcRoot, sessionId) {
151
+ const sessionDir = sessionStateDir(omcRoot, sessionId);
152
+ for (const file of SESSION_END_MODE_STATE_FILES) {
153
+ try {
154
+ const filePath = join(sessionDir, file);
155
+ const state = readJsonFile(filePath);
156
+ if (state?.active === true || file === 'skill-active-state.json') {
157
+ unlinkSync(filePath);
158
+ }
159
+ } catch {
160
+ // Leave ambiguous/unreadable state untouched.
161
+ }
162
+ }
163
+ }
164
+
165
+ function cleanupMissionStateForSession(omcRoot, sessionId) {
166
+ const missionStatePath = join(omcRoot, 'state', 'mission-state.json');
167
+ const parsed = readJsonFile(missionStatePath);
168
+ if (!Array.isArray(parsed?.missions)) return;
169
+
170
+ const before = parsed.missions.length;
171
+ parsed.missions = parsed.missions.filter((mission) => {
172
+ if (mission?.source !== 'session') return true;
173
+ const missionId = typeof mission.id === 'string' ? mission.id : '';
174
+ return !missionId.includes(sessionId);
175
+ });
176
+ if (parsed.missions.length !== before) {
177
+ parsed.updatedAt = new Date().toISOString();
178
+ try {
179
+ writeFileSync(missionStatePath, JSON.stringify(parsed, null, 2));
180
+ } catch {
181
+ // Best-effort only.
182
+ }
183
+ }
184
+ }
185
+
186
+ function reconcileAbandonedSessionStarts(omcRoot, currentSessionId) {
187
+ const sessionsDir = join(omcRoot, 'state', 'sessions');
188
+ if (!existsSync(sessionsDir)) return;
189
+
190
+ let entries = [];
191
+ try {
192
+ entries = readdirSync(sessionsDir);
193
+ } catch {
194
+ return;
195
+ }
196
+
197
+ for (const sessionId of entries) {
198
+ if (!SAFE_SESSION_ID_PATTERN.test(sessionId) || sessionId === currentSessionId) continue;
199
+
200
+ const marker = readJsonFile(sessionStartedMarkerPath(omcRoot, sessionId));
201
+ if (!marker || marker.session_id !== sessionId) continue;
202
+
203
+ if (existsSync(join(omcRoot, 'sessions', `${sessionId}.json`))) {
204
+ removeSessionStartedMarker(omcRoot, sessionId);
205
+ continue;
206
+ }
207
+
208
+ if (!hasDurableAbandonmentEvidence(marker)) continue;
209
+
210
+ cleanupSessionModeState(omcRoot, sessionId);
211
+ cleanupMissionStateForSession(omcRoot, sessionId);
212
+ removeSessionStartedMarker(omcRoot, sessionId);
213
+
214
+ try {
215
+ const sessionDir = sessionStateDir(omcRoot, sessionId);
216
+ if (readdirSync(sessionDir).length === 0) {
217
+ rmSync(sessionDir, { recursive: false, force: true });
218
+ }
219
+ } catch {
220
+ // Leave non-empty/unreadable directories untouched.
221
+ }
222
+ }
223
+ }
224
+
51
225
  function getRuntimeBaseDir() {
52
226
  return process.env.PLUGIN_ROOT || process.env.CLAUDE_PLUGIN_ROOT || join(__dirname, '..');
53
227
  }
@@ -145,6 +319,21 @@ function semverCompare(a, b) {
145
319
 
146
320
  const SESSION_START_CONTEXT_BUDGET = 6000;
147
321
  const SESSION_START_OMISSION_NOTICE = '[Additional SessionStart context omitted to preserve the 6000-character aggregate budget.]';
322
+ const SESSION_STARTED_MARKER_FILE = 'session-started.json';
323
+ const SAFE_SESSION_ID_PATTERN = /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,255}$/;
324
+ const LINUX_BOOT_ID_PATH = '/proc/sys/kernel/random/boot_id';
325
+ const SESSION_END_MODE_STATE_FILES = [
326
+ 'autopilot-state.json',
327
+ 'autoresearch-state.json',
328
+ 'team-state.json',
329
+ 'ralph-state.json',
330
+ 'ultrawork-state.json',
331
+ 'ultraqa-state.json',
332
+ 'ralplan-state.json',
333
+ 'deep-interview-state.json',
334
+ 'self-improve-state.json',
335
+ 'skill-active-state.json',
336
+ ];
148
337
 
149
338
  function compactBudgetedText(text, maxChars) {
150
339
  const notice = '\n...[truncated to preserve SessionStart context budget]';
@@ -432,6 +621,9 @@ async function main() {
432
621
  const messages = [];
433
622
  const projectMemoryModules = await loadProjectMemoryModules();
434
623
 
624
+ writeSessionStartedMarker(omcRoot, directory, sessionId);
625
+ reconcileAbandonedSessionStarts(omcRoot, sessionId);
626
+
435
627
  // Check for version drift between components
436
628
  const driftInfo = detectVersionDrift();
437
629
  if (driftInfo && shouldNotifyDrift(driftInfo)) {
@@ -489,7 +681,7 @@ async function main() {
489
681
  ultraworkState = readJsonFile(join(omcRoot, 'state', 'ultrawork-state.json'));
490
682
  }
491
683
 
492
- if (ultraworkState?.active) {
684
+ if (shouldRestoreModeState(omcRoot, 'ultrawork', ultraworkState, sessionId)) {
493
685
  messages.push(`<session-restore>
494
686
 
495
687
  [ULTRAWORK MODE RESTORED]
@@ -522,7 +714,7 @@ Treat this as prior-session context only. Prioritize the user's newest request,
522
714
  ralphState = readJsonFile(join(omcRoot, 'ralph-state.json'));
523
715
  }
524
716
  }
525
- if (ralphState?.active) {
717
+ if (shouldRestoreModeState(omcRoot, 'ralph', ralphState, sessionId)) {
526
718
  messages.push(`<session-restore>
527
719
 
528
720
  [RALPH LOOP RESTORED]