oh-my-codex 0.11.13 → 0.12.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 (377) hide show
  1. package/Cargo.lock +5 -5
  2. package/Cargo.toml +1 -1
  3. package/README.md +34 -17
  4. package/crates/omx-runtime/src/main.rs +6 -2
  5. package/dist/agents/native-config.js +1 -1
  6. package/dist/agents/native-config.js.map +1 -1
  7. package/dist/cli/__tests__/autoresearch-guided.test.js +74 -2
  8. package/dist/cli/__tests__/autoresearch-guided.test.js.map +1 -1
  9. package/dist/cli/__tests__/cleanup.test.js +37 -30
  10. package/dist/cli/__tests__/cleanup.test.js.map +1 -1
  11. package/dist/cli/__tests__/error-handling-warnings.test.js +3 -1
  12. package/dist/cli/__tests__/error-handling-warnings.test.js.map +1 -1
  13. package/dist/cli/__tests__/index.test.js +276 -5
  14. package/dist/cli/__tests__/index.test.js.map +1 -1
  15. package/dist/cli/__tests__/launch-fallback.test.js +95 -1
  16. package/dist/cli/__tests__/launch-fallback.test.js.map +1 -1
  17. package/dist/cli/__tests__/setup-refresh.test.js +49 -9
  18. package/dist/cli/__tests__/setup-refresh.test.js.map +1 -1
  19. package/dist/cli/__tests__/setup-scope.test.js +9 -0
  20. package/dist/cli/__tests__/setup-scope.test.js.map +1 -1
  21. package/dist/cli/__tests__/team.test.js +136 -11
  22. package/dist/cli/__tests__/team.test.js.map +1 -1
  23. package/dist/cli/__tests__/uninstall.test.js +10 -0
  24. package/dist/cli/__tests__/uninstall.test.js.map +1 -1
  25. package/dist/cli/__tests__/windows-popup-loop-contract.test.js +1 -0
  26. package/dist/cli/__tests__/windows-popup-loop-contract.test.js.map +1 -1
  27. package/dist/cli/autoresearch-guided.d.ts.map +1 -1
  28. package/dist/cli/autoresearch-guided.js +2 -1
  29. package/dist/cli/autoresearch-guided.js.map +1 -1
  30. package/dist/cli/autoresearch.d.ts.map +1 -1
  31. package/dist/cli/autoresearch.js +2 -1
  32. package/dist/cli/autoresearch.js.map +1 -1
  33. package/dist/cli/cleanup.d.ts.map +1 -1
  34. package/dist/cli/cleanup.js +10 -5
  35. package/dist/cli/cleanup.js.map +1 -1
  36. package/dist/cli/index.d.ts +21 -1
  37. package/dist/cli/index.d.ts.map +1 -1
  38. package/dist/cli/index.js +298 -36
  39. package/dist/cli/index.js.map +1 -1
  40. package/dist/cli/omx.js +2 -0
  41. package/dist/cli/omx.js.map +1 -1
  42. package/dist/cli/setup.d.ts +1 -0
  43. package/dist/cli/setup.d.ts.map +1 -1
  44. package/dist/cli/setup.js +41 -7
  45. package/dist/cli/setup.js.map +1 -1
  46. package/dist/cli/team.d.ts.map +1 -1
  47. package/dist/cli/team.js +16 -557
  48. package/dist/cli/team.js.map +1 -1
  49. package/dist/cli/uninstall.d.ts.map +1 -1
  50. package/dist/cli/uninstall.js +34 -9
  51. package/dist/cli/uninstall.js.map +1 -1
  52. package/dist/config/__tests__/generator-idempotent.test.js +79 -2
  53. package/dist/config/__tests__/generator-idempotent.test.js.map +1 -1
  54. package/dist/config/__tests__/generator-notify.test.js +2 -0
  55. package/dist/config/__tests__/generator-notify.test.js.map +1 -1
  56. package/dist/config/codex-hooks.d.ts +11 -0
  57. package/dist/config/codex-hooks.d.ts.map +1 -0
  58. package/dist/config/codex-hooks.js +50 -0
  59. package/dist/config/codex-hooks.js.map +1 -0
  60. package/dist/config/generator.d.ts +5 -3
  61. package/dist/config/generator.d.ts.map +1 -1
  62. package/dist/config/generator.js +24 -14
  63. package/dist/config/generator.js.map +1 -1
  64. package/dist/hooks/__tests__/debugger-log-recency-contract.test.d.ts +2 -0
  65. package/dist/hooks/__tests__/debugger-log-recency-contract.test.d.ts.map +1 -0
  66. package/dist/hooks/__tests__/debugger-log-recency-contract.test.js +20 -0
  67. package/dist/hooks/__tests__/debugger-log-recency-contract.test.js.map +1 -0
  68. package/dist/hooks/__tests__/keyword-detector.test.js +132 -0
  69. package/dist/hooks/__tests__/keyword-detector.test.js.map +1 -1
  70. package/dist/hooks/__tests__/notify-fallback-watcher.test.js +292 -4
  71. package/dist/hooks/__tests__/notify-fallback-watcher.test.js.map +1 -1
  72. package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js +86 -0
  73. package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js.map +1 -1
  74. package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js +40 -0
  75. package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js.map +1 -1
  76. package/dist/hooks/__tests__/notify-hook-managed-tmux.test.d.ts +2 -0
  77. package/dist/hooks/__tests__/notify-hook-managed-tmux.test.d.ts.map +1 -0
  78. package/dist/hooks/__tests__/notify-hook-managed-tmux.test.js +54 -0
  79. package/dist/hooks/__tests__/notify-hook-managed-tmux.test.js.map +1 -0
  80. package/dist/hooks/__tests__/notify-hook-modules.test.js +31 -0
  81. package/dist/hooks/__tests__/notify-hook-modules.test.js.map +1 -1
  82. package/dist/hooks/__tests__/notify-hook-ralph-resume.test.js +51 -0
  83. package/dist/hooks/__tests__/notify-hook-ralph-resume.test.js.map +1 -1
  84. package/dist/hooks/__tests__/notify-hook-session-idle-dedupe.test.d.ts +2 -0
  85. package/dist/hooks/__tests__/notify-hook-session-idle-dedupe.test.d.ts.map +1 -0
  86. package/dist/hooks/__tests__/notify-hook-session-idle-dedupe.test.js +136 -0
  87. package/dist/hooks/__tests__/notify-hook-session-idle-dedupe.test.js.map +1 -0
  88. package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js +120 -0
  89. package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js.map +1 -1
  90. package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js +145 -20
  91. package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js.map +1 -1
  92. package/dist/hooks/__tests__/notify-hook-team-tmux-guard.test.js +116 -0
  93. package/dist/hooks/__tests__/notify-hook-team-tmux-guard.test.js.map +1 -1
  94. package/dist/hooks/__tests__/notify-hook-worker-idle.test.js +86 -0
  95. package/dist/hooks/__tests__/notify-hook-worker-idle.test.js.map +1 -1
  96. package/dist/hooks/__tests__/pre-context-gate-skills.test.js +1 -0
  97. package/dist/hooks/__tests__/pre-context-gate-skills.test.js.map +1 -1
  98. package/dist/hooks/extensibility/__tests__/runtime.test.js +49 -0
  99. package/dist/hooks/extensibility/__tests__/runtime.test.js.map +1 -1
  100. package/dist/hooks/extensibility/runtime.d.ts.map +1 -1
  101. package/dist/hooks/extensibility/runtime.js +10 -0
  102. package/dist/hooks/extensibility/runtime.js.map +1 -1
  103. package/dist/hooks/extensibility/types.d.ts +1 -1
  104. package/dist/hooks/extensibility/types.d.ts.map +1 -1
  105. package/dist/hooks/keyword-detector.d.ts +2 -0
  106. package/dist/hooks/keyword-detector.d.ts.map +1 -1
  107. package/dist/hooks/keyword-detector.js +76 -4
  108. package/dist/hooks/keyword-detector.js.map +1 -1
  109. package/dist/hooks/prompt-guidance-contract.d.ts.map +1 -1
  110. package/dist/hooks/prompt-guidance-contract.js +12 -8
  111. package/dist/hooks/prompt-guidance-contract.js.map +1 -1
  112. package/dist/hooks/session.d.ts +5 -1
  113. package/dist/hooks/session.d.ts.map +1 -1
  114. package/dist/hooks/session.js +10 -6
  115. package/dist/hooks/session.js.map +1 -1
  116. package/dist/hud/index.d.ts.map +1 -1
  117. package/dist/hud/index.js +6 -1
  118. package/dist/hud/index.js.map +1 -1
  119. package/dist/mcp/__tests__/bootstrap.test.js +0 -3
  120. package/dist/mcp/__tests__/bootstrap.test.js.map +1 -1
  121. package/dist/mcp/__tests__/code-intel-server.test.js +27 -1
  122. package/dist/mcp/__tests__/code-intel-server.test.js.map +1 -1
  123. package/dist/mcp/__tests__/server-lifecycle.test.js +0 -5
  124. package/dist/mcp/__tests__/server-lifecycle.test.js.map +1 -1
  125. package/dist/mcp/bootstrap.d.ts +1 -1
  126. package/dist/mcp/bootstrap.d.ts.map +1 -1
  127. package/dist/mcp/bootstrap.js +0 -1
  128. package/dist/mcp/bootstrap.js.map +1 -1
  129. package/dist/mcp/code-intel-server.d.ts +20 -0
  130. package/dist/mcp/code-intel-server.d.ts.map +1 -1
  131. package/dist/mcp/code-intel-server.js +6 -5
  132. package/dist/mcp/code-intel-server.js.map +1 -1
  133. package/dist/notifications/__tests__/idle-cooldown.test.js +24 -1
  134. package/dist/notifications/__tests__/idle-cooldown.test.js.map +1 -1
  135. package/dist/notifications/__tests__/reply-listener.test.js +20 -1
  136. package/dist/notifications/__tests__/reply-listener.test.js.map +1 -1
  137. package/dist/notifications/__tests__/tmux.test.js +41 -0
  138. package/dist/notifications/__tests__/tmux.test.js.map +1 -1
  139. package/dist/notifications/idle-cooldown.d.ts +13 -0
  140. package/dist/notifications/idle-cooldown.d.ts.map +1 -1
  141. package/dist/notifications/idle-cooldown.js +50 -16
  142. package/dist/notifications/idle-cooldown.js.map +1 -1
  143. package/dist/notifications/reply-listener.d.ts.map +1 -1
  144. package/dist/notifications/reply-listener.js +2 -0
  145. package/dist/notifications/reply-listener.js.map +1 -1
  146. package/dist/notifications/tmux.d.ts.map +1 -1
  147. package/dist/notifications/tmux.js +4 -0
  148. package/dist/notifications/tmux.js.map +1 -1
  149. package/dist/scripts/__tests__/codex-native-hook.test.d.ts +2 -0
  150. package/dist/scripts/__tests__/codex-native-hook.test.d.ts.map +1 -0
  151. package/dist/scripts/__tests__/codex-native-hook.test.js +1050 -0
  152. package/dist/scripts/__tests__/codex-native-hook.test.js.map +1 -0
  153. package/dist/scripts/codex-native-hook.d.ts +22 -0
  154. package/dist/scripts/codex-native-hook.d.ts.map +1 -0
  155. package/dist/scripts/codex-native-hook.js +792 -0
  156. package/dist/scripts/codex-native-hook.js.map +1 -0
  157. package/dist/scripts/codex-native-pre-post.d.ts +26 -0
  158. package/dist/scripts/codex-native-pre-post.d.ts.map +1 -0
  159. package/dist/scripts/codex-native-pre-post.js +118 -0
  160. package/dist/scripts/codex-native-pre-post.js.map +1 -0
  161. package/dist/scripts/notify-fallback-watcher.js +322 -21
  162. package/dist/scripts/notify-fallback-watcher.js.map +1 -1
  163. package/dist/scripts/notify-hook/auto-nudge.d.ts.map +1 -1
  164. package/dist/scripts/notify-hook/auto-nudge.js +5 -6
  165. package/dist/scripts/notify-hook/auto-nudge.js.map +1 -1
  166. package/dist/scripts/notify-hook/log.d.ts +2 -2
  167. package/dist/scripts/notify-hook/log.d.ts.map +1 -1
  168. package/dist/scripts/notify-hook/log.js +10 -2
  169. package/dist/scripts/notify-hook/log.js.map +1 -1
  170. package/dist/scripts/notify-hook/managed-tmux.d.ts.map +1 -1
  171. package/dist/scripts/notify-hook/managed-tmux.js +2 -0
  172. package/dist/scripts/notify-hook/managed-tmux.js.map +1 -1
  173. package/dist/scripts/notify-hook/orchestration-intent.d.ts +18 -0
  174. package/dist/scripts/notify-hook/orchestration-intent.d.ts.map +1 -0
  175. package/dist/scripts/notify-hook/orchestration-intent.js +72 -0
  176. package/dist/scripts/notify-hook/orchestration-intent.js.map +1 -0
  177. package/dist/scripts/notify-hook/process-runner.js.map +1 -1
  178. package/dist/scripts/notify-hook/ralph-session-resume.d.ts.map +1 -1
  179. package/dist/scripts/notify-hook/ralph-session-resume.js +7 -0
  180. package/dist/scripts/notify-hook/ralph-session-resume.js.map +1 -1
  181. package/dist/scripts/notify-hook/team-dispatch.d.ts +15 -6
  182. package/dist/scripts/notify-hook/team-dispatch.d.ts.map +1 -1
  183. package/dist/scripts/notify-hook/team-dispatch.js +125 -6
  184. package/dist/scripts/notify-hook/team-dispatch.js.map +1 -1
  185. package/dist/scripts/notify-hook/team-leader-nudge.d.ts +3 -2
  186. package/dist/scripts/notify-hook/team-leader-nudge.d.ts.map +1 -1
  187. package/dist/scripts/notify-hook/team-leader-nudge.js +165 -37
  188. package/dist/scripts/notify-hook/team-leader-nudge.js.map +1 -1
  189. package/dist/scripts/notify-hook/team-tmux-guard.d.ts +4 -1
  190. package/dist/scripts/notify-hook/team-tmux-guard.d.ts.map +1 -1
  191. package/dist/scripts/notify-hook/team-tmux-guard.js +33 -44
  192. package/dist/scripts/notify-hook/team-tmux-guard.js.map +1 -1
  193. package/dist/scripts/notify-hook/team-worker.d.ts.map +1 -1
  194. package/dist/scripts/notify-hook/team-worker.js +68 -5
  195. package/dist/scripts/notify-hook/team-worker.js.map +1 -1
  196. package/dist/scripts/notify-hook/utils.d.ts +1 -1
  197. package/dist/scripts/notify-hook/utils.d.ts.map +1 -1
  198. package/dist/scripts/notify-hook/utils.js.map +1 -1
  199. package/dist/scripts/notify-hook.js +55 -32
  200. package/dist/scripts/notify-hook.js.map +1 -1
  201. package/dist/team/__tests__/api-interop.test.js +344 -18
  202. package/dist/team/__tests__/api-interop.test.js.map +1 -1
  203. package/dist/team/__tests__/delivery-e2e-smoke.test.d.ts +2 -0
  204. package/dist/team/__tests__/delivery-e2e-smoke.test.d.ts.map +1 -0
  205. package/dist/team/__tests__/delivery-e2e-smoke.test.js +671 -0
  206. package/dist/team/__tests__/delivery-e2e-smoke.test.js.map +1 -0
  207. package/dist/team/__tests__/mcp-comm.test.js +5 -0
  208. package/dist/team/__tests__/mcp-comm.test.js.map +1 -1
  209. package/dist/team/__tests__/runtime.test.js +543 -15
  210. package/dist/team/__tests__/runtime.test.js.map +1 -1
  211. package/dist/team/__tests__/state.test.js +133 -8
  212. package/dist/team/__tests__/state.test.js.map +1 -1
  213. package/dist/team/__tests__/team-ops-contract.test.js +4 -0
  214. package/dist/team/__tests__/team-ops-contract.test.js.map +1 -1
  215. package/dist/team/__tests__/tmux-session.test.js +160 -0
  216. package/dist/team/__tests__/tmux-session.test.js.map +1 -1
  217. package/dist/team/__tests__/worker-bootstrap.test.js +19 -1
  218. package/dist/team/__tests__/worker-bootstrap.test.js.map +1 -1
  219. package/dist/team/api-interop.d.ts.map +1 -1
  220. package/dist/team/api-interop.js +95 -23
  221. package/dist/team/api-interop.js.map +1 -1
  222. package/dist/team/contracts.d.ts +11 -1
  223. package/dist/team/contracts.d.ts.map +1 -1
  224. package/dist/team/contracts.js +29 -0
  225. package/dist/team/contracts.js.map +1 -1
  226. package/dist/team/delivery-log.d.ts +14 -0
  227. package/dist/team/delivery-log.d.ts.map +1 -0
  228. package/dist/team/delivery-log.js +35 -0
  229. package/dist/team/delivery-log.js.map +1 -0
  230. package/dist/team/idle-nudge.d.ts +2 -2
  231. package/dist/team/idle-nudge.js +2 -2
  232. package/dist/team/mcp-comm.d.ts +4 -0
  233. package/dist/team/mcp-comm.d.ts.map +1 -1
  234. package/dist/team/mcp-comm.js +84 -1
  235. package/dist/team/mcp-comm.js.map +1 -1
  236. package/dist/team/pane-status.d.ts +149 -0
  237. package/dist/team/pane-status.d.ts.map +1 -0
  238. package/dist/team/pane-status.js +558 -0
  239. package/dist/team/pane-status.js.map +1 -0
  240. package/dist/team/reminder-intents.d.ts +11 -0
  241. package/dist/team/reminder-intents.d.ts.map +1 -0
  242. package/dist/team/reminder-intents.js +40 -0
  243. package/dist/team/reminder-intents.js.map +1 -0
  244. package/dist/team/runtime-cli.d.ts +1 -1
  245. package/dist/team/runtime-cli.js +2 -2
  246. package/dist/team/runtime-cli.js.map +1 -1
  247. package/dist/team/runtime.d.ts +2 -1
  248. package/dist/team/runtime.d.ts.map +1 -1
  249. package/dist/team/runtime.js +409 -191
  250. package/dist/team/runtime.js.map +1 -1
  251. package/dist/team/scaling.d.ts.map +1 -1
  252. package/dist/team/scaling.js +6 -5
  253. package/dist/team/scaling.js.map +1 -1
  254. package/dist/team/state/dispatch.d.ts +4 -1
  255. package/dist/team/state/dispatch.d.ts.map +1 -1
  256. package/dist/team/state/dispatch.js +59 -18
  257. package/dist/team/state/dispatch.js.map +1 -1
  258. package/dist/team/state/mailbox.d.ts.map +1 -1
  259. package/dist/team/state/mailbox.js +45 -2
  260. package/dist/team/state/mailbox.js.map +1 -1
  261. package/dist/team/state/monitor.d.ts +2 -1
  262. package/dist/team/state/monitor.d.ts.map +1 -1
  263. package/dist/team/state/monitor.js +30 -1
  264. package/dist/team/state/monitor.js.map +1 -1
  265. package/dist/team/state/types.d.ts +5 -2
  266. package/dist/team/state/types.d.ts.map +1 -1
  267. package/dist/team/state/types.js.map +1 -1
  268. package/dist/team/state.d.ts +30 -3
  269. package/dist/team/state.d.ts.map +1 -1
  270. package/dist/team/state.js +170 -2
  271. package/dist/team/state.js.map +1 -1
  272. package/dist/team/team-ops.d.ts +5 -1
  273. package/dist/team/team-ops.d.ts.map +1 -1
  274. package/dist/team/team-ops.js +4 -0
  275. package/dist/team/team-ops.js.map +1 -1
  276. package/dist/team/tmux-session.d.ts +2 -0
  277. package/dist/team/tmux-session.d.ts.map +1 -1
  278. package/dist/team/tmux-session.js +19 -3
  279. package/dist/team/tmux-session.js.map +1 -1
  280. package/dist/team/worker-bootstrap.d.ts +4 -0
  281. package/dist/team/worker-bootstrap.d.ts.map +1 -1
  282. package/dist/team/worker-bootstrap.js +33 -6
  283. package/dist/team/worker-bootstrap.js.map +1 -1
  284. package/dist/utils/__tests__/paths.test.js +63 -1
  285. package/dist/utils/__tests__/paths.test.js.map +1 -1
  286. package/dist/utils/__tests__/platform-command.test.js +50 -4
  287. package/dist/utils/__tests__/platform-command.test.js.map +1 -1
  288. package/dist/utils/paths.d.ts +12 -0
  289. package/dist/utils/paths.d.ts.map +1 -1
  290. package/dist/utils/paths.js +44 -2
  291. package/dist/utils/paths.js.map +1 -1
  292. package/dist/utils/platform-command.d.ts.map +1 -1
  293. package/dist/utils/platform-command.js +13 -5
  294. package/dist/utils/platform-command.js.map +1 -1
  295. package/dist/utils/sleep.d.ts.map +1 -1
  296. package/dist/utils/sleep.js +10 -1
  297. package/dist/utils/sleep.js.map +1 -1
  298. package/package.json +1 -1
  299. package/prompts/analyst.md +2 -2
  300. package/prompts/api-reviewer.md +2 -2
  301. package/prompts/architect.md +2 -2
  302. package/prompts/build-fixer.md +2 -2
  303. package/prompts/code-reviewer.md +2 -2
  304. package/prompts/code-simplifier.md +1 -1
  305. package/prompts/critic.md +2 -2
  306. package/prompts/debugger.md +3 -2
  307. package/prompts/dependency-expert.md +2 -2
  308. package/prompts/designer.md +2 -2
  309. package/prompts/executor.md +3 -2
  310. package/prompts/explore.md +2 -2
  311. package/prompts/git-master.md +2 -2
  312. package/prompts/information-architect.md +15 -102
  313. package/prompts/performance-reviewer.md +2 -2
  314. package/prompts/planner.md +3 -2
  315. package/prompts/product-analyst.md +2 -2
  316. package/prompts/product-manager.md +2 -2
  317. package/prompts/qa-tester.md +2 -2
  318. package/prompts/quality-reviewer.md +2 -2
  319. package/prompts/quality-strategist.md +2 -2
  320. package/prompts/researcher.md +2 -2
  321. package/prompts/security-reviewer.md +2 -2
  322. package/prompts/sisyphus-lite.md +2 -2
  323. package/prompts/style-reviewer.md +2 -2
  324. package/prompts/team-executor.md +2 -2
  325. package/prompts/test-engineer.md +2 -2
  326. package/prompts/ux-researcher.md +2 -2
  327. package/prompts/verifier.md +3 -2
  328. package/prompts/vision.md +2 -2
  329. package/prompts/writer.md +2 -2
  330. package/skills/team/SKILL.md +18 -33
  331. package/src/scripts/__tests__/codex-native-hook.test.ts +1346 -0
  332. package/src/scripts/codex-native-hook.ts +983 -0
  333. package/src/scripts/codex-native-pre-post.ts +161 -0
  334. package/src/scripts/notify-fallback-watcher.ts +378 -29
  335. package/src/scripts/notify-hook/auto-nudge.ts +5 -10
  336. package/src/scripts/notify-hook/log.ts +18 -4
  337. package/src/scripts/notify-hook/managed-tmux.ts +1 -0
  338. package/src/scripts/notify-hook/orchestration-intent.ts +82 -0
  339. package/src/scripts/notify-hook/process-runner.ts +4 -4
  340. package/src/scripts/notify-hook/ralph-session-resume.ts +9 -0
  341. package/src/scripts/notify-hook/team-dispatch.ts +134 -6
  342. package/src/scripts/notify-hook/team-leader-nudge.ts +183 -37
  343. package/src/scripts/notify-hook/team-tmux-guard.ts +35 -43
  344. package/src/scripts/notify-hook/team-worker.ts +73 -4
  345. package/src/scripts/notify-hook/utils.ts +1 -1
  346. package/src/scripts/notify-hook.ts +64 -32
  347. package/templates/AGENTS.md +21 -11
  348. package/README.de.md +0 -263
  349. package/README.el.md +0 -223
  350. package/README.es.md +0 -263
  351. package/README.fr.md +0 -263
  352. package/README.it.md +0 -263
  353. package/README.ja.md +0 -264
  354. package/README.ko.md +0 -264
  355. package/README.pl.md +0 -216
  356. package/README.pt.md +0 -263
  357. package/README.ru.md +0 -263
  358. package/README.tr.md +0 -263
  359. package/README.vi.md +0 -223
  360. package/README.zh-TW.md +0 -293
  361. package/README.zh.md +0 -264
  362. package/dist/mcp/__tests__/team-server-cleanup.test.d.ts +0 -2
  363. package/dist/mcp/__tests__/team-server-cleanup.test.d.ts.map +0 -1
  364. package/dist/mcp/__tests__/team-server-cleanup.test.js +0 -219
  365. package/dist/mcp/__tests__/team-server-cleanup.test.js.map +0 -1
  366. package/dist/mcp/__tests__/team-server-runtime-deps.test.d.ts +0 -2
  367. package/dist/mcp/__tests__/team-server-runtime-deps.test.d.ts.map +0 -1
  368. package/dist/mcp/__tests__/team-server-runtime-deps.test.js +0 -13
  369. package/dist/mcp/__tests__/team-server-runtime-deps.test.js.map +0 -1
  370. package/dist/mcp/__tests__/team-server-wait.test.d.ts +0 -2
  371. package/dist/mcp/__tests__/team-server-wait.test.d.ts.map +0 -1
  372. package/dist/mcp/__tests__/team-server-wait.test.js +0 -155
  373. package/dist/mcp/__tests__/team-server-wait.test.js.map +0 -1
  374. package/dist/mcp/team-server.d.ts +0 -24
  375. package/dist/mcp/team-server.d.ts.map +0 -1
  376. package/dist/mcp/team-server.js +0 -482
  377. package/dist/mcp/team-server.js.map +0 -1
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { existsSync } from 'fs';
3
- import { appendFile, mkdir, open, readFile, readdir, rename, stat, unlink, writeFile } from 'fs/promises';
3
+ import { appendFile, mkdir, open, readFile, readdir, rename, rm, stat, unlink, writeFile } from 'fs/promises';
4
4
  import { spawnSync } from 'child_process';
5
5
  import { dirname, join, resolve } from 'path';
6
6
  import { homedir } from 'os';
@@ -12,6 +12,7 @@ import { checkWorkerPanesAlive, isLeaderStale, maybeNudgeTeamLeader, resolveLead
12
12
  import { DEFAULT_MARKER } from './tmux-hook-engine.js';
13
13
  import { isTerminalPhase } from './notify-hook/utils.js';
14
14
  import { isSessionStale, readSessionState } from '../hooks/session.js';
15
+ import { DEFAULT_SUBAGENT_ACTIVE_WINDOW_MS, readSubagentSessionSummary, } from '../subagents/tracker.js';
15
16
  function argValue(name, fallback = '') {
16
17
  const idx = process.argv.indexOf(name);
17
18
  if (idx < 0 || idx + 1 >= process.argv.length)
@@ -64,6 +65,7 @@ const authorityOnly = process.argv.includes('--authority-only');
64
65
  // ack budget so leaderless team dispatch + stale-alert recovery do not feel
65
66
  // laggy between native notify-hook turns.
66
67
  const pollMs = Math.max(50, asNumber(argValue('--poll-ms', '250'), 250));
68
+ const idleMaxPollMs = Math.max(pollMs, asNumber(argValue('--idle-max-poll-ms', process.env.OMX_NOTIFY_FALLBACK_IDLE_MAX_POLL_MS || '1000'), 1000));
67
69
  const parentPid = Math.trunc(asNumber(argValue('--parent-pid', String(process.ppid || 0)), process.ppid || 0));
68
70
  const startedAt = Date.now();
69
71
  const fileWindowMs = runOnce ? 15000 : 30000;
@@ -77,6 +79,10 @@ const stateDir = join(omxDir, 'state');
77
79
  const statePath = join(stateDir, 'notify-fallback-state.json');
78
80
  const pidFilePath = resolve(argValue('--pid-file', join(stateDir, 'notify-fallback.pid')));
79
81
  const logPath = join(logsDir, `notify-fallback-${new Date().toISOString().split('T')[0]}.jsonl`);
82
+ const logRotatePath = `${logPath}.1`;
83
+ const logLockPath = `${logPath}.lock`;
84
+ const defaultMaxLogBytes = 10 * 1024 * 1024;
85
+ const maxLogBytes = Math.max(0, asNumber(argValue('--log-max-bytes', process.env.OMX_NOTIFY_FALLBACK_LOG_MAX_BYTES || String(defaultMaxLogBytes)), defaultMaxLogBytes));
80
86
  const ralphSteerTimestampPath = join(stateDir, 'ralph-last-steer-at');
81
87
  const ralphSteerLockPath = join(stateDir, 'ralph-continue-steer.lock');
82
88
  const watcherOwnerToken = `${process.pid}-${startedAt}-${Math.random().toString(36).slice(2, 10)}`;
@@ -84,6 +90,7 @@ const RALPH_CONTINUE_TEXT = 'Ralph loop active continue';
84
90
  const RALPH_CONTINUE_CADENCE_MS = 60_000;
85
91
  const RALPH_STEER_LOCK_STALE_MS = 30_000;
86
92
  const RALPH_TERMINAL_PHASES = new Set(['complete', 'failed', 'cancelled']);
93
+ const QUIET_ONCE_EVENT_TYPES = new Set(['watcher_start', 'watcher_once_complete']);
87
94
  const fileState = new Map();
88
95
  const seenTurnKeys = new Set();
89
96
  let stopping = false;
@@ -119,6 +126,8 @@ let lastRalphContinueSteer = {
119
126
  pane_id: '',
120
127
  pane_current_command: '',
121
128
  current_phase: '',
129
+ subagent_session_id: '',
130
+ active_subagent_thread_ids: [],
122
131
  shared_timestamp_path: ralphSteerTimestampPath,
123
132
  shared_last_sent_at: '',
124
133
  singleton_lock_path: ralphSteerLockPath,
@@ -128,6 +137,14 @@ let lastParentGuard = {
128
137
  state_path: '',
129
138
  current_phase: '',
130
139
  };
140
+ let lastAuthorityBackoff = {
141
+ active: false,
142
+ reason: '',
143
+ primary_pid: null,
144
+ primary_last_tick_at: '',
145
+ freshness_ms: null,
146
+ threshold_ms: null,
147
+ };
131
148
  const AUTO_NUDGE_STALL_MS = Math.max(pollMs, asNumber(process.env.OMX_NOTIFY_FALLBACK_AUTO_NUDGE_STALL_MS || '5000', 5000));
132
149
  let lastFallbackAutoNudge = {
133
150
  enabled: true,
@@ -141,12 +158,106 @@ let lastFallbackAutoNudge = {
141
158
  last_nudged_signature: '',
142
159
  last_nudged_at: '',
143
160
  };
144
- function eventLog(event) {
145
- return appendFile(logPath, `${JSON.stringify({ timestamp: new Date().toISOString(), ...event })}\n`).catch(() => { });
161
+ let adaptivePollState = {
162
+ enabled: true,
163
+ base_ms: pollMs,
164
+ max_ms: idleMaxPollMs,
165
+ current_ms: pollMs,
166
+ idle_streak: 0,
167
+ last_tick_at: null,
168
+ last_activity_at: null,
169
+ last_activity_reason: 'init',
170
+ };
171
+ function shouldSuppressEventLog(event) {
172
+ const eventType = safeString(event.type).trim();
173
+ return runOnce && QUIET_ONCE_EVENT_TYPES.has(eventType);
174
+ }
175
+ async function acquireLogLock(timeoutMs = 1000) {
176
+ const deadline = Date.now() + timeoutMs;
177
+ while (Date.now() < deadline) {
178
+ try {
179
+ await mkdir(logLockPath, { recursive: false });
180
+ return true;
181
+ }
182
+ catch (error) {
183
+ if (error?.code !== 'EEXIST')
184
+ return false;
185
+ const lockStat = await stat(logLockPath).catch(() => null);
186
+ if (lockStat && Date.now() - lockStat.mtimeMs > 5000) {
187
+ await rm(logLockPath, { recursive: true, force: true }).catch(() => { });
188
+ continue;
189
+ }
190
+ await sleep(10);
191
+ }
192
+ }
193
+ return false;
194
+ }
195
+ async function releaseLogLock() {
196
+ await rm(logLockPath, { recursive: true, force: true }).catch(() => { });
197
+ }
198
+ async function rotateLogIfNeeded(nextEntryBytes) {
199
+ if (maxLogBytes <= 0)
200
+ return;
201
+ const currentStat = await stat(logPath).catch(() => null);
202
+ if (!currentStat || currentStat.size + nextEntryBytes <= maxLogBytes)
203
+ return;
204
+ await unlink(logRotatePath).catch(() => { });
205
+ await rename(logPath, logRotatePath).catch(() => { });
206
+ }
207
+ async function eventLog(event) {
208
+ if (shouldSuppressEventLog(event))
209
+ return;
210
+ const line = `${JSON.stringify({ timestamp: new Date().toISOString(), ...event })}\n`;
211
+ await mkdir(dirname(logPath), { recursive: true }).catch(() => { });
212
+ const locked = await acquireLogLock();
213
+ if (!locked)
214
+ return;
215
+ try {
216
+ await rotateLogIfNeeded(Buffer.byteLength(line));
217
+ await appendFile(logPath, line);
218
+ }
219
+ catch {
220
+ // best effort only
221
+ }
222
+ finally {
223
+ await releaseLogLock();
224
+ }
146
225
  }
147
226
  function shouldLogLeaderNudgeTick(reason) {
148
227
  return reason === 'leader_nudge_checked' || reason === 'leader_nudge_failed';
149
228
  }
229
+ function nextIdlePollMs(currentMs) {
230
+ return Math.min(idleMaxPollMs, Math.max(pollMs, currentMs * 2));
231
+ }
232
+ function updateAdaptivePollState(summary) {
233
+ const nowIso = new Date().toISOString();
234
+ if (summary.active) {
235
+ adaptivePollState = {
236
+ ...adaptivePollState,
237
+ enabled: true,
238
+ base_ms: pollMs,
239
+ max_ms: idleMaxPollMs,
240
+ current_ms: pollMs,
241
+ idle_streak: 0,
242
+ last_tick_at: nowIso,
243
+ last_activity_at: nowIso,
244
+ last_activity_reason: summary.reason,
245
+ };
246
+ return adaptivePollState.current_ms;
247
+ }
248
+ const nextMs = nextIdlePollMs(adaptivePollState.current_ms);
249
+ adaptivePollState = {
250
+ ...adaptivePollState,
251
+ enabled: true,
252
+ base_ms: pollMs,
253
+ max_ms: idleMaxPollMs,
254
+ current_ms: nextMs,
255
+ idle_streak: adaptivePollState.idle_streak + 1,
256
+ last_tick_at: nowIso,
257
+ last_activity_reason: summary.reason,
258
+ };
259
+ return adaptivePollState.current_ms;
260
+ }
150
261
  function shouldLogDispatchDrainTick(result) {
151
262
  if (!result || typeof result !== 'object')
152
263
  return false;
@@ -176,6 +287,10 @@ function normalizeRalphContinueSteerState(raw) {
176
287
  pane_id: safeString(raw.pane_id),
177
288
  pane_current_command: safeString(raw.pane_current_command),
178
289
  current_phase: safeString(raw.current_phase),
290
+ subagent_session_id: safeString(raw.subagent_session_id),
291
+ active_subagent_thread_ids: Array.isArray(raw.active_subagent_thread_ids)
292
+ ? raw.active_subagent_thread_ids.map((value) => safeString(value).trim()).filter(Boolean)
293
+ : [],
179
294
  shared_timestamp_path: safeString(raw.shared_timestamp_path) || ralphSteerTimestampPath,
180
295
  shared_last_sent_at: safeString(raw.shared_last_sent_at),
181
296
  singleton_lock_path: safeString(raw.singleton_lock_path) || ralphSteerLockPath,
@@ -215,6 +330,19 @@ async function loadPersistedWatcherState() {
215
330
  last_nudged_at: safeString(persistedAutoNudge.last_nudged_at),
216
331
  };
217
332
  }
333
+ const persistedAdaptivePoll = persisted?.adaptive_poll;
334
+ if (persistedAdaptivePoll && typeof persistedAdaptivePoll === 'object') {
335
+ adaptivePollState = {
336
+ enabled: persistedAdaptivePoll.enabled !== false,
337
+ base_ms: pollMs,
338
+ max_ms: idleMaxPollMs,
339
+ current_ms: Math.min(idleMaxPollMs, Math.max(pollMs, asNumber(persistedAdaptivePoll.current_ms, pollMs))),
340
+ idle_streak: Math.max(0, Math.trunc(asNumber(persistedAdaptivePoll.idle_streak, 0))),
341
+ last_tick_at: safeString(persistedAdaptivePoll.last_tick_at) || null,
342
+ last_activity_at: safeString(persistedAdaptivePoll.last_activity_at) || null,
343
+ last_activity_reason: safeString(persistedAdaptivePoll.last_activity_reason) || 'init',
344
+ };
345
+ }
218
346
  }
219
347
  async function resolveActiveModeState(mode) {
220
348
  const candidateDirs = [];
@@ -416,7 +544,8 @@ async function withRalphSteerLock(task) {
416
544
  throw error;
417
545
  const existing = await readRalphSteerLock(ralphSteerLockPath);
418
546
  const lockAgeMs = parseIsoMillis(existing?.acquired_at) ?? 0;
419
- const stale = !existing || !isPidAlive(existing.pid) || (lockAgeMs > 0 && Date.now() - lockAgeMs > RALPH_STEER_LOCK_STALE_MS);
547
+ const stale = existing !== null
548
+ && (!isPidAlive(existing.pid) || (lockAgeMs > 0 && Date.now() - lockAgeMs > RALPH_STEER_LOCK_STALE_MS));
420
549
  if (stale) {
421
550
  await unlink(ralphSteerLockPath).catch(() => { });
422
551
  continue;
@@ -438,23 +567,39 @@ async function withRalphSteerLock(task) {
438
567
  }
439
568
  }
440
569
  }
441
- async function readRalphProgressGate(now) {
570
+ async function readRalphProgressGate(activeRalphState, now) {
571
+ const subagentSessionId = safeString(activeRalphState?.owner_codex_session_id).trim();
572
+ if (subagentSessionId) {
573
+ const summary = await readSubagentSessionSummary(cwd, subagentSessionId, {
574
+ now: new Date(now),
575
+ activeWindowMs: DEFAULT_SUBAGENT_ACTIVE_WINDOW_MS,
576
+ });
577
+ if ((summary?.activeSubagentThreadIds.length ?? 0) > 0) {
578
+ return {
579
+ allow: false,
580
+ reason: 'subagents_active',
581
+ progress_at: '',
582
+ subagent_session_id: subagentSessionId,
583
+ active_subagent_thread_ids: summary?.activeSubagentThreadIds ?? [],
584
+ };
585
+ }
586
+ }
442
587
  const hudState = await readJsonObject(join(stateDir, 'hud-state.json'));
443
588
  if (!hudState || typeof hudState !== 'object') {
444
- return { allow: false, reason: 'progress_missing', progress_at: '' };
589
+ return { allow: false, reason: 'progress_missing', progress_at: '', subagent_session_id: subagentSessionId };
445
590
  }
446
591
  const progressAt = safeString(hudState.last_progress_at).trim();
447
592
  if (!progressAt) {
448
- return { allow: false, reason: 'progress_missing', progress_at: '' };
593
+ return { allow: false, reason: 'progress_missing', progress_at: '', subagent_session_id: subagentSessionId };
449
594
  }
450
595
  const progressMs = parseIsoMillis(progressAt);
451
596
  if (progressMs === null) {
452
- return { allow: false, reason: 'progress_invalid', progress_at: progressAt };
597
+ return { allow: false, reason: 'progress_invalid', progress_at: progressAt, subagent_session_id: subagentSessionId };
453
598
  }
454
599
  if (now - progressMs < RALPH_CONTINUE_CADENCE_MS) {
455
- return { allow: false, reason: 'progress_fresh', progress_at: progressAt };
600
+ return { allow: false, reason: 'progress_fresh', progress_at: progressAt, subagent_session_id: subagentSessionId };
456
601
  }
457
- return { allow: true, reason: 'progress_stale', progress_at: progressAt };
602
+ return { allow: true, reason: 'progress_stale', progress_at: progressAt, subagent_session_id: subagentSessionId };
458
603
  }
459
604
  function shouldSkipRalphContinue(now, candidateIso, startupIso) {
460
605
  const sharedMs = parseIsoMillis(candidateIso);
@@ -497,6 +642,100 @@ async function readPidFileRecord(path) {
497
642
  return pid === null ? null : { pid };
498
643
  }
499
644
  }
645
+ function createAuthorityBackoffState(reason, overrides = {}) {
646
+ return {
647
+ active: false,
648
+ reason,
649
+ primary_pid: null,
650
+ primary_last_tick_at: '',
651
+ freshness_ms: null,
652
+ threshold_ms: null,
653
+ ...overrides,
654
+ };
655
+ }
656
+ function latestWatcherTickIso(state) {
657
+ if (!state || typeof state !== 'object')
658
+ return '';
659
+ const candidates = [
660
+ safeString(state.dispatch_drain?.last_tick_at),
661
+ safeString(state.leader_nudge?.last_tick_at),
662
+ safeString(state.fallback_auto_nudge?.last_tick_at),
663
+ safeString(state.ralph_continue_steer?.last_state_check_at),
664
+ ]
665
+ .map((value) => value.trim())
666
+ .filter(Boolean);
667
+ let latestIso = '';
668
+ let latestMs = -1;
669
+ for (const candidate of candidates) {
670
+ const parsed = parseIsoMillis(candidate);
671
+ if (parsed === null || parsed <= latestMs)
672
+ continue;
673
+ latestMs = parsed;
674
+ latestIso = candidate;
675
+ }
676
+ return latestIso;
677
+ }
678
+ async function resolveAuthorityPrimaryWatcherHealth(now = Date.now()) {
679
+ if (!authorityOnly)
680
+ return createAuthorityBackoffState('not_authority');
681
+ const existingRecord = await readPidFileRecord(pidFilePath).catch(() => null);
682
+ if (!existingRecord)
683
+ return createAuthorityBackoffState('pid_missing');
684
+ if (existingRecord.cwd && resolve(existingRecord.cwd) !== cwd)
685
+ return createAuthorityBackoffState('cwd_mismatch');
686
+ if (!isPidAlive(existingRecord.pid)) {
687
+ return createAuthorityBackoffState('pid_stale', {
688
+ primary_pid: existingRecord.pid,
689
+ });
690
+ }
691
+ const persistedState = await readJsonObject(statePath);
692
+ if (!persistedState) {
693
+ return createAuthorityBackoffState('state_missing', {
694
+ primary_pid: existingRecord.pid,
695
+ });
696
+ }
697
+ const persistedPid = Math.trunc(asNumber(persistedState.pid, 0));
698
+ if (persistedPid > 0 && persistedPid !== existingRecord.pid) {
699
+ return createAuthorityBackoffState('state_pid_mismatch', {
700
+ primary_pid: existingRecord.pid,
701
+ });
702
+ }
703
+ const lastTickAt = latestWatcherTickIso(persistedState);
704
+ if (!lastTickAt) {
705
+ return createAuthorityBackoffState('tick_missing', {
706
+ primary_pid: existingRecord.pid,
707
+ });
708
+ }
709
+ const lastTickMs = parseIsoMillis(lastTickAt);
710
+ const primaryPollMs = Math.max(50, asNumber(persistedState.poll_ms, 250));
711
+ const thresholdMs = Math.max(1_000, primaryPollMs * 4);
712
+ if (lastTickMs === null) {
713
+ return createAuthorityBackoffState('tick_invalid', {
714
+ primary_pid: existingRecord.pid,
715
+ primary_last_tick_at: lastTickAt,
716
+ threshold_ms: thresholdMs,
717
+ });
718
+ }
719
+ const freshnessMs = now - lastTickMs;
720
+ if (freshnessMs > thresholdMs) {
721
+ return {
722
+ active: false,
723
+ reason: 'tick_stale',
724
+ primary_pid: existingRecord.pid,
725
+ primary_last_tick_at: lastTickAt,
726
+ freshness_ms: freshnessMs,
727
+ threshold_ms: thresholdMs,
728
+ };
729
+ }
730
+ return {
731
+ active: true,
732
+ reason: 'primary_watcher_healthy',
733
+ primary_pid: existingRecord.pid,
734
+ primary_last_tick_at: lastTickAt,
735
+ freshness_ms: freshnessMs,
736
+ threshold_ms: thresholdMs,
737
+ };
738
+ }
500
739
  async function writePidFileRecord() {
501
740
  const nextRecord = {
502
741
  pid: process.pid,
@@ -524,6 +763,8 @@ async function runRalphContinueSteerTick() {
524
763
  state_path: activeRalph.path,
525
764
  pane_id: activePaneId,
526
765
  pane_current_command: '',
766
+ subagent_session_id: safeString(activeRalph.state?.owner_codex_session_id).trim(),
767
+ active_subagent_thread_ids: [],
527
768
  shared_timestamp_path: ralphSteerTimestampPath,
528
769
  singleton_lock_path: ralphSteerLockPath,
529
770
  };
@@ -553,9 +794,11 @@ async function runRalphContinueSteerTick() {
553
794
  }
554
795
  return { sent: false, skipped: true };
555
796
  }
556
- const progressGate = await readRalphProgressGate(Date.now());
797
+ const progressGate = await readRalphProgressGate(activeRalph.state, Date.now());
557
798
  if (!progressGate.allow) {
558
799
  lastRalphContinueSteer.last_reason = progressGate.reason;
800
+ lastRalphContinueSteer.subagent_session_id = progressGate.subagent_session_id ?? lastRalphContinueSteer.subagent_session_id;
801
+ lastRalphContinueSteer.active_subagent_thread_ids = progressGate.active_subagent_thread_ids ?? [];
559
802
  return { sent: false, skipped: true };
560
803
  }
561
804
  const paneId = safeString(activeRalph.state?.tmux_pane_id).trim();
@@ -675,6 +918,8 @@ async function writeState(extra = {}) {
675
918
  notify_script: notifyScript,
676
919
  authority_only: authorityOnly,
677
920
  poll_ms: pollMs,
921
+ effective_poll_ms: adaptivePollState.current_ms,
922
+ idle_max_poll_ms: idleMaxPollMs,
678
923
  pid_file: runOnce ? null : pidFilePath,
679
924
  max_lifetime_ms: maxLifetimeMs,
680
925
  tracked_files: fileState.size,
@@ -701,10 +946,25 @@ async function writeState(extra = {}) {
701
946
  enabled: true,
702
947
  stall_ms: AUTO_NUDGE_STALL_MS,
703
948
  },
949
+ authority_backoff: lastAuthorityBackoff,
950
+ adaptive_poll: {
951
+ ...adaptivePollState,
952
+ enabled: true,
953
+ base_ms: pollMs,
954
+ max_ms: idleMaxPollMs,
955
+ },
704
956
  ...extra,
705
957
  };
706
958
  await writeFile(statePath, JSON.stringify(state, null, 2)).catch(() => { });
707
959
  }
960
+ async function writeAuthorityBackoffState() {
961
+ await mkdir(stateDir, { recursive: true }).catch(() => { });
962
+ const existing = await readJsonObject(statePath);
963
+ const state = existing && typeof existing === 'object'
964
+ ? { ...existing, authority_backoff: lastAuthorityBackoff }
965
+ : { authority_backoff: lastAuthorityBackoff };
966
+ await writeFile(statePath, JSON.stringify(state, null, 2)).catch(() => { });
967
+ }
708
968
  async function readJsonObject(path) {
709
969
  return readFile(path, 'utf-8')
710
970
  .then((content) => JSON.parse(content))
@@ -1020,6 +1280,7 @@ function splitBufferedLines(partial, delta) {
1020
1280
  };
1021
1281
  }
1022
1282
  async function pollFiles() {
1283
+ let processedCount = 0;
1023
1284
  for (const [path, meta] of fileState.entries()) {
1024
1285
  const currentSize = (await stat(path).catch(() => ({ size: 0 }))).size || 0;
1025
1286
  if (currentSize <= meta.offset)
@@ -1036,8 +1297,10 @@ async function pollFiles() {
1036
1297
  if (!line.trim())
1037
1298
  continue;
1038
1299
  await processLine(meta, line, path);
1300
+ processedCount += 1;
1039
1301
  }
1040
1302
  }
1303
+ return processedCount;
1041
1304
  }
1042
1305
  async function runLeaderNudgeTick() {
1043
1306
  const startedIso = new Date().toISOString();
@@ -1053,7 +1316,7 @@ async function runLeaderNudgeTick() {
1053
1316
  last_tick_at: startedIso,
1054
1317
  last_error: 'worker_context',
1055
1318
  };
1056
- return;
1319
+ return false;
1057
1320
  }
1058
1321
  try {
1059
1322
  const preComputedLeaderStale = await isLeaderStale(stateDir, staleThresholdMs, Date.now());
@@ -1063,6 +1326,7 @@ async function runLeaderNudgeTick() {
1063
1326
  logsDir,
1064
1327
  preComputedLeaderStale,
1065
1328
  allowFreshMailboxNudges: false,
1329
+ source: 'notify_fallback_watcher',
1066
1330
  });
1067
1331
  leaderNudgeRuns += 1;
1068
1332
  lastLeaderNudge = {
@@ -1084,6 +1348,7 @@ async function runLeaderNudgeTick() {
1084
1348
  reason,
1085
1349
  });
1086
1350
  }
1351
+ return preComputedLeaderStale;
1087
1352
  }
1088
1353
  catch (err) {
1089
1354
  leaderNudgeRuns += 1;
@@ -1103,6 +1368,7 @@ async function runLeaderNudgeTick() {
1103
1368
  reason: 'leader_nudge_failed',
1104
1369
  error: lastLeaderNudge.last_error,
1105
1370
  });
1371
+ return true;
1106
1372
  }
1107
1373
  }
1108
1374
  async function runDispatchDrainTick() {
@@ -1125,6 +1391,7 @@ async function runDispatchDrainTick() {
1125
1391
  ...(result && typeof result === 'object' ? result : {}),
1126
1392
  });
1127
1393
  }
1394
+ return shouldLogDispatchDrainTick(result);
1128
1395
  }
1129
1396
  catch (err) {
1130
1397
  dispatchDrainRuns += 1;
@@ -1142,6 +1409,7 @@ async function runDispatchDrainTick() {
1142
1409
  reason: 'dispatch_drain_failed',
1143
1410
  error: lastDispatchDrain.last_error,
1144
1411
  });
1412
+ return true;
1145
1413
  }
1146
1414
  }
1147
1415
  async function shouldSuppressInteractiveFallbackTicks() {
@@ -1152,34 +1420,65 @@ async function shouldSuppressInteractiveFallbackTicks() {
1152
1420
  return deepInterviewStateActive || deepInterviewInputLockActive;
1153
1421
  }
1154
1422
  async function pumpTeamControlPlaneTick() {
1155
- await runDispatchDrainTick();
1156
- if (await shouldSuppressInteractiveFallbackTicks())
1157
- return;
1158
- await runLeaderNudgeTick();
1423
+ const dispatchActive = await runDispatchDrainTick();
1424
+ if (await shouldSuppressInteractiveFallbackTicks()) {
1425
+ return { active: dispatchActive, reason: dispatchActive ? 'dispatch_drain' : 'deep_interview_locked' };
1426
+ }
1427
+ const leaderActive = await runLeaderNudgeTick();
1159
1428
  await runFallbackAutoNudgeTick();
1429
+ const autoNudgeActive = lastFallbackAutoNudge.last_reason === 'sent';
1430
+ if (dispatchActive)
1431
+ return { active: true, reason: 'dispatch_drain' };
1432
+ if (leaderActive)
1433
+ return { active: true, reason: 'leader_nudge' };
1434
+ if (autoNudgeActive)
1435
+ return { active: true, reason: 'fallback_auto_nudge' };
1436
+ return { active: false, reason: lastFallbackAutoNudge.last_reason || 'control_plane_idle' };
1160
1437
  }
1161
1438
  async function runWatcherCycle() {
1439
+ let processedRolloutCount = 0;
1440
+ if (authorityOnly) {
1441
+ const authorityBackoff = await resolveAuthorityPrimaryWatcherHealth();
1442
+ lastAuthorityBackoff = authorityBackoff;
1443
+ if (authorityBackoff.active) {
1444
+ await writeAuthorityBackoffState();
1445
+ return processedRolloutCount;
1446
+ }
1447
+ }
1448
+ else {
1449
+ lastAuthorityBackoff = createAuthorityBackoffState('');
1450
+ }
1162
1451
  if (!authorityOnly) {
1163
1452
  await ensureTrackedFiles();
1164
- await pollFiles();
1453
+ processedRolloutCount = await pollFiles();
1165
1454
  }
1166
- await pumpTeamControlPlaneTick();
1455
+ const controlPlaneSummary = await pumpTeamControlPlaneTick();
1167
1456
  if (!authorityOnly && !(await shouldSuppressInteractiveFallbackTicks())) {
1168
1457
  await runRalphWatcherBehaviorTick();
1169
1458
  }
1170
- await writeState();
1459
+ const ralphActive = lastRalphContinueSteer.last_reason === 'sent';
1460
+ const summary = processedRolloutCount > 0
1461
+ ? { active: true, reason: 'rollout_event' }
1462
+ : controlPlaneSummary.active
1463
+ ? controlPlaneSummary
1464
+ : ralphActive
1465
+ ? { active: true, reason: 'ralph_continue_steer' }
1466
+ : { active: false, reason: controlPlaneSummary.reason || lastRalphContinueSteer.last_reason || 'idle' };
1467
+ const nextDelayMs = updateAdaptivePollState(summary);
1468
+ await writeState({ last_cycle_activity: summary.reason });
1469
+ return nextDelayMs;
1171
1470
  }
1172
1471
  async function tick() {
1173
1472
  if (stopping)
1174
1473
  return;
1175
1474
  if (await enforceLifecycleGuards())
1176
1475
  return;
1177
- await runWatcherCycle();
1476
+ const nextDelayMs = await runWatcherCycle();
1178
1477
  if (await enforceLifecycleGuards())
1179
1478
  return;
1180
1479
  setTimeout(() => {
1181
1480
  void tick();
1182
- }, pollMs);
1481
+ }, nextDelayMs);
1183
1482
  }
1184
1483
  function shutdown(signal) {
1185
1484
  void requestShutdown('signal', signal);
@@ -1200,6 +1499,8 @@ async function main() {
1200
1499
  notify_script: notifyScript,
1201
1500
  authority_only: authorityOnly,
1202
1501
  poll_ms: pollMs,
1502
+ effective_poll_ms: adaptivePollState.current_ms,
1503
+ idle_max_poll_ms: idleMaxPollMs,
1203
1504
  once: runOnce,
1204
1505
  parent_pid: parentPid,
1205
1506
  pid_file: runOnce ? null : pidFilePath,