oh-my-codex 0.6.3 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (417) hide show
  1. package/README.md +19 -9
  2. package/bin/omx.js +3 -5
  3. package/dist/agents/__tests__/definitions.test.d.ts +2 -0
  4. package/dist/agents/__tests__/definitions.test.d.ts.map +1 -0
  5. package/dist/agents/__tests__/definitions.test.js +35 -0
  6. package/dist/agents/__tests__/definitions.test.js.map +1 -0
  7. package/dist/agents/__tests__/native-config.test.d.ts +2 -0
  8. package/dist/agents/__tests__/native-config.test.d.ts.map +1 -0
  9. package/dist/agents/__tests__/native-config.test.js +48 -0
  10. package/dist/agents/__tests__/native-config.test.js.map +1 -0
  11. package/dist/catalog/__tests__/schema.test.js +15 -0
  12. package/dist/catalog/__tests__/schema.test.js.map +1 -1
  13. package/dist/catalog/schema.d.ts.map +1 -1
  14. package/dist/catalog/schema.js +6 -0
  15. package/dist/catalog/schema.js.map +1 -1
  16. package/dist/cli/__tests__/catalog-contract.test.d.ts +2 -0
  17. package/dist/cli/__tests__/catalog-contract.test.d.ts.map +1 -0
  18. package/dist/cli/__tests__/catalog-contract.test.js +18 -0
  19. package/dist/cli/__tests__/catalog-contract.test.js.map +1 -0
  20. package/dist/cli/__tests__/doctor-team.test.js +3 -2
  21. package/dist/cli/__tests__/doctor-team.test.js.map +1 -1
  22. package/dist/cli/__tests__/error-handling-warnings.test.d.ts +2 -0
  23. package/dist/cli/__tests__/error-handling-warnings.test.d.ts.map +1 -0
  24. package/dist/cli/__tests__/error-handling-warnings.test.js +35 -0
  25. package/dist/cli/__tests__/error-handling-warnings.test.js.map +1 -0
  26. package/dist/cli/__tests__/index.test.js +81 -8
  27. package/dist/cli/__tests__/index.test.js.map +1 -1
  28. package/dist/cli/__tests__/setup-agents-overwrite.test.d.ts +2 -0
  29. package/dist/cli/__tests__/setup-agents-overwrite.test.d.ts.map +1 -0
  30. package/dist/cli/__tests__/setup-agents-overwrite.test.js +124 -0
  31. package/dist/cli/__tests__/setup-agents-overwrite.test.js.map +1 -0
  32. package/dist/cli/__tests__/setup-scope.test.js +79 -21
  33. package/dist/cli/__tests__/setup-scope.test.js.map +1 -1
  34. package/dist/cli/__tests__/setup-skills-overwrite.test.d.ts +2 -0
  35. package/dist/cli/__tests__/setup-skills-overwrite.test.d.ts.map +1 -0
  36. package/dist/cli/__tests__/setup-skills-overwrite.test.js +32 -0
  37. package/dist/cli/__tests__/setup-skills-overwrite.test.js.map +1 -0
  38. package/dist/cli/__tests__/star-prompt.test.js +74 -0
  39. package/dist/cli/__tests__/star-prompt.test.js.map +1 -1
  40. package/dist/cli/__tests__/team.test.js +8 -0
  41. package/dist/cli/__tests__/team.test.js.map +1 -1
  42. package/dist/cli/doctor.d.ts.map +1 -1
  43. package/dist/cli/doctor.js +75 -18
  44. package/dist/cli/doctor.js.map +1 -1
  45. package/dist/cli/index.d.ts +10 -1
  46. package/dist/cli/index.d.ts.map +1 -1
  47. package/dist/cli/index.js +153 -45
  48. package/dist/cli/index.js.map +1 -1
  49. package/dist/cli/setup.d.ts +2 -1
  50. package/dist/cli/setup.d.ts.map +1 -1
  51. package/dist/cli/setup.js +104 -60
  52. package/dist/cli/setup.js.map +1 -1
  53. package/dist/cli/star-prompt.d.ts +21 -1
  54. package/dist/cli/star-prompt.d.ts.map +1 -1
  55. package/dist/cli/star-prompt.js +34 -13
  56. package/dist/cli/star-prompt.js.map +1 -1
  57. package/dist/cli/team.d.ts.map +1 -1
  58. package/dist/cli/team.js +10 -3
  59. package/dist/cli/team.js.map +1 -1
  60. package/dist/cli/update.d.ts.map +1 -1
  61. package/dist/cli/update.js.map +1 -1
  62. package/dist/config/__tests__/generator-notify.test.js +16 -0
  63. package/dist/config/__tests__/generator-notify.test.js.map +1 -1
  64. package/dist/config/__tests__/models.test.js +9 -1
  65. package/dist/config/__tests__/models.test.js.map +1 -1
  66. package/dist/config/generator.js +9 -10
  67. package/dist/config/generator.js.map +1 -1
  68. package/dist/config/models.d.ts +8 -1
  69. package/dist/config/models.d.ts.map +1 -1
  70. package/dist/config/models.js +27 -5
  71. package/dist/config/models.js.map +1 -1
  72. package/dist/hooks/__tests__/agents-overlay.test.js +24 -0
  73. package/dist/hooks/__tests__/agents-overlay.test.js.map +1 -1
  74. package/dist/hooks/__tests__/consensus-execution-handoff.test.d.ts +18 -0
  75. package/dist/hooks/__tests__/consensus-execution-handoff.test.d.ts.map +1 -0
  76. package/dist/hooks/__tests__/consensus-execution-handoff.test.js +204 -0
  77. package/dist/hooks/__tests__/consensus-execution-handoff.test.js.map +1 -0
  78. package/dist/hooks/__tests__/emulator.test.d.ts +2 -0
  79. package/dist/hooks/__tests__/emulator.test.d.ts.map +1 -0
  80. package/dist/hooks/__tests__/emulator.test.js +47 -0
  81. package/dist/hooks/__tests__/emulator.test.js.map +1 -0
  82. package/dist/hooks/__tests__/keyword-detector.test.js +330 -4
  83. package/dist/hooks/__tests__/keyword-detector.test.js.map +1 -1
  84. package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js +101 -0
  85. package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js.map +1 -1
  86. package/dist/hooks/__tests__/notify-hook-cross-worktree-heartbeat.test.js +13 -7
  87. package/dist/hooks/__tests__/notify-hook-cross-worktree-heartbeat.test.js.map +1 -1
  88. package/dist/hooks/__tests__/notify-hook-modules.test.js +61 -0
  89. package/dist/hooks/__tests__/notify-hook-modules.test.js.map +1 -1
  90. package/dist/hooks/__tests__/notify-hook-session-scope.test.js +47 -0
  91. package/dist/hooks/__tests__/notify-hook-session-scope.test.js.map +1 -1
  92. package/dist/hooks/__tests__/notify-hook-worker-idle.test.d.ts +2 -0
  93. package/dist/hooks/__tests__/notify-hook-worker-idle.test.d.ts.map +1 -0
  94. package/dist/hooks/__tests__/notify-hook-worker-idle.test.js +560 -0
  95. package/dist/hooks/__tests__/notify-hook-worker-idle.test.js.map +1 -0
  96. package/dist/hooks/__tests__/session.test.d.ts +2 -0
  97. package/dist/hooks/__tests__/session.test.d.ts.map +1 -0
  98. package/dist/hooks/__tests__/session.test.js +161 -0
  99. package/dist/hooks/__tests__/session.test.js.map +1 -0
  100. package/dist/hooks/__tests__/task-size-detector.test.d.ts +2 -0
  101. package/dist/hooks/__tests__/task-size-detector.test.d.ts.map +1 -0
  102. package/dist/hooks/__tests__/task-size-detector.test.js +336 -0
  103. package/dist/hooks/__tests__/task-size-detector.test.js.map +1 -0
  104. package/dist/hooks/__tests__/tmux-hook-engine-types-sync.test.d.ts +2 -0
  105. package/dist/hooks/__tests__/tmux-hook-engine-types-sync.test.d.ts.map +1 -0
  106. package/dist/hooks/__tests__/tmux-hook-engine-types-sync.test.js +24 -0
  107. package/dist/hooks/__tests__/tmux-hook-engine-types-sync.test.js.map +1 -0
  108. package/dist/hooks/agents-overlay.d.ts.map +1 -1
  109. package/dist/hooks/agents-overlay.js +46 -2
  110. package/dist/hooks/agents-overlay.js.map +1 -1
  111. package/dist/hooks/code-simplifier/__tests__/index.test.js +67 -15
  112. package/dist/hooks/code-simplifier/__tests__/index.test.js.map +1 -1
  113. package/dist/hooks/code-simplifier/index.d.ts +10 -4
  114. package/dist/hooks/code-simplifier/index.d.ts.map +1 -1
  115. package/dist/hooks/code-simplifier/index.js +38 -12
  116. package/dist/hooks/code-simplifier/index.js.map +1 -1
  117. package/dist/hooks/codebase-map.d.ts.map +1 -1
  118. package/dist/hooks/codebase-map.js +5 -32
  119. package/dist/hooks/codebase-map.js.map +1 -1
  120. package/dist/hooks/emulator.d.ts.map +1 -1
  121. package/dist/hooks/emulator.js +11 -18
  122. package/dist/hooks/emulator.js.map +1 -1
  123. package/dist/hooks/extensibility/__tests__/dispatcher.test.js +59 -1
  124. package/dist/hooks/extensibility/__tests__/dispatcher.test.js.map +1 -1
  125. package/dist/hooks/extensibility/__tests__/loader.test.js +19 -0
  126. package/dist/hooks/extensibility/__tests__/loader.test.js.map +1 -1
  127. package/dist/hooks/extensibility/dispatcher.d.ts.map +1 -1
  128. package/dist/hooks/extensibility/dispatcher.js +51 -39
  129. package/dist/hooks/extensibility/dispatcher.js.map +1 -1
  130. package/dist/hooks/extensibility/loader.d.ts.map +1 -1
  131. package/dist/hooks/extensibility/loader.js +25 -13
  132. package/dist/hooks/extensibility/loader.js.map +1 -1
  133. package/dist/hooks/extensibility/logging.d.ts.map +1 -1
  134. package/dist/hooks/extensibility/logging.js +6 -1
  135. package/dist/hooks/extensibility/logging.js.map +1 -1
  136. package/dist/hooks/extensibility/sdk.js.map +1 -1
  137. package/dist/hooks/keyword-detector.d.ts +87 -0
  138. package/dist/hooks/keyword-detector.d.ts.map +1 -1
  139. package/dist/hooks/keyword-detector.js +235 -23
  140. package/dist/hooks/keyword-detector.js.map +1 -1
  141. package/dist/hooks/keyword-registry.d.ts +15 -0
  142. package/dist/hooks/keyword-registry.d.ts.map +1 -0
  143. package/dist/hooks/keyword-registry.js +41 -0
  144. package/dist/hooks/keyword-registry.js.map +1 -0
  145. package/dist/hooks/session.d.ts +18 -2
  146. package/dist/hooks/session.d.ts.map +1 -1
  147. package/dist/hooks/session.js +84 -11
  148. package/dist/hooks/session.js.map +1 -1
  149. package/dist/hooks/task-size-detector.d.ts +72 -0
  150. package/dist/hooks/task-size-detector.d.ts.map +1 -0
  151. package/dist/hooks/task-size-detector.js +204 -0
  152. package/dist/hooks/task-size-detector.js.map +1 -0
  153. package/dist/hud/__tests__/colors.test.js +1 -103
  154. package/dist/hud/__tests__/colors.test.js.map +1 -1
  155. package/dist/hud/__tests__/index.test.d.ts +2 -0
  156. package/dist/hud/__tests__/index.test.d.ts.map +1 -0
  157. package/dist/hud/__tests__/index.test.js +131 -0
  158. package/dist/hud/__tests__/index.test.js.map +1 -0
  159. package/dist/hud/__tests__/render.test.js +53 -0
  160. package/dist/hud/__tests__/render.test.js.map +1 -1
  161. package/dist/hud/__tests__/watch.test.d.ts +2 -0
  162. package/dist/hud/__tests__/watch.test.d.ts.map +1 -0
  163. package/dist/hud/__tests__/watch.test.js +63 -0
  164. package/dist/hud/__tests__/watch.test.js.map +1 -0
  165. package/dist/hud/colors.d.ts +2 -9
  166. package/dist/hud/colors.d.ts.map +1 -1
  167. package/dist/hud/colors.js +19 -34
  168. package/dist/hud/colors.js.map +1 -1
  169. package/dist/hud/constants.d.ts +1 -0
  170. package/dist/hud/constants.d.ts.map +1 -1
  171. package/dist/hud/constants.js +1 -0
  172. package/dist/hud/constants.js.map +1 -1
  173. package/dist/hud/index.d.ts +27 -0
  174. package/dist/hud/index.d.ts.map +1 -1
  175. package/dist/hud/index.js +149 -9
  176. package/dist/hud/index.js.map +1 -1
  177. package/dist/hud/render.d.ts.map +1 -1
  178. package/dist/hud/render.js +20 -7
  179. package/dist/hud/render.js.map +1 -1
  180. package/dist/mcp/__tests__/bootstrap.test.d.ts +2 -0
  181. package/dist/mcp/__tests__/bootstrap.test.d.ts.map +1 -0
  182. package/dist/mcp/__tests__/bootstrap.test.js +25 -0
  183. package/dist/mcp/__tests__/bootstrap.test.js.map +1 -0
  184. package/dist/mcp/__tests__/code-intel-server.test.d.ts +2 -0
  185. package/dist/mcp/__tests__/code-intel-server.test.d.ts.map +1 -0
  186. package/dist/mcp/__tests__/code-intel-server.test.js +43 -0
  187. package/dist/mcp/__tests__/code-intel-server.test.js.map +1 -0
  188. package/dist/mcp/__tests__/memory-server.test.d.ts +2 -0
  189. package/dist/mcp/__tests__/memory-server.test.d.ts.map +1 -0
  190. package/dist/mcp/__tests__/memory-server.test.js +34 -0
  191. package/dist/mcp/__tests__/memory-server.test.js.map +1 -0
  192. package/dist/mcp/__tests__/memory-validation.test.d.ts +2 -0
  193. package/dist/mcp/__tests__/memory-validation.test.d.ts.map +1 -0
  194. package/dist/mcp/__tests__/memory-validation.test.js +29 -0
  195. package/dist/mcp/__tests__/memory-validation.test.js.map +1 -0
  196. package/dist/mcp/__tests__/path-traversal.test.js +55 -0
  197. package/dist/mcp/__tests__/path-traversal.test.js.map +1 -1
  198. package/dist/mcp/__tests__/state-paths.test.js +43 -6
  199. package/dist/mcp/__tests__/state-paths.test.js.map +1 -1
  200. package/dist/mcp/__tests__/state-server-ralph-phase.test.js +50 -0
  201. package/dist/mcp/__tests__/state-server-ralph-phase.test.js.map +1 -1
  202. package/dist/mcp/__tests__/state-server-schema.test.js +3 -7
  203. package/dist/mcp/__tests__/state-server-schema.test.js.map +1 -1
  204. package/dist/mcp/__tests__/state-server.test.js +30 -1
  205. package/dist/mcp/__tests__/state-server.test.js.map +1 -1
  206. package/dist/mcp/__tests__/trace-server.test.js +58 -0
  207. package/dist/mcp/__tests__/trace-server.test.js.map +1 -1
  208. package/dist/mcp/bootstrap.d.ts +3 -0
  209. package/dist/mcp/bootstrap.d.ts.map +1 -0
  210. package/dist/mcp/bootstrap.js +13 -0
  211. package/dist/mcp/bootstrap.js.map +1 -0
  212. package/dist/mcp/code-intel-server.d.ts +8 -0
  213. package/dist/mcp/code-intel-server.d.ts.map +1 -1
  214. package/dist/mcp/code-intel-server.js +50 -24
  215. package/dist/mcp/code-intel-server.js.map +1 -1
  216. package/dist/mcp/memory-server.js +34 -13
  217. package/dist/mcp/memory-server.js.map +1 -1
  218. package/dist/mcp/memory-validation.d.ts +9 -0
  219. package/dist/mcp/memory-validation.d.ts.map +1 -0
  220. package/dist/mcp/memory-validation.js +11 -0
  221. package/dist/mcp/memory-validation.js.map +1 -0
  222. package/dist/mcp/state-paths.d.ts +2 -0
  223. package/dist/mcp/state-paths.d.ts.map +1 -1
  224. package/dist/mcp/state-paths.js +83 -12
  225. package/dist/mcp/state-paths.js.map +1 -1
  226. package/dist/mcp/state-server.d.ts.map +1 -1
  227. package/dist/mcp/state-server.js +85 -47
  228. package/dist/mcp/state-server.js.map +1 -1
  229. package/dist/mcp/trace-server.d.ts +16 -0
  230. package/dist/mcp/trace-server.d.ts.map +1 -1
  231. package/dist/mcp/trace-server.js +84 -24
  232. package/dist/mcp/trace-server.js.map +1 -1
  233. package/dist/modes/__tests__/base-ralph-contract.test.d.ts +2 -0
  234. package/dist/modes/__tests__/base-ralph-contract.test.d.ts.map +1 -0
  235. package/dist/modes/__tests__/base-ralph-contract.test.js +49 -0
  236. package/dist/modes/__tests__/base-ralph-contract.test.js.map +1 -0
  237. package/dist/modes/__tests__/base-tmux-pane.test.js +13 -1
  238. package/dist/modes/__tests__/base-tmux-pane.test.js.map +1 -1
  239. package/dist/modes/base.d.ts +0 -4
  240. package/dist/modes/base.d.ts.map +1 -1
  241. package/dist/modes/base.js +31 -11
  242. package/dist/modes/base.js.map +1 -1
  243. package/dist/notifications/__tests__/config.test.js +47 -1
  244. package/dist/notifications/__tests__/config.test.js.map +1 -1
  245. package/dist/notifications/__tests__/formatter.test.js +54 -2
  246. package/dist/notifications/__tests__/formatter.test.js.map +1 -1
  247. package/dist/notifications/__tests__/hook-config.test.d.ts +5 -0
  248. package/dist/notifications/__tests__/hook-config.test.d.ts.map +1 -0
  249. package/dist/notifications/__tests__/hook-config.test.js +139 -0
  250. package/dist/notifications/__tests__/hook-config.test.js.map +1 -0
  251. package/dist/notifications/__tests__/idle-cooldown.test.d.ts +5 -0
  252. package/dist/notifications/__tests__/idle-cooldown.test.d.ts.map +1 -0
  253. package/dist/notifications/__tests__/idle-cooldown.test.js +100 -0
  254. package/dist/notifications/__tests__/idle-cooldown.test.js.map +1 -0
  255. package/dist/notifications/__tests__/notifier.test.js +89 -1
  256. package/dist/notifications/__tests__/notifier.test.js.map +1 -1
  257. package/dist/notifications/__tests__/reply-config.test.d.ts +2 -0
  258. package/dist/notifications/__tests__/reply-config.test.d.ts.map +1 -0
  259. package/dist/notifications/__tests__/reply-config.test.js +79 -0
  260. package/dist/notifications/__tests__/reply-config.test.js.map +1 -0
  261. package/dist/notifications/__tests__/reply-listener.test.js +35 -1
  262. package/dist/notifications/__tests__/reply-listener.test.js.map +1 -1
  263. package/dist/notifications/__tests__/session-registry.test.js +40 -0
  264. package/dist/notifications/__tests__/session-registry.test.js.map +1 -1
  265. package/dist/notifications/__tests__/template-engine.test.d.ts +5 -0
  266. package/dist/notifications/__tests__/template-engine.test.d.ts.map +1 -0
  267. package/dist/notifications/__tests__/template-engine.test.js +147 -0
  268. package/dist/notifications/__tests__/template-engine.test.js.map +1 -0
  269. package/dist/notifications/config.d.ts +8 -0
  270. package/dist/notifications/config.d.ts.map +1 -1
  271. package/dist/notifications/config.js +110 -19
  272. package/dist/notifications/config.js.map +1 -1
  273. package/dist/notifications/formatter.d.ts +5 -0
  274. package/dist/notifications/formatter.d.ts.map +1 -1
  275. package/dist/notifications/formatter.js +45 -10
  276. package/dist/notifications/formatter.js.map +1 -1
  277. package/dist/notifications/hook-config-types.d.ts +43 -0
  278. package/dist/notifications/hook-config-types.d.ts.map +1 -0
  279. package/dist/notifications/hook-config-types.js +8 -0
  280. package/dist/notifications/hook-config-types.js.map +1 -0
  281. package/dist/notifications/hook-config.d.ts +40 -0
  282. package/dist/notifications/hook-config.d.ts.map +1 -0
  283. package/dist/notifications/hook-config.js +127 -0
  284. package/dist/notifications/hook-config.js.map +1 -0
  285. package/dist/notifications/idle-cooldown.d.ts +35 -0
  286. package/dist/notifications/idle-cooldown.d.ts.map +1 -0
  287. package/dist/notifications/idle-cooldown.js +108 -0
  288. package/dist/notifications/idle-cooldown.js.map +1 -0
  289. package/dist/notifications/index.d.ts +3 -0
  290. package/dist/notifications/index.d.ts.map +1 -1
  291. package/dist/notifications/index.js +43 -1
  292. package/dist/notifications/index.js.map +1 -1
  293. package/dist/notifications/notifier.d.ts +9 -0
  294. package/dist/notifications/notifier.d.ts.map +1 -1
  295. package/dist/notifications/notifier.js +36 -30
  296. package/dist/notifications/notifier.js.map +1 -1
  297. package/dist/notifications/reply-listener.d.ts +3 -0
  298. package/dist/notifications/reply-listener.d.ts.map +1 -1
  299. package/dist/notifications/reply-listener.js +61 -7
  300. package/dist/notifications/reply-listener.js.map +1 -1
  301. package/dist/notifications/session-registry.d.ts +1 -1
  302. package/dist/notifications/session-registry.d.ts.map +1 -1
  303. package/dist/notifications/session-registry.js +18 -6
  304. package/dist/notifications/session-registry.js.map +1 -1
  305. package/dist/notifications/template-engine.d.ts +34 -0
  306. package/dist/notifications/template-engine.d.ts.map +1 -0
  307. package/dist/notifications/template-engine.js +246 -0
  308. package/dist/notifications/template-engine.js.map +1 -0
  309. package/dist/notifications/types.d.ts +6 -0
  310. package/dist/notifications/types.d.ts.map +1 -1
  311. package/dist/openclaw/__tests__/config.test.d.ts +6 -0
  312. package/dist/openclaw/__tests__/config.test.d.ts.map +1 -0
  313. package/dist/openclaw/__tests__/config.test.js +174 -0
  314. package/dist/openclaw/__tests__/config.test.js.map +1 -0
  315. package/dist/openclaw/__tests__/dispatcher.test.d.ts +5 -0
  316. package/dist/openclaw/__tests__/dispatcher.test.d.ts.map +1 -0
  317. package/dist/openclaw/__tests__/dispatcher.test.js +104 -0
  318. package/dist/openclaw/__tests__/dispatcher.test.js.map +1 -0
  319. package/dist/openclaw/__tests__/index.test.d.ts +6 -0
  320. package/dist/openclaw/__tests__/index.test.d.ts.map +1 -0
  321. package/dist/openclaw/__tests__/index.test.js +131 -0
  322. package/dist/openclaw/__tests__/index.test.js.map +1 -0
  323. package/dist/openclaw/config.d.ts +37 -0
  324. package/dist/openclaw/config.d.ts.map +1 -0
  325. package/dist/openclaw/config.js +106 -0
  326. package/dist/openclaw/config.js.map +1 -0
  327. package/dist/openclaw/dispatcher.d.ts +63 -0
  328. package/dist/openclaw/dispatcher.d.ts.map +1 -0
  329. package/dist/openclaw/dispatcher.js +223 -0
  330. package/dist/openclaw/dispatcher.js.map +1 -0
  331. package/dist/openclaw/index.d.ts +27 -0
  332. package/dist/openclaw/index.d.ts.map +1 -0
  333. package/dist/openclaw/index.js +130 -0
  334. package/dist/openclaw/index.js.map +1 -0
  335. package/dist/openclaw/types.d.ts +105 -0
  336. package/dist/openclaw/types.d.ts.map +1 -0
  337. package/dist/openclaw/types.js +12 -0
  338. package/dist/openclaw/types.js.map +1 -0
  339. package/dist/ralph/contract.d.ts.map +1 -1
  340. package/dist/ralph/contract.js +13 -4
  341. package/dist/ralph/contract.js.map +1 -1
  342. package/dist/team/__tests__/phase-controller.test.js +14 -0
  343. package/dist/team/__tests__/phase-controller.test.js.map +1 -1
  344. package/dist/team/__tests__/runtime.test.js +328 -1
  345. package/dist/team/__tests__/runtime.test.js.map +1 -1
  346. package/dist/team/__tests__/scaling.test.d.ts +2 -0
  347. package/dist/team/__tests__/scaling.test.d.ts.map +1 -0
  348. package/dist/team/__tests__/scaling.test.js +295 -0
  349. package/dist/team/__tests__/scaling.test.js.map +1 -0
  350. package/dist/team/__tests__/state.test.js +62 -1
  351. package/dist/team/__tests__/state.test.js.map +1 -1
  352. package/dist/team/__tests__/tmux-session.test.js +219 -14
  353. package/dist/team/__tests__/tmux-session.test.js.map +1 -1
  354. package/dist/team/__tests__/worker-bootstrap.test.js +4 -0
  355. package/dist/team/__tests__/worker-bootstrap.test.js.map +1 -1
  356. package/dist/team/contracts.d.ts +14 -0
  357. package/dist/team/contracts.d.ts.map +1 -0
  358. package/dist/team/contracts.js +30 -0
  359. package/dist/team/contracts.js.map +1 -0
  360. package/dist/team/model-contract.d.ts +1 -0
  361. package/dist/team/model-contract.d.ts.map +1 -1
  362. package/dist/team/model-contract.js +5 -1
  363. package/dist/team/model-contract.js.map +1 -1
  364. package/dist/team/phase-controller.d.ts +2 -0
  365. package/dist/team/phase-controller.d.ts.map +1 -1
  366. package/dist/team/phase-controller.js +16 -2
  367. package/dist/team/phase-controller.js.map +1 -1
  368. package/dist/team/runtime.d.ts.map +1 -1
  369. package/dist/team/runtime.js +356 -65
  370. package/dist/team/runtime.js.map +1 -1
  371. package/dist/team/scaling.d.ts +58 -0
  372. package/dist/team/scaling.d.ts.map +1 -0
  373. package/dist/team/scaling.js +319 -0
  374. package/dist/team/scaling.js.map +1 -0
  375. package/dist/team/state.d.ts +11 -2
  376. package/dist/team/state.d.ts.map +1 -1
  377. package/dist/team/state.js +97 -27
  378. package/dist/team/state.js.map +1 -1
  379. package/dist/team/team-ops.d.ts +2 -0
  380. package/dist/team/team-ops.d.ts.map +1 -1
  381. package/dist/team/team-ops.js +4 -0
  382. package/dist/team/team-ops.js.map +1 -1
  383. package/dist/team/tmux-session.d.ts +34 -5
  384. package/dist/team/tmux-session.d.ts.map +1 -1
  385. package/dist/team/tmux-session.js +177 -49
  386. package/dist/team/tmux-session.js.map +1 -1
  387. package/dist/team/worker-bootstrap.d.ts.map +1 -1
  388. package/dist/team/worker-bootstrap.js +20 -0
  389. package/dist/team/worker-bootstrap.js.map +1 -1
  390. package/dist/utils/__tests__/paths.test.js +8 -1
  391. package/dist/utils/__tests__/paths.test.js.map +1 -1
  392. package/dist/utils/paths.d.ts.map +1 -1
  393. package/dist/utils/paths.js +14 -6
  394. package/dist/utils/paths.js.map +1 -1
  395. package/dist/verification/__tests__/verifier.test.js +20 -1
  396. package/dist/verification/__tests__/verifier.test.js.map +1 -1
  397. package/dist/verification/verifier.d.ts +5 -0
  398. package/dist/verification/verifier.d.ts.map +1 -1
  399. package/dist/verification/verifier.js +19 -0
  400. package/dist/verification/verifier.js.map +1 -1
  401. package/package.json +2 -1
  402. package/prompts/architect.md +11 -0
  403. package/prompts/critic.md +14 -1
  404. package/prompts/planner.md +21 -0
  405. package/scripts/notify-hook/auto-nudge.js +80 -1
  406. package/scripts/notify-hook/payload-parser.js +21 -0
  407. package/scripts/notify-hook/team-worker.js +142 -0
  408. package/scripts/notify-hook/tmux-injection.js +3 -3
  409. package/scripts/notify-hook.js +55 -4
  410. package/skills/configure-notifications/SKILL.md +278 -0
  411. package/skills/configure-openclaw/SKILL.md +267 -0
  412. package/skills/configure-slack/SKILL.md +226 -0
  413. package/skills/omx-setup/SKILL.md +14 -19
  414. package/skills/plan/SKILL.md +57 -33
  415. package/skills/ralplan/SKILL.md +107 -21
  416. package/skills/team/SKILL.md +10 -1
  417. package/templates/AGENTS.md +11 -3
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consensus-execution-handoff.test.js","sourceRoot":"","sources":["../../../src/hooks/__tests__/consensus-execution-handoff.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=emulator.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emulator.test.d.ts","sourceRoot":"","sources":["../../../src/hooks/__tests__/emulator.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,47 @@
1
+ import { describe, it } from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { HOOK_MAPPING, KEYWORD_TRIGGERS, generateKeywordDetectionSection, } from '../emulator.js';
4
+ const ALL_HOOK_EVENTS = [
5
+ 'SessionStart',
6
+ 'PreToolUse',
7
+ 'PostToolUse',
8
+ 'UserPromptSubmit',
9
+ 'SubagentStart',
10
+ 'SubagentStop',
11
+ 'PreCompact',
12
+ 'Stop',
13
+ 'SessionEnd',
14
+ ];
15
+ describe('hook emulator mapping contracts', () => {
16
+ it('defines mapping metadata for every hook event', () => {
17
+ const mappingKeys = Object.keys(HOOK_MAPPING).sort();
18
+ const expectedKeys = [...ALL_HOOK_EVENTS].sort();
19
+ assert.deepEqual(mappingKeys, expectedKeys);
20
+ for (const event of ALL_HOOK_EVENTS) {
21
+ const mapped = HOOK_MAPPING[event];
22
+ assert.ok(mapped, `missing mapping for ${event}`);
23
+ assert.equal(typeof mapped.mechanism, 'string');
24
+ assert.equal(mapped.mechanism.length > 0, true);
25
+ assert.equal(typeof mapped.notes, 'string');
26
+ assert.equal(mapped.notes.length > 0, true);
27
+ assert.ok(['full', 'partial', 'none'].includes(mapped.capability));
28
+ }
29
+ });
30
+ it('preserves expected session lifecycle capability semantics', () => {
31
+ assert.equal(HOOK_MAPPING.SessionStart.capability, 'full');
32
+ assert.equal(HOOK_MAPPING.Stop.capability, 'full');
33
+ assert.equal(HOOK_MAPPING.SessionEnd.capability, 'partial');
34
+ assert.match(HOOK_MAPPING.SessionStart.mechanism, /AGENTS\.md/i);
35
+ assert.match(HOOK_MAPPING.SessionEnd.mechanism, /postLaunch/i);
36
+ });
37
+ });
38
+ describe('hook emulator keyword guidance generation', () => {
39
+ it('renders every keyword trigger into the generated section', () => {
40
+ const section = generateKeywordDetectionSection();
41
+ for (const [keyword, action] of Object.entries(KEYWORD_TRIGGERS)) {
42
+ assert.match(section, new RegExp(`When user says "${keyword}"`));
43
+ assert.match(section, new RegExp(action.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')));
44
+ }
45
+ });
46
+ });
47
+ //# sourceMappingURL=emulator.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emulator.test.js","sourceRoot":"","sources":["../../../src/hooks/__tests__/emulator.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EACL,YAAY,EACZ,gBAAgB,EAEhB,+BAA+B,GAChC,MAAM,gBAAgB,CAAC;AAExB,MAAM,eAAe,GAAgB;IACnC,cAAc;IACd,YAAY;IACZ,aAAa;IACb,kBAAkB;IAClB,eAAe;IACf,cAAc;IACd,YAAY;IACZ,MAAM;IACN,YAAY;CACb,CAAC;AAEF,QAAQ,CAAC,iCAAiC,EAAE,GAAG,EAAE;IAC/C,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,IAAI,EAAE,CAAC;QACrD,MAAM,YAAY,GAAG,CAAC,GAAG,eAAe,CAAC,CAAC,IAAI,EAAE,CAAC;QACjD,MAAM,CAAC,SAAS,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;QAE5C,KAAK,MAAM,KAAK,IAAI,eAAe,EAAE,CAAC;YACpC,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YACnC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,uBAAuB,KAAK,EAAE,CAAC,CAAC;YAClD,MAAM,CAAC,KAAK,CAAC,OAAO,MAAM,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;YAChD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC;YAChD,MAAM,CAAC,KAAK,CAAC,OAAO,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;YAC5C,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC;YAC5C,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;QACrE,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2DAA2D,EAAE,GAAG,EAAE;QACnE,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QAC3D,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QACnD,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,UAAU,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;QAC5D,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,YAAY,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;QACjE,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,UAAU,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,2CAA2C,EAAE,GAAG,EAAE;IACzD,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;QAClE,MAAM,OAAO,GAAG,+BAA+B,EAAE,CAAC;QAClD,KAAK,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE,CAAC;YACjE,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,MAAM,CAAC,mBAAmB,OAAO,GAAG,CAAC,CAAC,CAAC;YACjE,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;QACnF,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1,7 +1,16 @@
1
- import { describe, it } from 'node:test';
1
+ import { describe, it, mock } from 'node:test';
2
2
  import assert from 'node:assert/strict';
3
- import { detectKeywords, detectPrimaryKeyword } from '../keyword-detector.js';
3
+ import { mkdtemp, mkdir, readFile, rm, writeFile } from 'node:fs/promises';
4
+ import { tmpdir } from 'node:os';
5
+ import { join } from 'node:path';
6
+ import { detectKeywords, detectPrimaryKeyword, recordSkillActivation, SKILL_ACTIVE_STATE_FILE, } from '../keyword-detector.js';
4
7
  import { generateKeywordDetectionSection } from '../emulator.js';
8
+ import { isUnderspecifiedForExecution, applyRalplanGate } from '../keyword-detector.js';
9
+ import { KEYWORD_TRIGGER_DEFINITIONS } from '../keyword-registry.js';
10
+ async function readTemplateKeywords() {
11
+ const section = generateKeywordDetectionSection();
12
+ return [...section.matchAll(/- When user says "([^"]+)":/g)].map((m) => m[1]);
13
+ }
5
14
  describe('keyword detector swarm/team compatibility', () => {
6
15
  it('maps "coordinated team" phrase to team orchestration skill', () => {
7
16
  const match = detectPrimaryKeyword('run a coordinated team for implementation');
@@ -21,19 +30,336 @@ describe('keyword detector swarm/team compatibility', () => {
21
30
  assert.match(match.keyword.toLowerCase(), /swarm/);
22
31
  });
23
32
  it('keeps swarm trigger priority aligned with team trigger', () => {
24
- const teamMatch = detectKeywords('team agents should handle this').find((entry) => entry.skill === 'team');
25
- const swarmMatch = detectKeywords('swarm should handle this').find((entry) => entry.skill === 'team');
33
+ const teamMatch = detectKeywords('use team agents for this').find((entry) => entry.skill === 'team');
34
+ const swarmMatch = detectKeywords('use swarm for this').find((entry) => entry.skill === 'team');
26
35
  assert.ok(teamMatch);
27
36
  assert.ok(swarmMatch);
28
37
  assert.equal(swarmMatch.priority, teamMatch.priority);
29
38
  });
39
+ it('does not trigger team keyword from filesystem/team-state path text', () => {
40
+ const match = detectPrimaryKeyword('You have 1 new message(s). Check .omx/state/team/execute-plan/mailbox/worker-3.json');
41
+ assert.equal(match, null);
42
+ });
43
+ it('does not trigger team skill from incidental prose usage', () => {
44
+ const match = detectPrimaryKeyword('the team reviewed the document and shared feedback');
45
+ assert.equal(match, null);
46
+ });
47
+ it('still triggers team for explicit $team invocation', () => {
48
+ const match = detectPrimaryKeyword('please run $team now');
49
+ assert.ok(match);
50
+ assert.equal(match.skill, 'team');
51
+ });
52
+ it('still triggers swarm for explicit /prompts:swarm invocation', () => {
53
+ const match = detectPrimaryKeyword('use /prompts:swarm for this');
54
+ assert.ok(match);
55
+ assert.equal(match.skill, 'team');
56
+ });
57
+ it('prefers ralplan over ralph when both keywords are present', () => {
58
+ const match = detectPrimaryKeyword('use ralph mode but do ralplan first');
59
+ assert.ok(match);
60
+ assert.equal(match.skill, 'ralplan');
61
+ });
62
+ it('applies longest-match tie-breaker when priorities are equal', () => {
63
+ const match = detectPrimaryKeyword('please run a coordinated swarm for this');
64
+ assert.ok(match);
65
+ assert.equal(match.skill, 'team');
66
+ assert.equal(match.keyword.toLowerCase(), 'coordinated swarm');
67
+ });
30
68
  });
31
69
  describe('keyword detection guidance generation', () => {
70
+ it('keeps template keyword table and runtime keyword registry in sync', async () => {
71
+ const templateKeywords = new Set((await readTemplateKeywords()).map((v) => v.toLowerCase()));
72
+ const registryKeywords = new Set(KEYWORD_TRIGGER_DEFINITIONS.map((v) => v.keyword.toLowerCase()));
73
+ assert.deepEqual([...registryKeywords].sort(), [...templateKeywords].sort());
74
+ });
32
75
  it('includes swarm alias activation guidance', () => {
33
76
  const section = generateKeywordDetectionSection();
34
77
  assert.match(section, /When user says "coordinated team": Activate coordinated team mode/);
35
78
  assert.match(section, /When user says "swarm": Activate coordinated team mode \(swarm is a compatibility alias for team\)/);
36
79
  assert.match(section, /When user says "coordinated swarm": Activate coordinated team mode \(swarm is a compatibility alias for team\)/);
37
80
  });
81
+ it('includes ralplan-first planning gate guidance', () => {
82
+ const section = generateKeywordDetectionSection();
83
+ assert.match(section, /Ralplan-first execution gate:/);
84
+ assert.match(section, /`prd-\*\.md`/);
85
+ assert.match(section, /`test-spec-\*\.md`/);
86
+ assert.match(section, /if ralph is active/i);
87
+ });
88
+ });
89
+ describe('keyword detector skill-active-state lifecycle', () => {
90
+ it('writes skill-active-state.json with planning phase when keyword activates', async () => {
91
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-state-'));
92
+ const stateDir = join(cwd, '.omx', 'state');
93
+ try {
94
+ await mkdir(stateDir, { recursive: true });
95
+ const result = await recordSkillActivation({
96
+ stateDir,
97
+ text: 'please run autopilot and keep going',
98
+ sessionId: 'sess-1',
99
+ threadId: 'thread-1',
100
+ turnId: 'turn-1',
101
+ nowIso: '2026-02-25T00:00:00.000Z',
102
+ });
103
+ assert.ok(result);
104
+ assert.equal(result.skill, 'autopilot');
105
+ assert.equal(result.phase, 'planning');
106
+ assert.equal(result.active, true);
107
+ const persisted = JSON.parse(await readFile(join(stateDir, SKILL_ACTIVE_STATE_FILE), 'utf-8'));
108
+ assert.equal(persisted.skill, 'autopilot');
109
+ assert.equal(persisted.phase, 'planning');
110
+ assert.equal(persisted.active, true);
111
+ }
112
+ finally {
113
+ await rm(cwd, { recursive: true, force: true });
114
+ }
115
+ });
116
+ it('does not write state when no keyword is present', async () => {
117
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-state-none-'));
118
+ const stateDir = join(cwd, '.omx', 'state');
119
+ try {
120
+ await mkdir(stateDir, { recursive: true });
121
+ const result = await recordSkillActivation({
122
+ stateDir,
123
+ text: 'hello there, how are you',
124
+ });
125
+ assert.equal(result, null);
126
+ }
127
+ finally {
128
+ await rm(cwd, { recursive: true, force: true });
129
+ }
130
+ });
131
+ it('emits a warning when skill-active-state persistence fails', async () => {
132
+ const warnings = [];
133
+ mock.method(console, 'warn', (...args) => {
134
+ warnings.push(args);
135
+ });
136
+ const result = await recordSkillActivation({
137
+ stateDir: join('/definitely-missing', 'nested', 'state-dir'),
138
+ text: 'please run autopilot',
139
+ nowIso: '2026-02-25T00:00:00.000Z',
140
+ });
141
+ assert.ok(result);
142
+ assert.equal(result.skill, 'autopilot');
143
+ assert.equal(warnings.length, 1);
144
+ assert.match(String(warnings[0][0]), /failed to persist keyword activation state/);
145
+ });
146
+ it('preserves activated_at for same-skill continuation', async () => {
147
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-state-continuation-'));
148
+ const stateDir = join(cwd, '.omx', 'state');
149
+ const statePath = join(stateDir, SKILL_ACTIVE_STATE_FILE);
150
+ try {
151
+ await mkdir(stateDir, { recursive: true });
152
+ await writeFile(statePath, JSON.stringify({
153
+ version: 1,
154
+ active: true,
155
+ skill: 'autopilot',
156
+ keyword: 'autopilot',
157
+ phase: 'planning',
158
+ activated_at: '2026-02-25T00:00:00.000Z',
159
+ updated_at: '2026-02-25T00:10:00.000Z',
160
+ source: 'keyword-detector',
161
+ }));
162
+ const result = await recordSkillActivation({
163
+ stateDir,
164
+ text: 'autopilot keep going',
165
+ nowIso: '2026-02-26T00:00:00.000Z',
166
+ });
167
+ assert.ok(result);
168
+ assert.equal(result.activated_at, '2026-02-25T00:00:00.000Z');
169
+ assert.equal(result.updated_at, '2026-02-26T00:00:00.000Z');
170
+ }
171
+ finally {
172
+ await rm(cwd, { recursive: true, force: true });
173
+ }
174
+ });
175
+ it('resets activated_at when skill changes', async () => {
176
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-state-skill-switch-'));
177
+ const stateDir = join(cwd, '.omx', 'state');
178
+ const statePath = join(stateDir, SKILL_ACTIVE_STATE_FILE);
179
+ try {
180
+ await mkdir(stateDir, { recursive: true });
181
+ await writeFile(statePath, JSON.stringify({
182
+ version: 1,
183
+ active: true,
184
+ skill: 'autopilot',
185
+ keyword: 'autopilot',
186
+ phase: 'planning',
187
+ activated_at: '2026-02-25T00:00:00.000Z',
188
+ updated_at: '2026-02-25T00:10:00.000Z',
189
+ source: 'keyword-detector',
190
+ }));
191
+ const result = await recordSkillActivation({
192
+ stateDir,
193
+ text: 'please run ralph now',
194
+ nowIso: '2026-02-26T00:00:00.000Z',
195
+ });
196
+ assert.ok(result);
197
+ assert.equal(result.skill, 'ralph');
198
+ assert.equal(result.activated_at, '2026-02-26T00:00:00.000Z');
199
+ }
200
+ finally {
201
+ await rm(cwd, { recursive: true, force: true });
202
+ }
203
+ });
204
+ it('resets activated_at when keyword changes within the same skill', async () => {
205
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-state-keyword-switch-'));
206
+ const stateDir = join(cwd, '.omx', 'state');
207
+ const statePath = join(stateDir, SKILL_ACTIVE_STATE_FILE);
208
+ try {
209
+ await mkdir(stateDir, { recursive: true });
210
+ await writeFile(statePath, JSON.stringify({
211
+ version: 1,
212
+ active: true,
213
+ skill: 'autopilot',
214
+ keyword: 'autopilot',
215
+ phase: 'planning',
216
+ activated_at: '2026-02-25T00:00:00.000Z',
217
+ updated_at: '2026-02-25T00:10:00.000Z',
218
+ source: 'keyword-detector',
219
+ }));
220
+ const result = await recordSkillActivation({
221
+ stateDir,
222
+ text: 'I want a starter API',
223
+ nowIso: '2026-02-26T00:00:00.000Z',
224
+ });
225
+ assert.ok(result);
226
+ assert.equal(result.skill, 'autopilot');
227
+ assert.notEqual(result.keyword.toLowerCase(), 'autopilot');
228
+ assert.equal(result.activated_at, '2026-02-26T00:00:00.000Z');
229
+ }
230
+ finally {
231
+ await rm(cwd, { recursive: true, force: true });
232
+ }
233
+ });
234
+ });
235
+ describe('isUnderspecifiedForExecution', () => {
236
+ it('flags vague prompt with no files or functions', () => {
237
+ assert.equal(isUnderspecifiedForExecution('ralph fix this'), true);
238
+ });
239
+ it('flags short vague prompt', () => {
240
+ assert.equal(isUnderspecifiedForExecution('autopilot build the app'), true);
241
+ });
242
+ it('flags prompt with only keyword and generic words', () => {
243
+ assert.equal(isUnderspecifiedForExecution('team improve performance'), true);
244
+ });
245
+ it('passes prompt with a file path reference', () => {
246
+ assert.equal(isUnderspecifiedForExecution('ralph fix src/hooks/bridge.ts'), false);
247
+ });
248
+ it('passes prompt with a file extension reference', () => {
249
+ assert.equal(isUnderspecifiedForExecution('fix the bug in auth.ts'), false);
250
+ });
251
+ it('passes prompt with a directory/file path', () => {
252
+ assert.equal(isUnderspecifiedForExecution('update src/hooks/emulator.ts'), false);
253
+ });
254
+ it('passes prompt with a camelCase symbol', () => {
255
+ assert.equal(isUnderspecifiedForExecution('team fix processKeywordDetector'), false);
256
+ });
257
+ it('passes prompt with a PascalCase symbol', () => {
258
+ assert.equal(isUnderspecifiedForExecution('ralph update UserModel'), false);
259
+ });
260
+ it('passes prompt with snake_case symbol', () => {
261
+ assert.equal(isUnderspecifiedForExecution('fix user_model validation'), false);
262
+ });
263
+ it('passes prompt with an issue number', () => {
264
+ assert.equal(isUnderspecifiedForExecution('autopilot implement #42'), false);
265
+ });
266
+ it('passes prompt with numbered steps', () => {
267
+ assert.equal(isUnderspecifiedForExecution('ralph do:\n1. Add input validation\n2. Write tests\n3. Update README'), false);
268
+ });
269
+ it('passes prompt with acceptance criteria keyword', () => {
270
+ assert.equal(isUnderspecifiedForExecution('add login - acceptance criteria: user sees error on bad password'), false);
271
+ });
272
+ it('passes prompt with a specific error reference', () => {
273
+ assert.equal(isUnderspecifiedForExecution('ralph fix TypeError in auth handler'), false);
274
+ });
275
+ it('passes with force: escape hatch prefix', () => {
276
+ assert.equal(isUnderspecifiedForExecution('force: ralph refactor the auth module'), false);
277
+ });
278
+ it('passes with ! escape hatch prefix', () => {
279
+ assert.equal(isUnderspecifiedForExecution('! autopilot optimize everything'), false);
280
+ });
281
+ it('returns true for empty string', () => {
282
+ assert.equal(isUnderspecifiedForExecution(''), true);
283
+ });
284
+ it('returns true for whitespace only', () => {
285
+ assert.equal(isUnderspecifiedForExecution(' '), true);
286
+ });
287
+ it('passes prompt with test runner command', () => {
288
+ assert.equal(isUnderspecifiedForExecution('ralph npm test && fix failures'), false);
289
+ });
290
+ it('passes longer prompt that exceeds word threshold', () => {
291
+ // 16+ effective words without specific signals → passes (not underspecified by word count)
292
+ const longVague = 'please help me improve the overall quality and performance and reliability of this system going forward';
293
+ assert.equal(isUnderspecifiedForExecution(longVague), false);
294
+ });
295
+ it('false positive prevention: camelCase identifiers pass', () => {
296
+ assert.equal(isUnderspecifiedForExecution('fix getUserById to handle null'), false);
297
+ });
298
+ });
299
+ describe('applyRalplanGate', () => {
300
+ it('redirects underspecified execution keywords to ralplan', () => {
301
+ const result = applyRalplanGate(['ralph'], 'ralph fix this');
302
+ assert.equal(result.gateApplied, true);
303
+ assert.ok(result.keywords.includes('ralplan'));
304
+ assert.ok(!result.keywords.includes('ralph'));
305
+ });
306
+ it('redirects autopilot to ralplan when underspecified', () => {
307
+ const result = applyRalplanGate(['autopilot'], 'autopilot build the app');
308
+ assert.equal(result.gateApplied, true);
309
+ assert.ok(result.keywords.includes('ralplan'));
310
+ });
311
+ it('does not gate well-specified prompts', () => {
312
+ const result = applyRalplanGate(['ralph'], 'ralph fix src/hooks/bridge.ts null check');
313
+ assert.equal(result.gateApplied, false);
314
+ assert.ok(result.keywords.includes('ralph'));
315
+ });
316
+ it('does not gate when cancel is present', () => {
317
+ const result = applyRalplanGate(['cancel', 'ralph'], 'cancel ralph');
318
+ assert.equal(result.gateApplied, false);
319
+ });
320
+ it('does not gate when ralplan is already present', () => {
321
+ const result = applyRalplanGate(['ralplan'], 'ralplan add auth');
322
+ assert.equal(result.gateApplied, false);
323
+ assert.ok(result.keywords.includes('ralplan'));
324
+ });
325
+ it('does not gate non-execution keywords', () => {
326
+ const result = applyRalplanGate(['analyze'], 'analyze this');
327
+ assert.equal(result.gateApplied, false);
328
+ });
329
+ it('preserves non-execution keywords when gating', () => {
330
+ const result = applyRalplanGate(['ralph', 'tdd'], 'ralph tdd fix this');
331
+ assert.equal(result.gateApplied, true);
332
+ assert.ok(result.keywords.includes('tdd'));
333
+ assert.ok(result.keywords.includes('ralplan'));
334
+ assert.ok(!result.keywords.includes('ralph'));
335
+ });
336
+ it('handles force: escape hatch — does not gate', () => {
337
+ const result = applyRalplanGate(['ralph'], 'force: ralph refactor the auth module');
338
+ assert.equal(result.gateApplied, false);
339
+ });
340
+ it('gates multiple execution keywords at once', () => {
341
+ const result = applyRalplanGate(['ralph', 'team'], 'ralph team fix this');
342
+ assert.equal(result.gateApplied, true);
343
+ assert.ok(result.keywords.includes('ralplan'));
344
+ assert.ok(!result.keywords.includes('ralph'));
345
+ assert.ok(!result.keywords.includes('team'));
346
+ assert.ok(result.gatedKeywords.includes('ralph'));
347
+ assert.ok(result.gatedKeywords.includes('team'));
348
+ });
349
+ it('returns empty keywords unchanged when no keywords', () => {
350
+ const result = applyRalplanGate([], 'fix this');
351
+ assert.equal(result.gateApplied, false);
352
+ assert.deepEqual(result.keywords, []);
353
+ });
354
+ it('does not duplicate ralplan if already in filtered list', () => {
355
+ // ultrawork is an execution keyword; after filtering, ralplan added once
356
+ const result = applyRalplanGate(['ultrawork'], 'ultrawork do stuff');
357
+ assert.equal(result.keywords.filter(k => k === 'ralplan').length, 1);
358
+ });
359
+ it('reports gatedKeywords correctly', () => {
360
+ const result = applyRalplanGate(['ralph', 'ultrawork'], 'ralph ultrawork build');
361
+ assert.ok(result.gatedKeywords.includes('ralph'));
362
+ assert.ok(result.gatedKeywords.includes('ultrawork'));
363
+ });
38
364
  });
39
365
  //# sourceMappingURL=keyword-detector.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"keyword-detector.test.js","sourceRoot":"","sources":["../../../src/hooks/__tests__/keyword-detector.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9E,OAAO,EAAE,+BAA+B,EAAE,MAAM,gBAAgB,CAAC;AAEjE,QAAQ,CAAC,2CAA2C,EAAE,GAAG,EAAE;IACzD,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;QACpE,MAAM,KAAK,GAAG,oBAAoB,CAAC,2CAA2C,CAAC,CAAC;QAEhF,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;QACjB,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAClC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,MAAM,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,KAAK,GAAG,oBAAoB,CAAC,gCAAgC,CAAC,CAAC;QAErE,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;QACjB,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6DAA6D,EAAE,GAAG,EAAE;QACrE,MAAM,KAAK,GAAG,oBAAoB,CAAC,4CAA4C,CAAC,CAAC;QAEjF,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;QACjB,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAClC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,OAAO,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;QAChE,MAAM,SAAS,GAAG,cAAc,CAAC,gCAAgC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC;QAC3G,MAAM,UAAU,GAAG,cAAc,CAAC,0BAA0B,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC;QAEtG,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;QACrB,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC;QACtB,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,QAAQ,EAAE,SAAS,CAAC,QAAQ,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,uCAAuC,EAAE,GAAG,EAAE;IACrD,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,OAAO,GAAG,+BAA+B,EAAE,CAAC;QAElD,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,mEAAmE,CAAC,CAAC;QAC3F,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,oGAAoG,CAAC,CAAC;QAC5H,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,gHAAgH,CAAC,CAAC;IAC1I,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"keyword-detector.test.js","sourceRoot":"","sources":["../../../src/hooks/__tests__/keyword-detector.test.ts"],"names":[],"mappings":"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"}
@@ -275,6 +275,107 @@ describe('notify-hook auto-nudge', () => {
275
275
  assert.ok(nudgeState.lastNudgeAt, 'should have lastNudgeAt timestamp');
276
276
  });
277
277
  });
278
+ it('writes skill-active-state.json when keyword activation is detected', async () => {
279
+ await withTempWorkingDir(async (cwd) => {
280
+ const omxDir = join(cwd, '.omx');
281
+ const stateDir = join(omxDir, 'state');
282
+ const logsDir = join(omxDir, 'logs');
283
+ const codexHome = join(cwd, 'codex-home');
284
+ const fakeBinDir = join(cwd, 'fake-bin');
285
+ await mkdir(logsDir, { recursive: true });
286
+ await mkdir(stateDir, { recursive: true });
287
+ await mkdir(codexHome, { recursive: true });
288
+ await mkdir(fakeBinDir, { recursive: true });
289
+ await writeJson(join(codexHome, '.omx-config.json'), {
290
+ autoNudge: { enabled: true, delaySec: 0 },
291
+ });
292
+ await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(join(cwd, 'tmux.log')));
293
+ await chmod(join(fakeBinDir, 'tmux'), 0o755);
294
+ const result = runNotifyHook(cwd, fakeBinDir, codexHome, {
295
+ 'input-messages': ['please use autopilot for this task'],
296
+ 'last-assistant-message': 'Here is the plan I will follow.',
297
+ });
298
+ assert.equal(result.status, 0, `hook failed: ${result.stderr || result.stdout}`);
299
+ const skillStatePath = join(stateDir, 'skill-active-state.json');
300
+ assert.ok(existsSync(skillStatePath), 'skill-active-state.json should be created');
301
+ const skillState = JSON.parse(await readFile(skillStatePath, 'utf-8'));
302
+ assert.equal(skillState.skill, 'autopilot');
303
+ assert.equal(skillState.phase, 'planning');
304
+ assert.equal(skillState.active, true);
305
+ });
306
+ });
307
+ it('still auto-nudges stall phrases when skill-active state is stale completing', async () => {
308
+ await withTempWorkingDir(async (cwd) => {
309
+ const omxDir = join(cwd, '.omx');
310
+ const stateDir = join(omxDir, 'state');
311
+ const logsDir = join(omxDir, 'logs');
312
+ const codexHome = join(cwd, 'codex-home');
313
+ const fakeBinDir = join(cwd, 'fake-bin');
314
+ const tmuxLogPath = join(cwd, 'tmux.log');
315
+ await mkdir(logsDir, { recursive: true });
316
+ await mkdir(stateDir, { recursive: true });
317
+ await mkdir(codexHome, { recursive: true });
318
+ await mkdir(fakeBinDir, { recursive: true });
319
+ await writeJson(join(codexHome, '.omx-config.json'), {
320
+ autoNudge: { enabled: true, delaySec: 0 },
321
+ });
322
+ await writeJson(join(stateDir, 'skill-active-state.json'), {
323
+ version: 1,
324
+ active: false,
325
+ skill: 'autopilot',
326
+ keyword: 'autopilot',
327
+ phase: 'completing',
328
+ activated_at: '2026-02-25T00:00:00.000Z',
329
+ updated_at: '2026-02-25T00:00:00.000Z',
330
+ source: 'keyword-detector',
331
+ });
332
+ await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(tmuxLogPath));
333
+ await chmod(join(fakeBinDir, 'tmux'), 0o755);
334
+ const result = runNotifyHook(cwd, fakeBinDir, codexHome, {
335
+ 'last-assistant-message': 'I can finish the cleanup too, if you want.',
336
+ });
337
+ assert.equal(result.status, 0, `hook failed: ${result.stderr || result.stdout}`);
338
+ const tmuxLog = await readFile(tmuxLogPath, 'utf-8');
339
+ assert.match(tmuxLog, /send-keys -t %99 -l yes, proceed \[OMX_TMUX_INJECT\]/, 'should still nudge when completion phase is stale but message has a stall phrase');
340
+ });
341
+ });
342
+ it('does not auto-nudge for true completion text when skill-active state is completing', async () => {
343
+ await withTempWorkingDir(async (cwd) => {
344
+ const omxDir = join(cwd, '.omx');
345
+ const stateDir = join(omxDir, 'state');
346
+ const logsDir = join(omxDir, 'logs');
347
+ const codexHome = join(cwd, 'codex-home');
348
+ const fakeBinDir = join(cwd, 'fake-bin');
349
+ const tmuxLogPath = join(cwd, 'tmux.log');
350
+ await mkdir(logsDir, { recursive: true });
351
+ await mkdir(stateDir, { recursive: true });
352
+ await mkdir(codexHome, { recursive: true });
353
+ await mkdir(fakeBinDir, { recursive: true });
354
+ await writeJson(join(codexHome, '.omx-config.json'), {
355
+ autoNudge: { enabled: true, delaySec: 0 },
356
+ });
357
+ await writeJson(join(stateDir, 'skill-active-state.json'), {
358
+ version: 1,
359
+ active: false,
360
+ skill: 'autopilot',
361
+ keyword: 'autopilot',
362
+ phase: 'completing',
363
+ activated_at: '2026-02-25T00:00:00.000Z',
364
+ updated_at: '2026-02-25T00:00:00.000Z',
365
+ source: 'keyword-detector',
366
+ });
367
+ await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(tmuxLogPath));
368
+ await chmod(join(fakeBinDir, 'tmux'), 0o755);
369
+ const result = runNotifyHook(cwd, fakeBinDir, codexHome, {
370
+ 'last-assistant-message': 'I completed the refactoring. All tests pass.',
371
+ });
372
+ assert.equal(result.status, 0, `hook failed: ${result.stderr || result.stdout}`);
373
+ if (existsSync(tmuxLogPath)) {
374
+ const tmuxLog = await readFile(tmuxLogPath, 'utf-8');
375
+ assert.doesNotMatch(tmuxLog, /send-keys -t %99 -l/, 'should remain quiet for true completion text');
376
+ }
377
+ });
378
+ });
278
379
  it('detects all default stall patterns case-insensitively', async () => {
279
380
  const patterns = [
280
381
  'If You Want me to make changes',