oh-my-codex 0.6.4 → 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 (416) 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 +156 -8
  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 +353 -66
  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 +10 -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 +18 -4
  384. package/dist/team/tmux-session.d.ts.map +1 -1
  385. package/dist/team/tmux-session.js +110 -32
  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/templates/AGENTS.md +11 -3
@@ -44,6 +44,7 @@ import {
44
44
  resolveTeamStateDirForWorker,
45
45
  updateWorkerHeartbeat,
46
46
  maybeNotifyLeaderAllWorkersIdle,
47
+ maybeNotifyLeaderWorkerIdle,
47
48
  } from './notify-hook/team-worker.js';
48
49
  import { DEFAULT_MARKER } from './tmux-hook-engine.js';
49
50
 
@@ -129,8 +130,27 @@ async function main() {
129
130
  const statePath = join(scopedDir, f);
130
131
  const state = JSON.parse(await readFile(statePath, 'utf-8'));
131
132
  if (state.active) {
132
- state.iteration = (state.iteration || 0) + 1;
133
- state.last_turn_at = new Date().toISOString();
133
+ const nowIso = new Date().toISOString();
134
+ const nextIteration = (state.iteration || 0) + 1;
135
+ state.iteration = nextIteration;
136
+ state.last_turn_at = nowIso;
137
+
138
+ const maxIterations = asNumber(state.max_iterations);
139
+ if (maxIterations !== null && maxIterations > 0 && nextIteration >= maxIterations) {
140
+ state.active = false;
141
+ if (typeof state.current_phase !== 'string' || !state.current_phase.trim()) {
142
+ state.current_phase = 'complete';
143
+ } else if (!['cancelled', 'failed', 'complete'].includes(state.current_phase)) {
144
+ state.current_phase = 'complete';
145
+ }
146
+ if (typeof state.completed_at !== 'string' || !state.completed_at) {
147
+ state.completed_at = nowIso;
148
+ }
149
+ if (typeof state.stop_reason !== 'string' || !state.stop_reason) {
150
+ state.stop_reason = 'max_iterations_reached';
151
+ }
152
+ }
153
+
134
154
  await writeFile(statePath, JSON.stringify(state, null, 2));
135
155
  }
136
156
  }
@@ -248,6 +268,15 @@ async function main() {
248
268
  }
249
269
  }
250
270
 
271
+ // 4.55. Notify leader when individual worker transitions to idle (worker session only)
272
+ if (isTeamWorker && parsedTeamWorker) {
273
+ try {
274
+ await maybeNotifyLeaderWorkerIdle({ cwd, stateDir, logsDir, parsedTeamWorker });
275
+ } catch {
276
+ // Non-critical
277
+ }
278
+ }
279
+
251
280
  // 4.6. Notify leader when all workers are idle (worker session only)
252
281
  if (isTeamWorker && parsedTeamWorker) {
253
282
  try {
@@ -300,6 +329,7 @@ async function main() {
300
329
  if (!isTeamWorker) {
301
330
  try {
302
331
  const { notifyLifecycle } = await import('../dist/notifications/index.js');
332
+ const { shouldSendIdleNotification, recordIdleNotificationSent } = await import('../dist/notifications/idle-cooldown.js');
303
333
  const sessionJsonPath = join(stateDir, 'session.json');
304
334
  let notifySessionId = '';
305
335
  try {
@@ -307,11 +337,14 @@ async function main() {
307
337
  notifySessionId = safeString(sessionData && sessionData.session_id ? sessionData.session_id : '');
308
338
  } catch { /* no session file */ }
309
339
 
310
- if (notifySessionId) {
311
- await notifyLifecycle('session-idle', {
340
+ if (notifySessionId && shouldSendIdleNotification(stateDir, notifySessionId)) {
341
+ const idleResult = await notifyLifecycle('session-idle', {
312
342
  sessionId: notifySessionId,
313
343
  projectPath: cwd,
314
344
  });
345
+ if (idleResult && idleResult.anySuccess) {
346
+ recordIdleNotificationSent(stateDir, notifySessionId);
347
+ }
315
348
  try {
316
349
  const { buildNativeHookEvent } = await import('../dist/hooks/extensibility/events.js');
317
350
  const { dispatchHookEvent } = await import('../dist/hooks/extensibility/dispatcher.js');
@@ -334,6 +367,24 @@ async function main() {
334
367
  }
335
368
  }
336
369
 
370
+ // 8.5. Skill activation tracking: update skill-active-state.json when a keyword is detected.
371
+ try {
372
+ const { recordSkillActivation } = await import('../dist/hooks/keyword-detector.js');
373
+ const inputMessages = normalizeInputMessages(payload);
374
+ const latestUserInput = safeString(inputMessages.length > 0 ? inputMessages[inputMessages.length - 1] : '');
375
+ if (latestUserInput) {
376
+ await recordSkillActivation({
377
+ stateDir,
378
+ text: latestUserInput,
379
+ sessionId: payloadSessionId,
380
+ threadId: safeString(payload['thread-id'] || payload.thread_id || ''),
381
+ turnId: safeString(payload['turn-id'] || payload.turn_id || ''),
382
+ });
383
+ }
384
+ } catch {
385
+ // Non-fatal: keyword detector module may not be built yet
386
+ }
387
+
337
388
  // 9. Auto-nudge: detect Codex stall patterns and automatically send a continuation prompt.
338
389
  // Works for both leader and worker contexts.
339
390
  try {
@@ -0,0 +1,278 @@
1
+ ---
2
+ name: configure-notifications
3
+ description: Configure OMX notifications - unified entry point for all platforms
4
+ triggers:
5
+ - "configure notifications"
6
+ - "setup notifications"
7
+ - "notification settings"
8
+ - "configure discord"
9
+ - "configure telegram"
10
+ - "configure slack"
11
+ - "configure openclaw"
12
+ - "setup discord"
13
+ - "setup telegram"
14
+ - "setup slack"
15
+ - "setup openclaw"
16
+ - "discord notifications"
17
+ - "telegram notifications"
18
+ - "slack notifications"
19
+ - "openclaw notifications"
20
+ - "discord webhook"
21
+ - "telegram bot"
22
+ - "slack webhook"
23
+ ---
24
+
25
+ # Configure OMX Notifications
26
+
27
+ Unified entry point for setting up notifications across all supported platforms.
28
+ OMX can notify you on Discord, Telegram, Slack, or your own OpenClaw gateway.
29
+
30
+ ## How This Skill Works
31
+
32
+ This skill detects what's already configured, presents a menu, and delegates to the
33
+ appropriate platform skill. It also handles cross-cutting settings like verbosity,
34
+ notification profiles, reply listener, and idle cooldown.
35
+
36
+ ## Step 1: Detect Currently Configured Platforms
37
+
38
+ ```bash
39
+ CONFIG_FILE="$HOME/.codex/.omx-config.json"
40
+
41
+ if [ -f "$CONFIG_FILE" ]; then
42
+ DISCORD_ENABLED=$(jq -r '.notifications.discord.enabled // false' "$CONFIG_FILE" 2>/dev/null)
43
+ DISCORD_BOT_ENABLED=$(jq -r '.notifications["discord-bot"].enabled // false' "$CONFIG_FILE" 2>/dev/null)
44
+ TELEGRAM_ENABLED=$(jq -r '.notifications.telegram.enabled // false' "$CONFIG_FILE" 2>/dev/null)
45
+ SLACK_ENABLED=$(jq -r '.notifications.slack.enabled // false' "$CONFIG_FILE" 2>/dev/null)
46
+ OPENCLAW_ENABLED=$(jq -r '.notifications.openclaw.enabled // false' "$CONFIG_FILE" 2>/dev/null)
47
+ NOTIF_ENABLED=$(jq -r '.notifications.enabled // false' "$CONFIG_FILE" 2>/dev/null)
48
+ VERBOSITY=$(jq -r '.notifications.verbosity // "session"' "$CONFIG_FILE" 2>/dev/null)
49
+ COOLDOWN=$(jq -r '.notifications.idleCooldownSeconds // 60' "$CONFIG_FILE" 2>/dev/null)
50
+ REPLY_ENABLED=$(jq -r '.notifications.reply.enabled // false' "$CONFIG_FILE" 2>/dev/null)
51
+
52
+ echo "NOTIF_ENABLED=$NOTIF_ENABLED"
53
+ echo "DISCORD_ENABLED=$DISCORD_ENABLED"
54
+ echo "DISCORD_BOT_ENABLED=$DISCORD_BOT_ENABLED"
55
+ echo "TELEGRAM_ENABLED=$TELEGRAM_ENABLED"
56
+ echo "SLACK_ENABLED=$SLACK_ENABLED"
57
+ echo "OPENCLAW_ENABLED=$OPENCLAW_ENABLED"
58
+ echo "VERBOSITY=$VERBOSITY"
59
+ echo "COOLDOWN=$COOLDOWN"
60
+ echo "REPLY_ENABLED=$REPLY_ENABLED"
61
+ else
62
+ echo "NO_CONFIG_FILE"
63
+ fi
64
+ ```
65
+
66
+ ## Step 2: Show Current Status and Main Menu
67
+
68
+ Display a summary of what's configured:
69
+
70
+ ```
71
+ OMX Notification Status
72
+ ───────────────────────
73
+ Discord webhook: enabled / not configured
74
+ Discord bot: enabled / not configured
75
+ Telegram: enabled / not configured
76
+ Slack: enabled / not configured
77
+ OpenClaw: enabled / not configured
78
+
79
+ Verbosity: session (default)
80
+ Idle cooldown: 60s
81
+ Reply listener: disabled
82
+ ```
83
+
84
+ Then use AskUserQuestion:
85
+
86
+ **Question:** "What would you like to configure?"
87
+
88
+ **Options:**
89
+ 1. **Discord** - Webhook or bot notifications to Discord channels
90
+ 2. **Telegram** - Bot notifications to personal or group chats
91
+ 3. **Slack** - Incoming webhook notifications to Slack channels
92
+ 4. **OpenClaw** - Self-hosted HTTP or CLI command gateway
93
+ 5. **Cross-cutting settings** - Verbosity, idle cooldown, profiles, reply listener
94
+ 6. **Disable all notifications** - Turn off all notification dispatching
95
+
96
+ ## Step 3: Delegate to Platform Skill
97
+
98
+ Based on the user's choice, invoke the appropriate platform skill:
99
+
100
+ - **Discord** → invoke `/configure-discord`
101
+ - **Telegram** → invoke `/configure-telegram`
102
+ - **Slack** → invoke `/configure-slack`
103
+ - **OpenClaw** → invoke `/configure-openclaw`
104
+ - **Cross-cutting settings** → continue with Step 4 below
105
+ - **Disable all** → continue with Step 5 below
106
+
107
+ When delegating, say: "Starting the [Platform] configuration wizard..." and invoke the skill.
108
+
109
+ ## Step 4: Cross-Cutting Settings
110
+
111
+ If the user chose "Cross-cutting settings":
112
+
113
+ ### 4a. Verbosity
114
+
115
+ Use AskUserQuestion:
116
+
117
+ **Question:** "How verbose should notifications be?"
118
+
119
+ **Options:**
120
+ 1. **session (Recommended)** - Start, idle, stop, end events + tmux snippet
121
+ 2. **minimal** - Start, stop, end only (no idle events, no tmux tail)
122
+ 3. **agent** - All session events plus ask-user-question prompts
123
+ 4. **verbose** - Everything including tool call output
124
+
125
+ Write verbosity to config:
126
+
127
+ ```bash
128
+ echo "$(cat "$CONFIG_FILE")" | jq \
129
+ --arg verbosity "$VERBOSITY" \
130
+ '.notifications.verbosity = $verbosity' > "$CONFIG_FILE"
131
+ ```
132
+
133
+ Env var alternative: `OMX_NOTIFY_VERBOSITY=session`
134
+
135
+ ### 4b. Idle Notification Cooldown
136
+
137
+ Use AskUserQuestion:
138
+
139
+ **Question:** "How often should idle notifications fire at most? (in seconds)"
140
+
141
+ **Options:**
142
+ 1. **60 seconds (default)** - At most once per minute
143
+ 2. **300 seconds** - At most once per 5 minutes
144
+ 3. **0 (disabled)** - Send every turn with no throttling
145
+ 4. **Custom** - Enter a number of seconds
146
+
147
+ Write the cooldown to config:
148
+
149
+ ```bash
150
+ echo "$(cat "$CONFIG_FILE")" | jq \
151
+ --argjson cooldown "$COOLDOWN_SECONDS" \
152
+ '.notifications.idleCooldownSeconds = $cooldown' > "$CONFIG_FILE"
153
+ ```
154
+
155
+ Env var alternative: `OMX_IDLE_COOLDOWN_SECONDS=60`
156
+
157
+ ### 4c. Notification Profiles
158
+
159
+ Explain that profiles let the user have different notification configs per context:
160
+
161
+ ```
162
+ Notification Profiles
163
+ ─────────────────────
164
+ Profiles let you switch notification targets based on context.
165
+ For example: a "work" profile for your work Slack, a "personal"
166
+ profile for your personal Telegram.
167
+
168
+ Activate a profile with: OMX_NOTIFY_PROFILE=work
169
+ or set a default: .omx-config.json > notifications.defaultProfile
170
+ ```
171
+
172
+ Use AskUserQuestion:
173
+
174
+ **Question:** "Would you like to configure notification profiles?"
175
+
176
+ **Options:**
177
+ 1. **Yes** - Set up named profiles
178
+ 2. **No, use flat config** - Keep the current single-config setup
179
+
180
+ If yes, guide the user to manually add profiles under `notifications.profiles` in `.omx-config.json`, and set `defaultProfile`.
181
+
182
+ ### 4d. Reply Listener
183
+
184
+ Explain the reply listener:
185
+
186
+ ```
187
+ Reply Listener
188
+ ──────────────
189
+ The reply listener lets you send messages back to Codex from
190
+ Discord (bot) or Telegram. When OMX asks for input, you can
191
+ reply directly from your phone or messaging app.
192
+
193
+ Requires:
194
+ - Discord Bot or Telegram platform configured
195
+ - OMX_REPLY_ENABLED=true in your shell profile
196
+ - For Discord: OMX_REPLY_DISCORD_USER_IDS=<your user ID>
197
+ (only messages from these IDs are accepted for security)
198
+ ```
199
+
200
+ Use AskUserQuestion:
201
+
202
+ **Question:** "Would you like to enable the reply listener?"
203
+
204
+ **Options:**
205
+ 1. **Yes** - Enable two-way communication from Discord/Telegram
206
+ 2. **No** - Keep notifications one-way only
207
+
208
+ If yes, write to config:
209
+
210
+ ```bash
211
+ echo "$(cat "$CONFIG_FILE")" | jq \
212
+ '.notifications.reply = (.notifications.reply // {}) |
213
+ .notifications.reply.enabled = true' > "$CONFIG_FILE"
214
+ ```
215
+
216
+ And remind them to set `OMX_REPLY_ENABLED=true` and (for Discord) `OMX_REPLY_DISCORD_USER_IDS`.
217
+
218
+ ## Step 5: Disable All Notifications
219
+
220
+ If the user chose "Disable all notifications":
221
+
222
+ Use AskUserQuestion:
223
+
224
+ **Question:** "Are you sure you want to disable all notifications?"
225
+
226
+ **Options:**
227
+ 1. **Yes, disable all** - Set notifications.enabled = false
228
+ 2. **No, go back** - Return to the main menu
229
+
230
+ If confirmed:
231
+
232
+ ```bash
233
+ echo "$(cat "$CONFIG_FILE")" | jq \
234
+ '.notifications.enabled = false' > "$CONFIG_FILE"
235
+ ```
236
+
237
+ Confirm: "Notifications disabled. Re-enable anytime by running /configure-notifications."
238
+
239
+ ## Step 6: After Configuration
240
+
241
+ After completing any platform or setting configuration, offer to configure another:
242
+
243
+ Use AskUserQuestion:
244
+
245
+ **Question:** "Would you like to configure another platform or setting?"
246
+
247
+ **Options:**
248
+ 1. **Yes** - Return to the main menu (Step 2)
249
+ 2. **No, I'm done** - Show final summary and exit
250
+
251
+ ## Final Summary
252
+
253
+ Display a summary of all active notification platforms:
254
+
255
+ ```
256
+ OMX Notification Configuration Complete!
257
+ ─────────────────────────────────────────
258
+ Active platforms:
259
+ Discord webhook: enabled
260
+ Telegram: enabled
261
+
262
+ Verbosity: session
263
+ Idle cooldown: 60s
264
+ Reply listener: disabled
265
+
266
+ Config saved to: ~/.codex/.omx-config.json
267
+
268
+ Quick reference — env vars:
269
+ OMX_DISCORD_WEBHOOK_URL=...
270
+ OMX_TELEGRAM_BOT_TOKEN=...
271
+ OMX_TELEGRAM_CHAT_ID=...
272
+ OMX_SLACK_WEBHOOK_URL=...
273
+ OMX_NOTIFY_VERBOSITY=session
274
+ OMX_IDLE_COOLDOWN_SECONDS=60
275
+ OMX_OPENCLAW=1
276
+
277
+ Run /configure-notifications again to update any settings.
278
+ ```
@@ -0,0 +1,267 @@
1
+ ---
2
+ name: configure-openclaw
3
+ description: Configure OpenClaw notification gateway via natural language
4
+ triggers:
5
+ - "configure openclaw"
6
+ - "setup openclaw"
7
+ - "openclaw notifications"
8
+ - "openclaw gateway"
9
+ ---
10
+
11
+ # Configure OpenClaw Notifications
12
+
13
+ Set up OpenClaw as a notification gateway so OMX can route session events through your own HTTP endpoint or CLI command.
14
+
15
+ ## What is OpenClaw?
16
+
17
+ OpenClaw is a self-hosted notification gateway that lets you receive OMX events however you want — HTTP webhooks to your own server, shell commands, or any integration you build. Unlike platform-specific notifiers (Discord, Slack), OpenClaw gives you full control over message routing and format.
18
+
19
+ **Two gateway modes:**
20
+ - **HTTP Gateway** — OMX POSTs JSON events to your HTTP endpoint
21
+ - **CLI Command Gateway** — OMX runs a shell command with event data as arguments or stdin
22
+
23
+ ## How This Skill Works
24
+
25
+ This is an interactive, natural-language configuration skill. Walk the user through setup by asking questions with AskUserQuestion. Write the result to `~/.codex/.omx-config.json`.
26
+
27
+ ## Step 1: Detect Existing Configuration
28
+
29
+ ```bash
30
+ CONFIG_FILE="$HOME/.codex/.omx-config.json"
31
+
32
+ if [ -f "$CONFIG_FILE" ]; then
33
+ HAS_OPENCLAW=$(jq -r '.notifications.openclaw.enabled // false' "$CONFIG_FILE" 2>/dev/null)
34
+ GATEWAY_TYPE=$(jq -r '.notifications.openclaw.gatewayType // empty' "$CONFIG_FILE" 2>/dev/null)
35
+ ENDPOINT=$(jq -r '.notifications.openclaw.endpoint // empty' "$CONFIG_FILE" 2>/dev/null)
36
+ COMMAND=$(jq -r '.notifications.openclaw.command // empty' "$CONFIG_FILE" 2>/dev/null)
37
+
38
+ if [ "$HAS_OPENCLAW" = "true" ]; then
39
+ echo "EXISTING_CONFIG=true"
40
+ echo "GATEWAY_TYPE=$GATEWAY_TYPE"
41
+ [ -n "$ENDPOINT" ] && echo "ENDPOINT=$ENDPOINT"
42
+ [ -n "$COMMAND" ] && echo "COMMAND=$COMMAND"
43
+ else
44
+ echo "EXISTING_CONFIG=false"
45
+ fi
46
+ else
47
+ echo "NO_CONFIG_FILE"
48
+ fi
49
+ ```
50
+
51
+ If existing config is found, show the user what's currently configured and ask if they want to update or reconfigure.
52
+
53
+ ## Step 2: Choose Gateway Type
54
+
55
+ Use AskUserQuestion:
56
+
57
+ **Question:** "Which OpenClaw gateway mode do you want to use?"
58
+
59
+ **Options:**
60
+ 1. **HTTP Gateway** - OMX sends a POST request with JSON to your endpoint. Good for web servers, n8n, Zapier webhooks, or any HTTP-capable service.
61
+ 2. **CLI Command Gateway** - OMX runs a shell command you specify. Good for local scripts, custom notification tools, or anything shell-scriptable.
62
+
63
+ ## Step 3A: HTTP Gateway Setup
64
+
65
+ If user chose HTTP:
66
+
67
+ Use AskUserQuestion:
68
+
69
+ **Question:** "Enter your OpenClaw HTTP endpoint URL. OMX will POST JSON event data to this URL."
70
+
71
+ The user types their URL in the "Other" field.
72
+
73
+ **Validate** the URL:
74
+ - Must start with `http://` or `https://`
75
+ - If invalid, explain the format and ask again
76
+
77
+ ### Optional: Secret Header
78
+
79
+ Use AskUserQuestion:
80
+
81
+ **Question:** "Add an authorization header to secure requests? (Optional)"
82
+
83
+ **Options:**
84
+ 1. **Yes, add Bearer token** - Sends `Authorization: Bearer <token>`
85
+ 2. **Yes, add custom header** - Specify header name and value
86
+ 3. **No auth header** - Open endpoint (use firewall rules or IP allowlist instead)
87
+
88
+ If they want a Bearer token or custom header, collect the values.
89
+
90
+ ## Step 3B: CLI Command Gateway Setup
91
+
92
+ If user chose CLI Command:
93
+
94
+ Use AskUserQuestion:
95
+
96
+ **Question:** "Enter the shell command OMX should run for each notification event. Use these placeholders:
97
+ - `{event}` — event name (e.g. session-end)
98
+ - `{session_id}` — session identifier
99
+ - `{project}` — project name/path
100
+ - `{message}` — formatted notification message
101
+
102
+ Example: `notify-send 'OMX: {event}' '{message}'`
103
+ Example: `~/.local/bin/my-notifier --event {event} --msg '{message}'`"
104
+
105
+ The user types their command in the "Other" field.
106
+
107
+ **IMPORTANT: Dual activation gate for CLI Command gateways**
108
+
109
+ CLI command gateways require TWO environment variables to be set:
110
+ - `OMX_OPENCLAW=1` — enables the OpenClaw gateway
111
+ - `OMX_OPENCLAW_COMMAND=1` — specifically enables CLI command execution
112
+
113
+ This two-gate design prevents accidental command execution when only the config file is present. Remind the user to set both in their shell profile.
114
+
115
+ ## Step 4: Map Events
116
+
117
+ Use AskUserQuestion with multiSelect:
118
+
119
+ **Question:** "Which events should be routed through OpenClaw?"
120
+
121
+ **Options (multiSelect: true):**
122
+ 1. **Session end (Recommended)** - When a Codex session finishes
123
+ 2. **Input needed** - When Codex is waiting for your response
124
+ 3. **Session start** - When a new session begins
125
+ 4. **Session continuing** - When a persistent mode keeps the session alive
126
+
127
+ Default selection: session-end + ask-user-question.
128
+
129
+ ## Step 5: Write Configuration
130
+
131
+ Read the existing config, merge the OpenClaw settings, and write back:
132
+
133
+ ```bash
134
+ CONFIG_FILE="$HOME/.codex/.omx-config.json"
135
+ mkdir -p "$(dirname "$CONFIG_FILE")"
136
+
137
+ if [ -f "$CONFIG_FILE" ]; then
138
+ EXISTING=$(cat "$CONFIG_FILE")
139
+ else
140
+ EXISTING='{}'
141
+ fi
142
+ ```
143
+
144
+ ### For HTTP Gateway:
145
+
146
+ ```bash
147
+ # ENDPOINT, AUTH_HEADER_NAME, AUTH_HEADER_VALUE are collected from user
148
+ echo "$EXISTING" | jq \
149
+ --arg endpoint "$ENDPOINT" \
150
+ --arg headerName "$AUTH_HEADER_NAME" \
151
+ --arg headerValue "$AUTH_HEADER_VALUE" \
152
+ '.notifications = (.notifications // {enabled: true}) |
153
+ .notifications.enabled = true |
154
+ .notifications.openclaw = {
155
+ enabled: true,
156
+ gatewayType: "http",
157
+ endpoint: $endpoint,
158
+ headers: (if $headerName == "" then null else {($headerName): $headerValue} end)
159
+ }' > "$CONFIG_FILE"
160
+ ```
161
+
162
+ ### For CLI Command Gateway:
163
+
164
+ ```bash
165
+ # COMMAND is collected from user
166
+ echo "$EXISTING" | jq \
167
+ --arg command "$COMMAND" \
168
+ '.notifications = (.notifications // {enabled: true}) |
169
+ .notifications.enabled = true |
170
+ .notifications.openclaw = {
171
+ enabled: true,
172
+ gatewayType: "command",
173
+ command: $command
174
+ }' > "$CONFIG_FILE"
175
+ ```
176
+
177
+ ### Add event-specific config if user didn't select all events:
178
+
179
+ ```bash
180
+ # Example: disable session-start if not selected
181
+ echo "$(cat "$CONFIG_FILE")" | jq \
182
+ '.notifications.events = (.notifications.events // {}) |
183
+ .notifications.events["session-start"] = {enabled: false}' > "$CONFIG_FILE"
184
+ ```
185
+
186
+ ## Step 6: Explain Activation Gates
187
+
188
+ Regardless of gateway type, explain the activation model:
189
+
190
+ ```
191
+ OpenClaw Activation Gates
192
+ ─────────────────────────
193
+ OpenClaw requires environment variables to be set before it activates.
194
+ This prevents accidental notifications in shared or CI environments.
195
+
196
+ For HTTP Gateway:
197
+ export OMX_OPENCLAW=1
198
+
199
+ For CLI Command Gateway (requires both):
200
+ export OMX_OPENCLAW=1
201
+ export OMX_OPENCLAW_COMMAND=1
202
+
203
+ Add these to your ~/.zshrc or ~/.bashrc.
204
+ ```
205
+
206
+ ## Step 7: Test the Configuration
207
+
208
+ After writing config, offer to test:
209
+
210
+ Use AskUserQuestion:
211
+
212
+ **Question:** "Send a test notification through OpenClaw to verify the setup?"
213
+
214
+ **Options:**
215
+ 1. **Yes, test now (Recommended)** - Run a test dispatch
216
+ 2. **No, I'll test later** - Skip testing
217
+
218
+ ### If testing HTTP Gateway:
219
+
220
+ ```bash
221
+ curl -s -o /dev/null -w "%{http_code}" \
222
+ -H "Content-Type: application/json" \
223
+ ${AUTH_HEADER_NAME:+-H "$AUTH_HEADER_NAME: $AUTH_HEADER_VALUE"} \
224
+ -d '{"event":"test","message":"OMX OpenClaw test notification","session_id":"test"}' \
225
+ "$ENDPOINT"
226
+ ```
227
+
228
+ ### If testing CLI Command Gateway:
229
+
230
+ Replace placeholders in the command with test values and run it.
231
+
232
+ Report success or failure. If it fails, help debug (check URL accessibility, command path, permissions).
233
+
234
+ ## Step 8: Confirm
235
+
236
+ Display the final configuration summary:
237
+
238
+ ```
239
+ OpenClaw Gateway Configured!
240
+
241
+ Type: HTTP / CLI Command
242
+ Endpoint: https://your-server/omx-hook (HTTP only)
243
+ Command: notify-send 'OMX' '{message}' (CLI only)
244
+ Events: session-end, ask-user-question
245
+
246
+ Config saved to: ~/.codex/.omx-config.json
247
+
248
+ Activation (add to ~/.zshrc or ~/.bashrc):
249
+ export OMX_OPENCLAW=1
250
+ export OMX_OPENCLAW_COMMAND=1 # CLI Command gateways only
251
+
252
+ To reconfigure: /configure-openclaw
253
+ To configure other platforms: /configure-notifications
254
+ ```
255
+
256
+ ## Environment Variable Reference
257
+
258
+ ```bash
259
+ # Required for all OpenClaw gateways
260
+ export OMX_OPENCLAW=1
261
+
262
+ # Required additionally for CLI Command gateways
263
+ export OMX_OPENCLAW_COMMAND=1
264
+
265
+ # HTTP gateway: override endpoint URL
266
+ export OMX_OPENCLAW_URL="https://your-server/omx-hook"
267
+ ```