oh-my-codex 0.7.6 → 0.8.1

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 (376) hide show
  1. package/README.de.md +315 -0
  2. package/README.es.md +296 -17
  3. package/README.fr.md +315 -0
  4. package/README.it.md +315 -0
  5. package/README.ja.md +297 -18
  6. package/README.ko.md +296 -17
  7. package/README.md +110 -13
  8. package/README.pt.md +296 -17
  9. package/README.ru.md +296 -17
  10. package/README.tr.md +315 -0
  11. package/README.vi.md +297 -18
  12. package/README.zh-TW.md +362 -0
  13. package/README.zh.md +293 -17
  14. package/dist/catalog/__tests__/generator.test.js +2 -0
  15. package/dist/catalog/__tests__/generator.test.js.map +1 -1
  16. package/dist/catalog/__tests__/schema.test.js +7 -0
  17. package/dist/catalog/__tests__/schema.test.js.map +1 -1
  18. package/dist/cli/__tests__/ask.test.d.ts +2 -0
  19. package/dist/cli/__tests__/ask.test.d.ts.map +1 -0
  20. package/dist/cli/__tests__/ask.test.js +236 -0
  21. package/dist/cli/__tests__/ask.test.js.map +1 -0
  22. package/dist/cli/__tests__/doctor-warning-copy.test.d.ts +2 -0
  23. package/dist/cli/__tests__/doctor-warning-copy.test.d.ts.map +1 -0
  24. package/dist/cli/__tests__/doctor-warning-copy.test.js +45 -0
  25. package/dist/cli/__tests__/doctor-warning-copy.test.js.map +1 -0
  26. package/dist/cli/__tests__/index.test.js +85 -2
  27. package/dist/cli/__tests__/index.test.js.map +1 -1
  28. package/dist/cli/__tests__/ralph-prd-deep-interview.test.d.ts +2 -0
  29. package/dist/cli/__tests__/ralph-prd-deep-interview.test.d.ts.map +1 -0
  30. package/dist/cli/__tests__/ralph-prd-deep-interview.test.js +15 -0
  31. package/dist/cli/__tests__/ralph-prd-deep-interview.test.js.map +1 -0
  32. package/dist/cli/__tests__/ralph.test.js +19 -43
  33. package/dist/cli/__tests__/ralph.test.js.map +1 -1
  34. package/dist/cli/__tests__/setup-scope.test.js +2 -0
  35. package/dist/cli/__tests__/setup-scope.test.js.map +1 -1
  36. package/dist/cli/__tests__/team.test.js +219 -1
  37. package/dist/cli/__tests__/team.test.js.map +1 -1
  38. package/dist/cli/__tests__/version.test.d.ts +2 -0
  39. package/dist/cli/__tests__/version.test.d.ts.map +1 -0
  40. package/dist/cli/__tests__/version.test.js +21 -0
  41. package/dist/cli/__tests__/version.test.js.map +1 -0
  42. package/dist/cli/ask.d.ts +13 -0
  43. package/dist/cli/ask.d.ts.map +1 -0
  44. package/dist/cli/ask.js +174 -0
  45. package/dist/cli/ask.js.map +1 -0
  46. package/dist/cli/constants.d.ts +10 -0
  47. package/dist/cli/constants.d.ts.map +1 -0
  48. package/dist/cli/constants.js +10 -0
  49. package/dist/cli/constants.js.map +1 -0
  50. package/dist/cli/doctor.js +16 -5
  51. package/dist/cli/doctor.js.map +1 -1
  52. package/dist/cli/index.d.ts +8 -2
  53. package/dist/cli/index.d.ts.map +1 -1
  54. package/dist/cli/index.js +150 -52
  55. package/dist/cli/index.js.map +1 -1
  56. package/dist/cli/ralph.d.ts +3 -11
  57. package/dist/cli/ralph.d.ts.map +1 -1
  58. package/dist/cli/ralph.js +64 -45
  59. package/dist/cli/ralph.js.map +1 -1
  60. package/dist/cli/setup.d.ts.map +1 -1
  61. package/dist/cli/setup.js +17 -18
  62. package/dist/cli/setup.js.map +1 -1
  63. package/dist/cli/team.d.ts.map +1 -1
  64. package/dist/cli/team.js +257 -0
  65. package/dist/cli/team.js.map +1 -1
  66. package/dist/hooks/__tests__/deep-interview-contract.test.d.ts +2 -0
  67. package/dist/hooks/__tests__/deep-interview-contract.test.d.ts.map +1 -0
  68. package/dist/hooks/__tests__/deep-interview-contract.test.js +55 -0
  69. package/dist/hooks/__tests__/deep-interview-contract.test.js.map +1 -0
  70. package/dist/hooks/__tests__/emulator.test.js +6 -0
  71. package/dist/hooks/__tests__/emulator.test.js.map +1 -1
  72. package/dist/hooks/__tests__/keyword-detector.test.js +44 -22
  73. package/dist/hooks/__tests__/keyword-detector.test.js.map +1 -1
  74. package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js +23 -7
  75. package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js.map +1 -1
  76. package/dist/hooks/__tests__/notify-hook-session-scope.test.js +59 -0
  77. package/dist/hooks/__tests__/notify-hook-session-scope.test.js.map +1 -1
  78. package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js +264 -1
  79. package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js.map +1 -1
  80. package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js +61 -1
  81. package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js.map +1 -1
  82. package/dist/hooks/__tests__/notify-hook-worker-idle.test.js +17 -7
  83. package/dist/hooks/__tests__/notify-hook-worker-idle.test.js.map +1 -1
  84. package/dist/hooks/__tests__/openclaw-setup-contract.test.d.ts +2 -0
  85. package/dist/hooks/__tests__/openclaw-setup-contract.test.d.ts.map +1 -0
  86. package/dist/hooks/__tests__/openclaw-setup-contract.test.js +61 -0
  87. package/dist/hooks/__tests__/openclaw-setup-contract.test.js.map +1 -0
  88. package/dist/hooks/__tests__/pre-context-gate-skills.test.d.ts +2 -0
  89. package/dist/hooks/__tests__/pre-context-gate-skills.test.d.ts.map +1 -0
  90. package/dist/hooks/__tests__/pre-context-gate-skills.test.js +34 -0
  91. package/dist/hooks/__tests__/pre-context-gate-skills.test.js.map +1 -0
  92. package/dist/hooks/__tests__/visual-verdict-loop.test.d.ts +2 -0
  93. package/dist/hooks/__tests__/visual-verdict-loop.test.d.ts.map +1 -0
  94. package/dist/hooks/__tests__/visual-verdict-loop.test.js +35 -0
  95. package/dist/hooks/__tests__/visual-verdict-loop.test.js.map +1 -0
  96. package/dist/hooks/agents-overlay.d.ts.map +1 -1
  97. package/dist/hooks/agents-overlay.js +18 -16
  98. package/dist/hooks/agents-overlay.js.map +1 -1
  99. package/dist/hooks/codebase-map.d.ts.map +1 -1
  100. package/dist/hooks/codebase-map.js +6 -2
  101. package/dist/hooks/codebase-map.js.map +1 -1
  102. package/dist/hooks/emulator.d.ts.map +1 -1
  103. package/dist/hooks/emulator.js +2 -0
  104. package/dist/hooks/emulator.js.map +1 -1
  105. package/dist/hooks/extensibility/sdk.d.ts.map +1 -1
  106. package/dist/hooks/extensibility/sdk.js +2 -1
  107. package/dist/hooks/extensibility/sdk.js.map +1 -1
  108. package/dist/hooks/keyword-registry.d.ts.map +1 -1
  109. package/dist/hooks/keyword-registry.js +6 -0
  110. package/dist/hooks/keyword-registry.js.map +1 -1
  111. package/dist/hud/index.d.ts.map +1 -1
  112. package/dist/hud/index.js +2 -24
  113. package/dist/hud/index.js.map +1 -1
  114. package/dist/mcp/__tests__/path-traversal.test.js +9 -227
  115. package/dist/mcp/__tests__/path-traversal.test.js.map +1 -1
  116. package/dist/mcp/__tests__/state-server-schema.test.js +16 -20
  117. package/dist/mcp/__tests__/state-server-schema.test.js.map +1 -1
  118. package/dist/mcp/__tests__/state-server-team-tools.test.js +30 -487
  119. package/dist/mcp/__tests__/state-server-team-tools.test.js.map +1 -1
  120. package/dist/mcp/code-intel-server.d.ts.map +1 -1
  121. package/dist/mcp/code-intel-server.js +18 -8
  122. package/dist/mcp/code-intel-server.js.map +1 -1
  123. package/dist/mcp/memory-server.js +72 -11
  124. package/dist/mcp/memory-server.js.map +1 -1
  125. package/dist/mcp/state-paths.d.ts.map +1 -1
  126. package/dist/mcp/state-paths.js +4 -1
  127. package/dist/mcp/state-paths.js.map +1 -1
  128. package/dist/mcp/state-server.d.ts +179 -0
  129. package/dist/mcp/state-server.d.ts.map +1 -1
  130. package/dist/mcp/state-server.js +221 -1111
  131. package/dist/mcp/state-server.js.map +1 -1
  132. package/dist/mcp/team-server.d.ts.map +1 -1
  133. package/dist/mcp/team-server.js +9 -3
  134. package/dist/mcp/team-server.js.map +1 -1
  135. package/dist/mcp/trace-server.d.ts.map +1 -1
  136. package/dist/mcp/trace-server.js +8 -3
  137. package/dist/mcp/trace-server.js.map +1 -1
  138. package/dist/notifications/__tests__/dispatch-cooldown.test.d.ts +5 -0
  139. package/dist/notifications/__tests__/dispatch-cooldown.test.d.ts.map +1 -0
  140. package/dist/notifications/__tests__/dispatch-cooldown.test.js +100 -0
  141. package/dist/notifications/__tests__/dispatch-cooldown.test.js.map +1 -0
  142. package/dist/notifications/__tests__/temp-mode.test.d.ts +2 -0
  143. package/dist/notifications/__tests__/temp-mode.test.d.ts.map +1 -0
  144. package/dist/notifications/__tests__/temp-mode.test.js +172 -0
  145. package/dist/notifications/__tests__/temp-mode.test.js.map +1 -0
  146. package/dist/notifications/config.d.ts.map +1 -1
  147. package/dist/notifications/config.js +67 -7
  148. package/dist/notifications/config.js.map +1 -1
  149. package/dist/notifications/dispatch-cooldown.d.ts +36 -0
  150. package/dist/notifications/dispatch-cooldown.d.ts.map +1 -0
  151. package/dist/notifications/dispatch-cooldown.js +109 -0
  152. package/dist/notifications/dispatch-cooldown.js.map +1 -0
  153. package/dist/notifications/dispatcher.d.ts.map +1 -1
  154. package/dist/notifications/dispatcher.js +4 -4
  155. package/dist/notifications/dispatcher.js.map +1 -1
  156. package/dist/notifications/index.d.ts +5 -0
  157. package/dist/notifications/index.d.ts.map +1 -1
  158. package/dist/notifications/index.js +39 -8
  159. package/dist/notifications/index.js.map +1 -1
  160. package/dist/notifications/reply-listener.d.ts.map +1 -1
  161. package/dist/notifications/reply-listener.js +6 -2
  162. package/dist/notifications/reply-listener.js.map +1 -1
  163. package/dist/notifications/session-registry.d.ts.map +1 -1
  164. package/dist/notifications/session-registry.js +2 -2
  165. package/dist/notifications/session-registry.js.map +1 -1
  166. package/dist/notifications/temp-contract.d.ts +22 -0
  167. package/dist/notifications/temp-contract.d.ts.map +1 -0
  168. package/dist/notifications/temp-contract.js +147 -0
  169. package/dist/notifications/temp-contract.js.map +1 -0
  170. package/dist/notifications/tmux.js +2 -2
  171. package/dist/notifications/tmux.js.map +1 -1
  172. package/dist/notifications/types.d.ts +18 -0
  173. package/dist/notifications/types.d.ts.map +1 -1
  174. package/dist/openclaw/__tests__/config.test.js +81 -0
  175. package/dist/openclaw/__tests__/config.test.js.map +1 -1
  176. package/dist/openclaw/__tests__/dispatcher.test.js +40 -1
  177. package/dist/openclaw/__tests__/dispatcher.test.js.map +1 -1
  178. package/dist/openclaw/config.d.ts +4 -0
  179. package/dist/openclaw/config.d.ts.map +1 -1
  180. package/dist/openclaw/config.js +110 -16
  181. package/dist/openclaw/config.js.map +1 -1
  182. package/dist/openclaw/dispatcher.d.ts +9 -3
  183. package/dist/openclaw/dispatcher.d.ts.map +1 -1
  184. package/dist/openclaw/dispatcher.js +42 -9
  185. package/dist/openclaw/dispatcher.js.map +1 -1
  186. package/dist/openclaw/types.d.ts +5 -1
  187. package/dist/openclaw/types.d.ts.map +1 -1
  188. package/dist/ralph/__tests__/persistence.test.js +28 -1
  189. package/dist/ralph/__tests__/persistence.test.js.map +1 -1
  190. package/dist/ralph/persistence.d.ts +21 -0
  191. package/dist/ralph/persistence.d.ts.map +1 -1
  192. package/dist/ralph/persistence.js +85 -2
  193. package/dist/ralph/persistence.js.map +1 -1
  194. package/dist/state/paths.d.ts +3 -0
  195. package/dist/state/paths.d.ts.map +1 -0
  196. package/dist/state/paths.js +2 -0
  197. package/dist/state/paths.js.map +1 -0
  198. package/dist/team/__tests__/api-interop.test.d.ts +2 -0
  199. package/dist/team/__tests__/api-interop.test.d.ts.map +1 -0
  200. package/dist/team/__tests__/api-interop.test.js +1052 -0
  201. package/dist/team/__tests__/api-interop.test.js.map +1 -0
  202. package/dist/team/__tests__/idle-nudge.test.d.ts +2 -0
  203. package/dist/team/__tests__/idle-nudge.test.d.ts.map +1 -0
  204. package/dist/team/__tests__/idle-nudge.test.js +225 -0
  205. package/dist/team/__tests__/idle-nudge.test.js.map +1 -0
  206. package/dist/team/__tests__/mcp-comm.test.js +30 -0
  207. package/dist/team/__tests__/mcp-comm.test.js.map +1 -1
  208. package/dist/team/__tests__/runtime.test.js +33 -26
  209. package/dist/team/__tests__/runtime.test.js.map +1 -1
  210. package/dist/team/__tests__/state-root.test.d.ts +2 -0
  211. package/dist/team/__tests__/state-root.test.d.ts.map +1 -0
  212. package/dist/team/__tests__/state-root.test.js +9 -0
  213. package/dist/team/__tests__/state-root.test.js.map +1 -0
  214. package/dist/team/__tests__/state.test.js +52 -17
  215. package/dist/team/__tests__/state.test.js.map +1 -1
  216. package/dist/team/__tests__/team-ops-contract.test.d.ts +2 -0
  217. package/dist/team/__tests__/team-ops-contract.test.d.ts.map +1 -0
  218. package/dist/team/__tests__/team-ops-contract.test.js +90 -0
  219. package/dist/team/__tests__/team-ops-contract.test.js.map +1 -0
  220. package/dist/team/__tests__/tmux-claude-workers-demo.test.d.ts +2 -0
  221. package/dist/team/__tests__/tmux-claude-workers-demo.test.d.ts.map +1 -0
  222. package/dist/team/__tests__/tmux-claude-workers-demo.test.js +176 -0
  223. package/dist/team/__tests__/tmux-claude-workers-demo.test.js.map +1 -0
  224. package/dist/team/__tests__/tmux-session.test.js +8 -0
  225. package/dist/team/__tests__/tmux-session.test.js.map +1 -1
  226. package/dist/team/__tests__/worker-bootstrap.test.js +29 -0
  227. package/dist/team/__tests__/worker-bootstrap.test.js.map +1 -1
  228. package/dist/team/__tests__/worktree.test.js +54 -1
  229. package/dist/team/__tests__/worktree.test.js.map +1 -1
  230. package/dist/team/api-interop.d.ts +19 -0
  231. package/dist/team/api-interop.d.ts.map +1 -0
  232. package/dist/team/api-interop.js +578 -0
  233. package/dist/team/api-interop.js.map +1 -0
  234. package/dist/team/mcp-comm.d.ts.map +1 -1
  235. package/dist/team/mcp-comm.js +32 -2
  236. package/dist/team/mcp-comm.js.map +1 -1
  237. package/dist/team/orchestrator.d.ts +1 -10
  238. package/dist/team/orchestrator.d.ts.map +1 -1
  239. package/dist/team/orchestrator.js +8 -0
  240. package/dist/team/orchestrator.js.map +1 -1
  241. package/dist/team/runtime-cli.js +14 -8
  242. package/dist/team/runtime-cli.js.map +1 -1
  243. package/dist/team/runtime.d.ts +2 -1
  244. package/dist/team/runtime.d.ts.map +1 -1
  245. package/dist/team/runtime.js +103 -30
  246. package/dist/team/runtime.js.map +1 -1
  247. package/dist/team/scaling.d.ts.map +1 -1
  248. package/dist/team/scaling.js +33 -12
  249. package/dist/team/scaling.js.map +1 -1
  250. package/dist/team/state/approvals.d.ts +25 -0
  251. package/dist/team/state/approvals.d.ts.map +1 -0
  252. package/dist/team/state/approvals.js +31 -0
  253. package/dist/team/state/approvals.js.map +1 -0
  254. package/dist/team/state/config.d.ts +2 -0
  255. package/dist/team/state/config.d.ts.map +1 -0
  256. package/dist/team/state/config.js +2 -0
  257. package/dist/team/state/config.js.map +1 -0
  258. package/dist/team/state/dispatch-lock.d.ts +3 -0
  259. package/dist/team/state/dispatch-lock.d.ts.map +1 -0
  260. package/dist/team/state/dispatch-lock.js +81 -0
  261. package/dist/team/state/dispatch-lock.js.map +1 -0
  262. package/dist/team/state/dispatch.d.ts +61 -0
  263. package/dist/team/state/dispatch.d.ts.map +1 -0
  264. package/dist/team/state/dispatch.js +158 -0
  265. package/dist/team/state/dispatch.js.map +1 -0
  266. package/dist/team/state/events.d.ts +2 -0
  267. package/dist/team/state/events.d.ts.map +1 -0
  268. package/dist/team/state/events.js +2 -0
  269. package/dist/team/state/events.js.map +1 -0
  270. package/dist/team/state/index.d.ts +11 -0
  271. package/dist/team/state/index.d.ts.map +1 -0
  272. package/dist/team/state/index.js +11 -0
  273. package/dist/team/state/index.js.map +1 -0
  274. package/dist/team/state/io.d.ts +2 -0
  275. package/dist/team/state/io.d.ts.map +1 -0
  276. package/dist/team/state/io.js +2 -0
  277. package/dist/team/state/io.js.map +1 -0
  278. package/dist/team/state/locks.d.ts +16 -0
  279. package/dist/team/state/locks.d.ts.map +1 -0
  280. package/dist/team/state/locks.js +201 -0
  281. package/dist/team/state/locks.js.map +1 -0
  282. package/dist/team/state/mailbox.d.ts +39 -0
  283. package/dist/team/state/mailbox.d.ts.map +1 -0
  284. package/dist/team/state/mailbox.js +58 -0
  285. package/dist/team/state/mailbox.js.map +1 -0
  286. package/dist/team/state/monitor.d.ts +96 -0
  287. package/dist/team/state/monitor.d.ts.map +1 -0
  288. package/dist/team/state/monitor.js +163 -0
  289. package/dist/team/state/monitor.js.map +1 -0
  290. package/dist/team/state/shutdown.d.ts +2 -0
  291. package/dist/team/state/shutdown.d.ts.map +1 -0
  292. package/dist/team/state/shutdown.js +2 -0
  293. package/dist/team/state/shutdown.js.map +1 -0
  294. package/dist/team/state/summary.d.ts +2 -0
  295. package/dist/team/state/summary.d.ts.map +1 -0
  296. package/dist/team/state/summary.js +2 -0
  297. package/dist/team/state/summary.js.map +1 -0
  298. package/dist/team/state/tasks.d.ts +49 -0
  299. package/dist/team/state/tasks.d.ts.map +1 -0
  300. package/dist/team/state/tasks.js +182 -0
  301. package/dist/team/state/tasks.js.map +1 -0
  302. package/dist/team/state/types.d.ts +281 -0
  303. package/dist/team/state/types.d.ts.map +1 -0
  304. package/dist/team/state/types.js +3 -0
  305. package/dist/team/state/types.js.map +1 -0
  306. package/dist/team/state/workers.d.ts +2 -0
  307. package/dist/team/state/workers.d.ts.map +1 -0
  308. package/dist/team/state/workers.js +2 -0
  309. package/dist/team/state/workers.js.map +1 -0
  310. package/dist/team/state-root.d.ts +5 -0
  311. package/dist/team/state-root.d.ts.map +1 -0
  312. package/dist/team/state-root.js +8 -0
  313. package/dist/team/state-root.js.map +1 -0
  314. package/dist/team/state.d.ts +4 -1
  315. package/dist/team/state.d.ts.map +1 -1
  316. package/dist/team/state.js +200 -881
  317. package/dist/team/state.js.map +1 -1
  318. package/dist/team/tmux-session.d.ts.map +1 -1
  319. package/dist/team/tmux-session.js +11 -10
  320. package/dist/team/tmux-session.js.map +1 -1
  321. package/dist/team/worker-bootstrap.d.ts.map +1 -1
  322. package/dist/team/worker-bootstrap.js +58 -26
  323. package/dist/team/worker-bootstrap.js.map +1 -1
  324. package/dist/team/worktree.d.ts.map +1 -1
  325. package/dist/team/worktree.js +43 -1
  326. package/dist/team/worktree.js.map +1 -1
  327. package/dist/utils/safe-json.d.ts +3 -0
  328. package/dist/utils/safe-json.d.ts.map +1 -0
  329. package/dist/utils/safe-json.js +19 -0
  330. package/dist/utils/safe-json.js.map +1 -0
  331. package/dist/utils/sleep.d.ts +3 -0
  332. package/dist/utils/sleep.d.ts.map +1 -0
  333. package/dist/utils/sleep.js +15 -0
  334. package/dist/utils/sleep.js.map +1 -0
  335. package/dist/visual/__tests__/verdict.test.d.ts +2 -0
  336. package/dist/visual/__tests__/verdict.test.d.ts.map +1 -0
  337. package/dist/visual/__tests__/verdict.test.js +81 -0
  338. package/dist/visual/__tests__/verdict.test.js.map +1 -0
  339. package/dist/visual/constants.d.ts +4 -0
  340. package/dist/visual/constants.d.ts.map +1 -0
  341. package/dist/visual/constants.js +3 -0
  342. package/dist/visual/constants.js.map +1 -0
  343. package/dist/visual/verdict.d.ts +17 -0
  344. package/dist/visual/verdict.d.ts.map +1 -0
  345. package/dist/visual/verdict.js +61 -0
  346. package/dist/visual/verdict.js.map +1 -0
  347. package/package.json +10 -3
  348. package/scripts/ask-claude.sh +17 -0
  349. package/scripts/ask-gemini.sh +14 -0
  350. package/scripts/demo-claude-workers.sh +241 -0
  351. package/scripts/demo-team-e2e.sh +179 -0
  352. package/scripts/fixtures/ask-advisor-stub.js +12 -0
  353. package/scripts/notify-hook/team-dispatch.js +234 -12
  354. package/scripts/notify-hook/team-leader-nudge.js +42 -2
  355. package/scripts/notify-hook/team-worker.js +63 -4
  356. package/scripts/notify-hook/visual-verdict.js +50 -1
  357. package/scripts/notify-hook.js +1 -0
  358. package/scripts/run-provider-advisor.js +179 -0
  359. package/skills/ask-claude/SKILL.md +61 -0
  360. package/skills/ask-gemini/SKILL.md +61 -0
  361. package/skills/autopilot/SKILL.md +32 -2
  362. package/skills/configure-notifications/SKILL.md +188 -186
  363. package/skills/deep-interview/SKILL.md +247 -0
  364. package/skills/omx-setup/SKILL.md +1 -1
  365. package/skills/ralph/SKILL.md +42 -11
  366. package/skills/ralplan/SKILL.md +17 -0
  367. package/skills/team/SKILL.md +64 -5
  368. package/skills/visual-verdict/SKILL.md +76 -0
  369. package/skills/web-clone/SKILL.md +366 -0
  370. package/skills/worker/SKILL.md +42 -11
  371. package/templates/AGENTS.md +9 -0
  372. package/templates/catalog-manifest.json +39 -18
  373. package/skills/configure-discord/SKILL.md +0 -256
  374. package/skills/configure-openclaw/SKILL.md +0 -267
  375. package/skills/configure-slack/SKILL.md +0 -226
  376. package/skills/configure-telegram/SKILL.md +0 -232
package/dist/cli/index.js CHANGED
@@ -15,6 +15,8 @@ import { hooksCommand } from './hooks.js';
15
15
  import { hudCommand } from '../hud/index.js';
16
16
  import { teamCommand } from './team.js';
17
17
  import { ralphCommand } from './ralph.js';
18
+ import { askCommand } from './ask.js';
19
+ import { MADMAX_FLAG, CODEX_BYPASS_FLAG, HIGH_REASONING_FLAG, XHIGH_REASONING_FLAG, SPARK_FLAG, MADMAX_SPARK_FLAG, CONFIG_FLAG, LONG_CONFIG_FLAG, } from './constants.js';
18
20
  import { getBaseStateDir, getStateDir, listModeStateFilesWithScopePreference, } from '../mcp/state-paths.js';
19
21
  import { maybeCheckAndPromptUpdate } from './update.js';
20
22
  import { maybePromptGithubStar } from './star-prompt.js';
@@ -28,6 +30,7 @@ import { buildHookEvent } from '../hooks/extensibility/events.js';
28
30
  import { dispatchHookEvent } from '../hooks/extensibility/dispatcher.js';
29
31
  import { collectInheritableTeamWorkerArgs as collectInheritableTeamWorkerArgsShared, resolveTeamWorkerLaunchArgs, resolveTeamLowComplexityDefaultModel, } from '../team/model-contract.js';
30
32
  import { parseWorktreeMode, planWorktreeTarget, ensureWorktree, } from '../team/worktree.js';
33
+ import { OMX_NOTIFY_TEMP_CONTRACT_ENV, parseNotifyTempContractFromArgs, serializeNotifyTempContract, } from '../notifications/temp-contract.js';
31
34
  const HELP = `
32
35
  oh-my-codex (omx) - Multi-agent orchestration for Codex CLI
33
36
 
@@ -37,6 +40,7 @@ Usage:
37
40
  omx uninstall Remove OMX configuration and clean up installed artifacts
38
41
  omx doctor Check installation health
39
42
  omx doctor --team Check team/swarm runtime health diagnostics
43
+ omx ask Ask local provider CLI (claude|gemini) and write artifact output
40
44
  omx team Spawn parallel worker panes in tmux and bootstrap inbox/task state
41
45
  omx ralph Launch Codex with ralph persistence mode active
42
46
  omx version Show version information
@@ -60,6 +64,12 @@ Options:
60
64
  Workers get the configured low-complexity team model; leader model unchanged
61
65
  --madmax-spark spark model for workers + bypass approvals for leader and workers
62
66
  (shorthand for: --spark --madmax)
67
+ --notify-temp Enable temporary notification routing for this run/session only
68
+ --discord Select Discord provider for temporary notification mode
69
+ --slack Select Slack provider for temporary notification mode
70
+ --telegram Select Telegram provider for temporary notification mode
71
+ --custom <name>
72
+ Select custom/OpenClaw gateway name for temporary notification mode
63
73
  -w, --worktree[=<name>]
64
74
  Launch Codex in a git worktree (detached when no name is given)
65
75
  --force Force reinstall (overwrite existing files)
@@ -70,14 +80,6 @@ Options:
70
80
  --scope Setup scope for "omx setup" only:
71
81
  user | project
72
82
  `;
73
- const MADMAX_FLAG = '--madmax';
74
- const CODEX_BYPASS_FLAG = '--dangerously-bypass-approvals-and-sandbox';
75
- const HIGH_REASONING_FLAG = '--high';
76
- const XHIGH_REASONING_FLAG = '--xhigh';
77
- const SPARK_FLAG = '--spark';
78
- const MADMAX_SPARK_FLAG = '--madmax-spark';
79
- const CONFIG_FLAG = '-c';
80
- const LONG_CONFIG_FLAG = '--config';
81
83
  const REASONING_KEY = 'model_reasoning_effort';
82
84
  const MODEL_INSTRUCTIONS_FILE_KEY = 'model_instructions_file';
83
85
  const TEAM_WORKER_LAUNCH_ARGS_ENV = 'OMX_TEAM_WORKER_LAUNCH_ARGS';
@@ -87,6 +89,11 @@ const OMX_MODEL_INSTRUCTIONS_FILE_ENV = 'OMX_MODEL_INSTRUCTIONS_FILE';
87
89
  const REASONING_MODES = ['low', 'medium', 'high', 'xhigh'];
88
90
  const REASONING_MODE_SET = new Set(REASONING_MODES);
89
91
  const REASONING_USAGE = 'Usage: omx reasoning <low|medium|high|xhigh>';
92
+ const ALLOWED_SHELLS = new Set([
93
+ '/bin/sh', '/bin/bash', '/bin/zsh', '/bin/dash', '/bin/fish',
94
+ '/usr/bin/sh', '/usr/bin/bash', '/usr/bin/zsh', '/usr/bin/dash', '/usr/bin/fish',
95
+ '/usr/local/bin/bash', '/usr/local/bin/zsh', '/usr/local/bin/fish',
96
+ ]);
90
97
  /**
91
98
  * Legacy scope values that may appear in persisted setup-scope.json files.
92
99
  * Both 'project-local' (renamed) and old 'project' (minimal, removed) are
@@ -110,7 +117,8 @@ export function readPersistedSetupScope(cwd) {
110
117
  return migrated;
111
118
  }
112
119
  }
113
- catch {
120
+ catch (err) {
121
+ process.stderr.write(`[cli/index] operation failed: ${err}\n`);
114
122
  // Ignore malformed persisted scope and use defaults.
115
123
  }
116
124
  return undefined;
@@ -153,6 +161,9 @@ export function resolveCliInvocation(args) {
153
161
  if (firstArg === '--help' || firstArg === '-h') {
154
162
  return { command: 'help', launchArgs: [] };
155
163
  }
164
+ if (firstArg === '--version' || firstArg === '-v') {
165
+ return { command: 'version', launchArgs: [] };
166
+ }
156
167
  if (!firstArg || firstArg.startsWith('--')) {
157
168
  return { command: 'launch', launchArgs: firstArg ? args : [] };
158
169
  }
@@ -161,6 +172,9 @@ export function resolveCliInvocation(args) {
161
172
  }
162
173
  return { command: firstArg, launchArgs: [] };
163
174
  }
175
+ export function resolveNotifyTempContract(args, env = process.env) {
176
+ return parseNotifyTempContractFromArgs(args, env);
177
+ }
164
178
  export function resolveCodexLaunchPolicy(env = process.env) {
165
179
  return env.TMUX ? 'inside-tmux' : 'direct';
166
180
  }
@@ -264,18 +278,19 @@ export function buildHudPaneCleanupTargets(existingPaneIds, createdPaneId, leade
264
278
  }
265
279
  export async function main(args) {
266
280
  const knownCommands = new Set([
267
- 'launch', 'setup', 'uninstall', 'doctor', 'team', 'ralph', 'version', 'tmux-hook', 'hooks', 'hud', 'status', 'cancel', 'help', '--help', '-h',
281
+ 'launch', 'setup', 'uninstall', 'doctor', 'ask', 'team', 'ralph', 'version', 'tmux-hook', 'hooks', 'hud', 'status', 'cancel', 'help', '--help', '-h',
268
282
  ]);
269
283
  const firstArg = args[0];
270
284
  const { command, launchArgs } = resolveCliInvocation(args);
271
285
  const flags = new Set(args.filter(a => a.startsWith('--')));
286
+ const ralphHelpRequested = firstArg === 'ralph' && (args[1] === '--help' || args[1] === '-h');
272
287
  const options = {
273
288
  force: flags.has('--force'),
274
289
  dryRun: flags.has('--dry-run'),
275
290
  verbose: flags.has('--verbose'),
276
291
  team: flags.has('--team'),
277
292
  };
278
- if (flags.has('--help') || flags.has('-h')) {
293
+ if (flags.has('--help') && !ralphHelpRequested && command !== 'team') {
279
294
  console.log(HELP);
280
295
  return;
281
296
  }
@@ -304,6 +319,9 @@ export async function main(args) {
304
319
  case 'doctor':
305
320
  await doctor(options);
306
321
  break;
322
+ case 'ask':
323
+ await askCommand(args.slice(1));
324
+ break;
307
325
  case 'team':
308
326
  await teamCommand(args.slice(1), options);
309
327
  break;
@@ -363,13 +381,21 @@ async function showStatus() {
363
381
  }
364
382
  for (const path of states) {
365
383
  const content = await readFile(path, 'utf-8');
366
- const state = JSON.parse(content);
384
+ let state;
385
+ try {
386
+ state = JSON.parse(content);
387
+ }
388
+ catch (err) {
389
+ process.stderr.write(`[cli/index] operation failed: ${err}\n`);
390
+ continue;
391
+ }
367
392
  const file = basename(path);
368
393
  const mode = file.replace('-state.json', '');
369
- console.log(`${mode}: ${state.active ? 'ACTIVE' : 'inactive'} (phase: ${state.current_phase || 'n/a'})`);
394
+ console.log(`${mode}: ${state.active === true ? 'ACTIVE' : 'inactive'} (phase: ${String(state.current_phase || 'n/a')})`);
370
395
  }
371
396
  }
372
- catch {
397
+ catch (err) {
398
+ process.stderr.write(`[cli/index] operation failed: ${err}\n`);
373
399
  console.log('No active modes.');
374
400
  }
375
401
  }
@@ -417,9 +443,10 @@ export async function launchWithHud(args) {
417
443
  }
418
444
  const launchCwd = process.cwd();
419
445
  const parsedWorktree = parseWorktreeMode(args);
446
+ const notifyTempResult = resolveNotifyTempContract(parsedWorktree.remainingArgs, process.env);
420
447
  const codexHomeOverride = resolveCodexHomeForLaunch(launchCwd, process.env);
421
- const workerSparkModel = resolveWorkerSparkModel(parsedWorktree.remainingArgs, codexHomeOverride);
422
- const normalizedArgs = normalizeCodexLaunchArgs(parsedWorktree.remainingArgs);
448
+ const workerSparkModel = resolveWorkerSparkModel(notifyTempResult.passthroughArgs, codexHomeOverride);
449
+ const normalizedArgs = normalizeCodexLaunchArgs(notifyTempResult.passthroughArgs);
423
450
  let cwd = launchCwd;
424
451
  if (parsedWorktree.mode.enabled) {
425
452
  const planned = planWorktreeTarget({
@@ -436,18 +463,20 @@ export async function launchWithHud(args) {
436
463
  try {
437
464
  await maybeCheckAndPromptUpdate(cwd);
438
465
  }
439
- catch {
466
+ catch (err) {
467
+ process.stderr.write(`[cli/index] operation failed: ${err}\n`);
440
468
  // Non-fatal: update checks must never block launch
441
469
  }
442
470
  try {
443
471
  await maybePromptGithubStar();
444
472
  }
445
- catch {
473
+ catch (err) {
474
+ process.stderr.write(`[cli/index] operation failed: ${err}\n`);
446
475
  // Non-fatal: star prompt must never block launch
447
476
  }
448
477
  // ── Phase 1: preLaunch ──────────────────────────────────────────────────
449
478
  try {
450
- await preLaunch(cwd, sessionId);
479
+ await preLaunch(cwd, sessionId, notifyTempResult.contract);
451
480
  }
452
481
  catch (err) {
453
482
  // preLaunch errors must NOT prevent Codex from starting
@@ -455,7 +484,10 @@ export async function launchWithHud(args) {
455
484
  }
456
485
  // ── Phase 2: run ────────────────────────────────────────────────────────
457
486
  try {
458
- runCodex(cwd, normalizedArgs, sessionId, workerSparkModel, codexHomeOverride);
487
+ const notifyTempContractRaw = notifyTempResult.contract.active
488
+ ? serializeNotifyTempContract(notifyTempResult.contract)
489
+ : null;
490
+ runCodex(cwd, normalizedArgs, sessionId, workerSparkModel, codexHomeOverride, notifyTempContractRaw);
459
491
  }
460
492
  finally {
461
493
  // ── Phase 3: postLaunch ─────────────────────────────────────────────
@@ -664,7 +696,8 @@ export function buildTmuxSessionName(cwd, sessionId) {
664
696
  if (branch)
665
697
  branchToken = sanitizeTmuxToken(branch);
666
698
  }
667
- catch {
699
+ catch (err) {
700
+ process.stderr.write(`[cli/index] operation failed: ${err}\n`);
668
701
  // Non-git directory or git unavailable.
669
702
  }
670
703
  const sessionToken = sanitizeTmuxToken(sessionId.replace(/^omx-/, ''));
@@ -684,15 +717,17 @@ function detectDetachedSessionWindowIndex(sessionName) {
684
717
  const output = execFileSync('tmux', ['display-message', '-p', '-t', sessionName, '#{window_index}'], { encoding: 'utf-8' });
685
718
  return parseWindowIndexFromTmuxOutput(output);
686
719
  }
687
- catch {
720
+ catch (err) {
721
+ process.stderr.write(`[cli/index] operation failed: ${err}\n`);
688
722
  return null;
689
723
  }
690
724
  }
691
- export function buildDetachedSessionBootstrapSteps(sessionName, cwd, codexCmd, hudCmd, workerLaunchArgs, codexHomeOverride) {
725
+ export function buildDetachedSessionBootstrapSteps(sessionName, cwd, codexCmd, hudCmd, workerLaunchArgs, codexHomeOverride, notifyTempContractRaw) {
692
726
  const newSessionArgs = [
693
727
  'new-session', '-d', '-s', sessionName, '-c', cwd,
694
728
  ...(workerLaunchArgs ? ['-e', `${TEAM_WORKER_LAUNCH_ARGS_ENV}=${workerLaunchArgs}`] : []),
695
729
  ...(codexHomeOverride ? ['-e', `CODEX_HOME=${codexHomeOverride}`] : []),
730
+ ...(notifyTempContractRaw ? ['-e', `${OMX_NOTIFY_TEMP_CONTRACT_ENV}=${notifyTempContractRaw}`] : []),
696
731
  codexCmd,
697
732
  ];
698
733
  const splitCaptureArgs = [
@@ -753,25 +788,42 @@ export function buildDetachedSessionRollbackSteps(sessionName, hookTarget, hookN
753
788
  steps.push({ name: 'kill-session', args: ['kill-session', '-t', sessionName] });
754
789
  return steps;
755
790
  }
791
+ export function buildNotifyTempStartupMessages(contract, hasValidProviders) {
792
+ const providers = contract.canonicalSelectors.length > 0
793
+ ? contract.canonicalSelectors.join(',')
794
+ : 'none';
795
+ const infoLines = [
796
+ `notify temp: active | providers=${providers} | persistent-routing=bypassed`,
797
+ ];
798
+ const warningLines = [...contract.warnings];
799
+ if (!hasValidProviders) {
800
+ warningLines.push('notify temp: no valid providers resolved; notifications skipped');
801
+ }
802
+ return { infoLines, warningLines };
803
+ }
756
804
  /**
757
805
  * preLaunch: Prepare environment before Codex starts.
758
806
  * 1. Orphan cleanup (stale session from a crashed launch)
759
807
  * 2. Generate runtime overlay + write session-scoped model instructions file
760
808
  * 3. Write session.json
761
809
  */
762
- async function preLaunch(cwd, sessionId) {
810
+ async function preLaunch(cwd, sessionId, notifyTempContract) {
763
811
  // 1. Orphan cleanup
764
812
  const existingSession = await readSessionState(cwd);
765
813
  if (existingSession && isSessionStale(existingSession)) {
766
814
  try {
767
815
  await removeSessionModelInstructionsFile(cwd, existingSession.session_id);
768
816
  }
769
- catch { /* best effort */ }
817
+ catch (err) {
818
+ process.stderr.write(`[cli/index] operation failed: ${err}\n`);
819
+ }
770
820
  const { unlink } = await import('fs/promises');
771
821
  try {
772
822
  await unlink(join(cwd, '.omx', 'state', 'session.json'));
773
823
  }
774
- catch { /* best effort */ }
824
+ catch (err) {
825
+ process.stderr.write(`[cli/index] operation failed: ${err}\n`);
826
+ }
775
827
  }
776
828
  // 2. Generate runtime overlay + write session-scoped model instructions file
777
829
  const overlay = await generateOverlay(cwd, sessionId);
@@ -783,18 +835,35 @@ async function preLaunch(cwd, sessionId) {
783
835
  try {
784
836
  await startNotifyFallbackWatcher(cwd);
785
837
  }
786
- catch {
838
+ catch (err) {
839
+ process.stderr.write(`[cli/index] operation failed: ${err}\n`);
787
840
  // Non-fatal
788
841
  }
789
842
  // 5. Start derived watcher (best effort, opt-in)
790
843
  try {
791
844
  await startHookDerivedWatcher(cwd);
792
845
  }
793
- catch {
846
+ catch (err) {
847
+ process.stderr.write(`[cli/index] operation failed: ${err}\n`);
794
848
  // Non-fatal
795
849
  }
796
- // 6. Send session-start lifecycle notification (best effort)
850
+ // 6. Emit temp notification startup summary + warnings, then send session-start lifecycle notification (best effort)
797
851
  try {
852
+ if (notifyTempContract?.active) {
853
+ process.env[OMX_NOTIFY_TEMP_CONTRACT_ENV] = serializeNotifyTempContract(notifyTempContract);
854
+ const { getNotificationConfig } = await import('../notifications/config.js');
855
+ const resolved = getNotificationConfig();
856
+ const startup = buildNotifyTempStartupMessages(notifyTempContract, Boolean(resolved?.enabled));
857
+ for (const info of startup.infoLines) {
858
+ console.log(`[omx] ${info}`);
859
+ }
860
+ for (const warning of startup.warningLines) {
861
+ console.warn(`[omx] ${warning}`);
862
+ }
863
+ }
864
+ else {
865
+ delete process.env[OMX_NOTIFY_TEMP_CONTRACT_ENV];
866
+ }
798
867
  const { notifyLifecycle } = await import('../notifications/index.js');
799
868
  await notifyLifecycle('session-start', {
800
869
  sessionId,
@@ -802,7 +871,8 @@ async function preLaunch(cwd, sessionId) {
802
871
  projectName: basename(cwd),
803
872
  });
804
873
  }
805
- catch {
874
+ catch (err) {
875
+ process.stderr.write(`[cli/index] operation failed: ${err}\n`);
806
876
  // Non-fatal: notification failures must never block launch
807
877
  }
808
878
  // 7. Dispatch native hook event (best effort)
@@ -815,7 +885,8 @@ async function preLaunch(cwd, sessionId) {
815
885
  },
816
886
  });
817
887
  }
818
- catch {
888
+ catch (err) {
889
+ process.stderr.write(`[cli/index] operation failed: ${err}\n`);
819
890
  // Non-fatal
820
891
  }
821
892
  }
@@ -823,7 +894,7 @@ async function preLaunch(cwd, sessionId) {
823
894
  * runCodex: Launch Codex CLI (blocks until exit).
824
895
  * All 3 paths (new tmux, existing tmux, no tmux) block via execSync/execFileSync.
825
896
  */
826
- function runCodex(cwd, args, sessionId, workerDefaultModel, codexHomeOverride) {
897
+ function runCodex(cwd, args, sessionId, workerDefaultModel, codexHomeOverride, notifyTempContractRaw) {
827
898
  const launchArgs = injectModelInstructionsBypassArgs(cwd, args, process.env, sessionModelInstructionsPath(cwd, sessionId));
828
899
  const omxBin = process.argv[1];
829
900
  const hudCmd = buildTmuxPaneCommand('node', [omxBin, 'hud', '--watch']);
@@ -835,6 +906,9 @@ function runCodex(cwd, args, sessionId, workerDefaultModel, codexHomeOverride) {
835
906
  const codexEnv = workerLaunchArgs
836
907
  ? { ...codexBaseEnv, [TEAM_WORKER_LAUNCH_ARGS_ENV]: workerLaunchArgs }
837
908
  : codexBaseEnv;
909
+ const codexEnvWithNotify = notifyTempContractRaw
910
+ ? { ...codexEnv, [OMX_NOTIFY_TEMP_CONTRACT_ENV]: notifyTempContractRaw }
911
+ : codexEnv;
838
912
  if (resolveCodexLaunchPolicy(process.env) === 'inside-tmux') {
839
913
  // Already in tmux: launch codex in current pane, HUD in bottom split
840
914
  const currentPaneId = process.env.TMUX_PANE;
@@ -846,7 +920,8 @@ function runCodex(cwd, args, sessionId, workerDefaultModel, codexHomeOverride) {
846
920
  try {
847
921
  hudPaneId = createHudWatchPane(cwd, hudCmd);
848
922
  }
849
- catch {
923
+ catch (err) {
924
+ process.stderr.write(`[cli/index] operation failed: ${err}\n`);
850
925
  // HUD split failed, continue without it
851
926
  }
852
927
  // Enable mouse scrolling at session start so scroll works before team
@@ -862,12 +937,13 @@ function runCodex(cwd, args, sessionId, workerDefaultModel, codexHomeOverride) {
862
937
  if (tmuxSession)
863
938
  enableMouseScrolling(tmuxSession);
864
939
  }
865
- catch {
940
+ catch (err) {
941
+ process.stderr.write(`[cli/index] operation failed: ${err}\n`);
866
942
  // Non-fatal: mouse scrolling is a convenience feature
867
943
  }
868
944
  }
869
945
  try {
870
- runCodexBlocking(cwd, launchArgs, codexEnv);
946
+ runCodexBlocking(cwd, launchArgs, codexEnvWithNotify);
871
947
  }
872
948
  finally {
873
949
  const cleanupPaneIds = buildHudPaneCleanupTargets(listHudWatchPaneIdsInCurrentWindow(currentPaneId), hudPaneId, currentPaneId);
@@ -886,7 +962,7 @@ function runCodex(cwd, args, sessionId, workerDefaultModel, codexHomeOverride) {
886
962
  let registeredHookName = null;
887
963
  let registeredClientAttachedHookName = null;
888
964
  try {
889
- const bootstrapSteps = buildDetachedSessionBootstrapSteps(sessionName, cwd, codexCmd, hudCmd, workerLaunchArgs, codexHomeOverride);
965
+ const bootstrapSteps = buildDetachedSessionBootstrapSteps(sessionName, cwd, codexCmd, hudCmd, workerLaunchArgs, codexHomeOverride, notifyTempContractRaw);
890
966
  for (const step of bootstrapSteps) {
891
967
  const output = execFileSync('tmux', step.args, { stdio: step.name === 'new-session' ? 'ignore' : 'pipe', encoding: 'utf-8' });
892
968
  if (step.name === 'new-session') {
@@ -910,7 +986,8 @@ function runCodex(cwd, args, sessionId, workerDefaultModel, codexHomeOverride) {
910
986
  try {
911
987
  execFileSync('tmux', finalizeStep.args, { stdio });
912
988
  }
913
- catch {
989
+ catch (err) {
990
+ process.stderr.write(`[cli/index] operation failed: ${err}\n`);
914
991
  if (finalizeStep.name === 'attach-session')
915
992
  throw new Error('failed to attach detached tmux session');
916
993
  continue;
@@ -926,20 +1003,22 @@ function runCodex(cwd, args, sessionId, workerDefaultModel, codexHomeOverride) {
926
1003
  }
927
1004
  }
928
1005
  }
929
- catch {
1006
+ catch (err) {
1007
+ process.stderr.write(`[cli/index] operation failed: ${err}\n`);
930
1008
  if (createdDetachedSession) {
931
1009
  const rollbackSteps = buildDetachedSessionRollbackSteps(sessionName, registeredHookTarget, registeredHookName, registeredClientAttachedHookName);
932
1010
  for (const rollbackStep of rollbackSteps) {
933
1011
  try {
934
1012
  execFileSync('tmux', rollbackStep.args, { stdio: 'ignore' });
935
1013
  }
936
- catch {
1014
+ catch (err) {
1015
+ process.stderr.write(`[cli/index] operation failed: ${err}\n`);
937
1016
  // best-effort rollback only
938
1017
  }
939
1018
  }
940
1019
  }
941
1020
  // tmux not available or failed, just run codex directly
942
- runCodexBlocking(cwd, launchArgs, codexEnv);
1021
+ runCodexBlocking(cwd, launchArgs, codexEnvWithNotify);
943
1022
  }
944
1023
  }
945
1024
  }
@@ -948,7 +1027,8 @@ function listHudWatchPaneIdsInCurrentWindow(currentPaneId) {
948
1027
  const output = execFileSync('tmux', ['list-panes', '-F', '#{pane_id}\t#{pane_current_command}\t#{pane_start_command}'], { encoding: 'utf-8' });
949
1028
  return findHudWatchPaneIds(parseTmuxPaneSnapshot(output), currentPaneId);
950
1029
  }
951
- catch {
1030
+ catch (err) {
1031
+ process.stderr.write(`[cli/index] operation failed: ${err}\n`);
952
1032
  return [];
953
1033
  }
954
1034
  }
@@ -962,7 +1042,8 @@ function killTmuxPane(paneId) {
962
1042
  try {
963
1043
  execFileSync('tmux', ['kill-pane', '-t', paneId], { stdio: 'ignore' });
964
1044
  }
965
- catch {
1045
+ catch (err) {
1046
+ process.stderr.write(`[cli/index] operation failed: ${err}\n`);
966
1047
  // Pane may already be gone; ignore.
967
1048
  }
968
1049
  }
@@ -983,7 +1064,8 @@ export function buildTmuxPaneCommand(command, args, shellPath = process.env.SHEL
983
1064
  else if (shellPath && /\/bash$/i.test(shellPath)) {
984
1065
  rcSource = 'if [ -f ~/.bashrc ]; then source ~/.bashrc; fi; ';
985
1066
  }
986
- const shellBin = shellPath && shellPath.trim() !== '' ? shellPath : '/bin/sh';
1067
+ const rawShell = shellPath && shellPath.trim() !== '' ? shellPath.trim() : '/bin/sh';
1068
+ const shellBin = ALLOWED_SHELLS.has(rawShell) ? rawShell : '/bin/sh';
987
1069
  const inner = `${rcSource}exec ${bareCmd}`;
988
1070
  return `${quoteShellArg(shellBin)} -lc ${quoteShellArg(inner)}`;
989
1071
  }
@@ -1001,35 +1083,40 @@ async function postLaunch(cwd, sessionId) {
1001
1083
  const sessionState = await readSessionState(cwd);
1002
1084
  sessionStartedAt = sessionState?.started_at;
1003
1085
  }
1004
- catch {
1086
+ catch (err) {
1087
+ process.stderr.write(`[cli/index] operation failed: ${err}\n`);
1005
1088
  // Non-fatal
1006
1089
  }
1007
1090
  // 0. Flush fallback watcher once to reduce race with fast codex exit.
1008
1091
  try {
1009
1092
  await flushNotifyFallbackOnce(cwd);
1010
1093
  }
1011
- catch {
1094
+ catch (err) {
1095
+ process.stderr.write(`[cli/index] operation failed: ${err}\n`);
1012
1096
  // Non-fatal
1013
1097
  }
1014
1098
  // 0. Stop notify fallback watcher first.
1015
1099
  try {
1016
1100
  await stopNotifyFallbackWatcher(cwd);
1017
1101
  }
1018
- catch {
1102
+ catch (err) {
1103
+ process.stderr.write(`[cli/index] operation failed: ${err}\n`);
1019
1104
  // Non-fatal
1020
1105
  }
1021
1106
  // 0. Flush derived watcher once on shutdown (opt-in, best effort).
1022
1107
  try {
1023
1108
  await flushHookDerivedWatcherOnce(cwd);
1024
1109
  }
1025
- catch {
1110
+ catch (err) {
1111
+ process.stderr.write(`[cli/index] operation failed: ${err}\n`);
1026
1112
  // Non-fatal
1027
1113
  }
1028
1114
  // 0.1 Stop derived watcher first (opt-in, best effort).
1029
1115
  try {
1030
1116
  await stopHookDerivedWatcher(cwd);
1031
1117
  }
1032
- catch {
1118
+ catch (err) {
1119
+ process.stderr.write(`[cli/index] operation failed: ${err}\n`);
1033
1120
  // Non-fatal
1034
1121
  }
1035
1122
  // 1. Remove session-scoped model instructions file
@@ -1083,7 +1170,8 @@ async function postLaunch(cwd, sessionId) {
1083
1170
  reason: 'session_exit',
1084
1171
  });
1085
1172
  }
1086
- catch {
1173
+ catch (err) {
1174
+ process.stderr.write(`[cli/index] operation failed: ${err}\n`);
1087
1175
  // Non-fatal: notification failures must never block session cleanup
1088
1176
  }
1089
1177
  // 5. Dispatch native hook event (best effort)
@@ -1101,7 +1189,8 @@ async function postLaunch(cwd, sessionId) {
1101
1189
  },
1102
1190
  });
1103
1191
  }
1104
- catch {
1192
+ catch (err) {
1193
+ process.stderr.write(`[cli/index] operation failed: ${err}\n`);
1105
1194
  // Non-fatal
1106
1195
  }
1107
1196
  }
@@ -1299,10 +1388,18 @@ async function cancelModes() {
1299
1388
  const states = new Map();
1300
1389
  for (const ref of refs) {
1301
1390
  const content = await readFile(ref.path, 'utf-8');
1391
+ let parsedState;
1392
+ try {
1393
+ parsedState = JSON.parse(content);
1394
+ }
1395
+ catch (err) {
1396
+ process.stderr.write(`[cli/index] operation failed: ${err}\n`);
1397
+ continue;
1398
+ }
1302
1399
  states.set(ref.mode, {
1303
1400
  path: ref.path,
1304
1401
  scope: ref.scope,
1305
- state: JSON.parse(content),
1402
+ state: parsedState,
1306
1403
  });
1307
1404
  }
1308
1405
  const changed = new Set();
@@ -1364,7 +1461,8 @@ async function cancelModes() {
1364
1461
  console.log('No active modes to cancel.');
1365
1462
  }
1366
1463
  }
1367
- catch {
1464
+ catch (err) {
1465
+ process.stderr.write(`[cli/index] operation failed: ${err}\n`);
1368
1466
  console.log('No active modes to cancel.');
1369
1467
  }
1370
1468
  }